Skip to content

Commit a59dd49

Browse files
author
th37rose
authored
Merge branch 'dev' into feature/bundle
2 parents 0c4ac50 + e0383d8 commit a59dd49

File tree

15 files changed

+239
-32
lines changed

15 files changed

+239
-32
lines changed

client/packages/lowcoder/src/comps/comps/columnLayout/columnLayout.tsx

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,20 @@ import { disabledPropertyView, hiddenPropertyView } from "comps/utils/propertyUt
4242
import { DisabledContext } from "comps/generators/uiCompBuilder";
4343

4444
const ContainWrapper = styled.div<{
45-
$style: ContainerStyleType | undefined;
45+
$style: ContainerStyleType & {
46+
display: string,
47+
gridTemplateColumns: string,
48+
columnGap: string,
49+
gridTemplateRows: string,
50+
rowGap: string,
51+
} | undefined;
4652
}>`
53+
display: ${(props) => props.$style?.display};
54+
grid-template-columns: ${(props) => props.$style?.gridTemplateColumns};
55+
grid-template-rows: ${(props) => props.$style?.gridTemplateRows};
56+
column-gap: ${(props) => props.$style?.columnGap};
57+
row-gap: ${(props) => props.$style?.rowGap};
58+
4759
background-color: ${(props) => props.$style?.background} !important;
4860
border-radius: ${(props) => props.$style?.radius};
4961
border-width: ${(props) => props.$style?.borderWidth};
@@ -59,7 +71,7 @@ const ColWrapper = styled(Col)<{
5971
$matchColumnsHeight: boolean,
6072
}>`
6173
> div {
62-
height: ${(props) => props.$matchColumnsHeight ? '100%' : 'auto'};
74+
height: ${(props) => props.$matchColumnsHeight ? `calc(100% - ${props.$style?.padding || 0} - ${props.$style?.padding || 0})` : 'auto'};
6375
background-color: ${(props) => props.$style?.background} !important;
6476
border-radius: ${(props) => props.$style?.radius};
6577
border-width: ${(props) => props.$style?.borderWidth};
@@ -121,17 +133,24 @@ const ColumnLayout = (props: ColumnLayoutProps) => {
121133
} = props;
122134

123135
return (
124-
<BackgroundColorContext.Provider value={"none"}>
136+
<BackgroundColorContext.Provider value={props.style.background}>
125137
<DisabledContext.Provider value={props.disabled}>
126-
<ContainWrapper $style={props.style}>
127-
<div style={{display: "grid", gridTemplateColumns: templateColumns, columnGap, gridTemplateRows: templateRows, rowGap}}>
128-
{columns.map(column => {
129-
const id = String(column.id);
130-
const childDispatch = wrapDispatch(wrapDispatch(dispatch, "containers"), id);
131-
if(!containers[id]) return null
132-
const containerProps = containers[id].children;
133-
const noOfColumns = columns.length;
134-
return (
138+
<ContainWrapper $style={{
139+
...props.style,
140+
display: "grid",
141+
gridTemplateColumns: templateColumns,
142+
columnGap,
143+
gridTemplateRows: templateRows,
144+
rowGap,
145+
}}>
146+
{columns.map(column => {
147+
const id = String(column.id);
148+
const childDispatch = wrapDispatch(wrapDispatch(dispatch, "containers"), id);
149+
if(!containers[id]) return null
150+
const containerProps = containers[id].children;
151+
const noOfColumns = columns.length;
152+
return (
153+
<BackgroundColorContext.Provider value={props.columnStyle.background}>
135154
<ColWrapper
136155
key={id}
137156
$style={props.columnStyle}
@@ -147,12 +166,12 @@ const ColumnLayout = (props: ColumnLayoutProps) => {
147166
style={columnStyle}
148167
/>
149168
</ColWrapper>
150-
)
151-
})
152-
}
153-
</div>
169+
</BackgroundColorContext.Provider>
170+
)
171+
})
172+
}
154173
</ContainWrapper>
155-
</DisabledContext.Provider>
174+
</DisabledContext.Provider>
156175
</BackgroundColorContext.Provider>
157176
);
158177
};

client/packages/lowcoder/src/layout/gridItem.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,12 @@ export function GridItem(props: GridItemProps) {
441441
cssTransforms: true,
442442
}),
443443
style: {
444-
...setTransform(pos,props.name),
444+
...setTransform(
445+
pos,
446+
props.name,
447+
props.autoHeight,
448+
Boolean(draggingUtils.isDragging())
449+
),
445450
opacity: layoutHide ? 0 : undefined,
446451
pointerEvents: layoutHide ? "none" : "auto",
447452
},

client/packages/lowcoder/src/layout/utils.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,21 @@ export function getStatics(layout: Layout): Layout {
199199
return _.pickBy(layout, (l) => l.static);
200200
}
201201

202-
export function setTransform({ top, left, width, height }: Position,name?:string): Record<string, any> {
202+
export function setTransform(
203+
{top, left, width, height }: Position,
204+
name ?: string,
205+
autoHeight?: boolean,
206+
isDragging?: boolean,
207+
): Record<string, any> {
203208
// Replace unitless items with px
204209
const translate = `translate(${left}px,${top}px)`;
205210
function containsChart(str:string) {
206211
return /chart/i.test(str);
207212
}
213+
let updatedHeight = 'auto';
214+
if (isDragging || !autoHeight || (name && containsChart(name))) {
215+
updatedHeight = `${height}px`;
216+
}
208217

209218
return {
210219
transform: translate,
@@ -213,7 +222,7 @@ export function setTransform({ top, left, width, height }: Position,name?:string
213222
msTransform: translate,
214223
OTransform: translate,
215224
width: `${width}px`,
216-
height: name ?containsChart(name)?`${height}px`:'auto':`${height}px`,
225+
height: updatedHeight,
217226
position: 'absolute',
218227
};
219228
}

deploy/docker/docker-compose.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ services:
6666
LOWCODER_ADMIN_SMTP_PORT: 587
6767
LOWCODER_ADMIN_SMTP_USERNAME:
6868
LOWCODER_ADMIN_SMTP_PASSWORD:
69-
LOWCODER_ADMIN_SMTP_AUTH: true
70-
LOWCODER_ADMIN_SMTP_SSL_ENABLED: false
71-
LOWCODER_ADMIN_SMTP_STARTTLS_ENABLED: true
72-
LOWCODER_ADMIN_SMTP_STARTTLS_REQUIRED: true
69+
LOWCODER_ADMIN_SMTP_AUTH: "true"
70+
LOWCODER_ADMIN_SMTP_SSL_ENABLED: "false"
71+
LOWCODER_ADMIN_SMTP_STARTTLS_ENABLED: "true"
72+
LOWCODER_ADMIN_SMTP_STARTTLS_REQUIRED: "true"
7373
# Email used as sender in lost password email
7474
LOWCODER_EMAIL_NOTIFICATIONS_SENDER: info@localhost
7575
volumes:

server/api-service/lowcoder-plugins/restApiPlugin/src/test/java/org/lowcoder/plugin/restapi/RestApiEngineTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ public void testEncodingParams() {
180180
assertTrue(result.isSuccess());
181181
assertNotNull(result.getData());
182182
JsonNode url = ((ObjectNode) result.getData()).get("url");
183-
assertEquals("\"https://postman-echo.com/post?param=value+with+blank\"", url.toString());
183+
assertEquals("\"http://postman-echo.com/post?param=value+with+blank\"", url.toString());
184184
})
185185
.verifyComplete();
186186
}

server/api-service/lowcoder-server/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,12 @@
240240
<groupId>org.springframework</groupId>
241241
<artifactId>spring-aspects</artifactId>
242242
</dependency>
243+
<dependency>
244+
<groupId>org.wiremock</groupId>
245+
<artifactId>wiremock-jetty12</artifactId>
246+
<version>3.6.0</version>
247+
<scope>test</scope>
248+
</dependency>
243249
</dependencies>
244250

245251
<dependencyManagement>

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/authentication/request/oauth2/request/GenericAuthRequest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.lowcoder.api.authentication.request.oauth2.request;
22

3+
import lombok.Setter;
34
import org.lowcoder.api.authentication.request.AuthException;
45
import org.lowcoder.api.authentication.request.oauth2.GenericOAuthProviderSource;
56
import org.lowcoder.api.authentication.request.oauth2.OAuth2RequestContext;
@@ -75,6 +76,7 @@ protected Mono<AuthToken> refreshAuthToken(String refreshToken) {
7576

7677
@Override
7778
protected Mono<AuthUser> getAuthUser(AuthToken authToken) {
79+
if(!config.getUserInfoIntrospection()) return Mono.just(AuthUser.builder().build());
7880
return WebClientBuildHelper.builder()
7981
.systemProxy()
8082
.timeoutMs(HTTP_TIMEOUT)

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/authentication/service/AuthenticationApiServiceImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ public void updateConnection(AuthUser authUser, User user) {
224224
Optional.ofNullable(authUser.getAuthToken()).map(ConnectionAuthToken::of).orElse(null));
225225
oldConnection.setRawUserInfo(authUser.getRawUserInfo());
226226

227+
//if auth by google, set refresh token
228+
if (StringUtils.isEmpty(authUser.getAuthToken().getRefreshToken()) && StringUtils.isNotEmpty(oldConnection.getAuthConnectionAuthToken().getRefreshToken())) {
229+
authUser.getAuthToken().setRefreshToken(oldConnection.getAuthConnectionAuthToken().getRefreshToken());
230+
}
231+
227232
user.setActiveAuthId(oldConnection.getAuthId());
228233
}
229234

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/bundle/BundleApiServiceImpl.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@
1616
import org.lowcoder.api.permission.view.PermissionItemView;
1717
import org.lowcoder.api.usermanagement.OrgDevChecker;
1818
import org.lowcoder.domain.application.model.Application;
19+
import org.lowcoder.domain.application.model.ApplicationStatus;
1920
import org.lowcoder.domain.application.model.ApplicationType;
2021
import org.lowcoder.domain.application.repository.ApplicationRepository;
2122
import org.lowcoder.domain.application.service.ApplicationServiceImpl;
22-
import org.lowcoder.domain.bundle.model.Bundle;
23-
import org.lowcoder.domain.bundle.model.BundleApplication;
24-
import org.lowcoder.domain.bundle.model.BundleRequestType;
25-
import org.lowcoder.domain.bundle.model.BundleStatus;
23+
import org.lowcoder.domain.bundle.model.*;
2624
import org.lowcoder.domain.bundle.repository.BundleRepository;
2725
import org.lowcoder.domain.bundle.service.BundleElementRelationService;
2826
import org.lowcoder.domain.bundle.service.BundleService;
@@ -45,7 +43,9 @@
4543
import reactor.core.scheduler.Schedulers;
4644

4745
import java.util.*;
48-
import java.util.function.Function;
46+
import java.util.function.Function;=
47+
import java.util.function.ToLongFunction;
48+
import java.util.stream.Collectors;
4949

5050
import static org.lowcoder.domain.bundle.model.BundleStatus.NORMAL;
5151
import static org.lowcoder.domain.permission.model.ResourceAction.*;
@@ -452,7 +452,6 @@ public Mono<BundleInfoView> getEditingBundle(String bundleId) {
452452
.description(bundle.getDescription())
453453
.image(bundle.getImage())
454454
.editingBundleDSL(bundle.getEditingBundleDSL())
455-
// .publishedBundleDSL(bundle.getPublishedBundleDSL())
456455
.publicToMarketplace(bundle.getPublicToMarketplace())
457456
.publicToAll(bundle.getPublicToAll())
458457
.agencyProfile(bundle.getAgencyProfile())

server/api-service/lowcoder-server/src/main/java/org/lowcoder/runner/migrations/DatabaseChangelog.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.lowcoder.runner.migrations.job.AddSuperAdminUser;
2424
import org.lowcoder.runner.migrations.job.CompleteAuthType;
2525
import org.lowcoder.runner.migrations.job.MigrateAuthConfigJob;
26+
import org.springframework.context.annotation.Profile;
2627
import org.springframework.data.domain.Sort;
2728
import org.springframework.data.mongodb.UncategorizedMongoDbException;
2829
import org.springframework.data.mongodb.core.index.CompoundIndexDefinition;
@@ -35,6 +36,7 @@
3536
@SuppressWarnings("all")
3637
@Slf4j
3738
@ChangeLog(order = "001")
39+
@Profile("!test")
3840
public class DatabaseChangelog {
3941

4042
@ChangeSet(order = "001", id = "init-indexes", author = "")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package org.lowcoder.api.authentication;
2+
3+
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
4+
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.extension.ExtendWith;
8+
import org.lowcoder.api.common.mockuser.WithMockUser;
9+
import org.lowcoder.domain.authentication.AuthenticationService;
10+
import org.lowcoder.domain.authentication.FindAuthConfig;
11+
import org.lowcoder.domain.organization.model.Organization;
12+
import org.lowcoder.domain.user.model.User;
13+
import org.lowcoder.domain.user.model.UserState;
14+
import org.lowcoder.domain.user.repository.UserRepository;
15+
import org.lowcoder.sdk.auth.AbstractAuthConfig;
16+
import org.lowcoder.sdk.auth.Oauth2GenericAuthConfig;
17+
import org.lowcoder.sdk.auth.constants.AuthTypeConstants;
18+
import org.lowcoder.sdk.constants.AuthSourceConstants;
19+
import org.lowcoder.sdk.constants.GlobalContext;
20+
import org.mockito.Mockito;
21+
import org.mockito.junit.jupiter.MockitoExtension;
22+
import org.springframework.beans.factory.annotation.Autowired;
23+
import org.springframework.boot.test.context.SpringBootTest;
24+
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
25+
import org.springframework.mock.web.server.MockServerWebExchange;
26+
import org.springframework.test.context.ActiveProfiles;
27+
import reactor.core.publisher.Mono;
28+
import reactor.test.StepVerifier;
29+
import reactor.util.context.Context;
30+
31+
import static com.github.tomakehurst.wiremock.client.WireMock.*;
32+
import static org.junit.jupiter.api.Assertions.assertEquals;
33+
import static org.junit.jupiter.api.Assertions.assertTrue;
34+
35+
/**
36+
* This class is for testing GenericAuth feature
37+
*/
38+
@ActiveProfiles("test")
39+
@SpringBootTest
40+
//@RunWith(SpringRunner.class)
41+
@WireMockTest
42+
@ExtendWith(MockitoExtension.class)
43+
@Slf4j
44+
public class GenericAuthenticateTest {
45+
46+
@Autowired
47+
private AuthenticationController authenticationController;
48+
@Autowired
49+
private UserRepository userRepository;
50+
@Autowired
51+
private AuthenticationService authenticationService;
52+
53+
@Test
54+
@WithMockUser
55+
public void testGoogleLoginSuccess(WireMockRuntimeInfo wmRuntimeInfo) {
56+
log.info("Running mock server on port: {}", wmRuntimeInfo.getHttpPort());
57+
//Begin mocking services
58+
var authConfig = Oauth2GenericAuthConfig.builder()
59+
.source(AuthSourceConstants.GOOGLE)
60+
.sourceName(AuthSourceConstants.GOOGLE_NAME)
61+
.enable(true)
62+
.enableRegister(true)
63+
.authType(AuthTypeConstants.GENERIC)
64+
.clientId("clientid")
65+
.clientSecret("clientsecret")
66+
.sourceDescription("Google Auth")
67+
.sourceIcon("")
68+
.sourceCategory("cat")
69+
.issuerUri("http://google.com")
70+
.authorizationEndpoint(wmRuntimeInfo.getHttpBaseUrl() + "/oauth2/v4/token")
71+
.tokenEndpoint(wmRuntimeInfo.getHttpBaseUrl() + "/oauth2/v4/token")
72+
.userInfoEndpoint(wmRuntimeInfo.getHttpBaseUrl() + "/oauth2/v2/userinfo")
73+
.scope("scope")
74+
.userInfoIntrospection(true)
75+
.build();
76+
77+
var organization = Organization.builder().build();
78+
var mockAuthConfig = new FindAuthConfig(authConfig, organization);
79+
Mockito.when(authenticationService.findAuthConfigByAuthId(Mockito.any(), Mockito.any())).thenReturn(Mono.just(mockAuthConfig));
80+
Mockito.when(authenticationService.findAuthConfigBySource(Mockito.any(), Mockito.any())).thenReturn(Mono.just(mockAuthConfig));
81+
82+
stubFor(post(urlPathEqualTo("/oauth2/v4/token"))
83+
.willReturn(okJson("{\"access_token\":\"ya29.a0AfH6SMB...\",\"expires_in\":3600,\"token_type\":\"Bearer\",\"scope\":\"https://www.googleapis.com/auth/userinfo.profile\"}")));
84+
stubFor(get(urlPathEqualTo("/oauth2/v2/userinfo"))
85+
.willReturn(okJson("{\"sub\":\"user001\",\"email\":\"user001@gmail.com\"}")));
86+
//
87+
88+
String source = AuthSourceConstants.GOOGLE;
89+
String code = "test-code-123456";
90+
String orgId = "org01";
91+
String redirectUrl = "https://test.com";
92+
93+
String uid = "user001";
94+
95+
MockServerHttpRequest request = MockServerHttpRequest.post("").build();
96+
MockServerWebExchange exchange = MockServerWebExchange.builder(request).build();
97+
98+
var authId = getGenericAuthConfigId(orgId).block();
99+
Mono<User> userMono = authenticationController.loginWithThirdParty(authId, source, code, null, redirectUrl, orgId, exchange).hasElement()
100+
.then(userRepository.findByConnections_SourceAndConnections_RawId(source, uid));
101+
102+
StepVerifier.create(userMono)
103+
.assertNext(user -> {
104+
assertEquals("user001@gmail.com", user.getName());
105+
assertEquals(UserState.ACTIVATED, user.getState());
106+
assertEquals(1, user.getConnections().size());
107+
assertTrue(user.getIsEnabled());
108+
})
109+
.verifyComplete();
110+
}
111+
112+
private Mono<String> getGenericAuthConfigId(String orgId) {
113+
return authenticationService.findAuthConfigBySource(orgId, AuthSourceConstants.GOOGLE)
114+
.map(FindAuthConfig::authConfig)
115+
.map(AbstractAuthConfig::getId)
116+
.contextWrite(Context.of(GlobalContext.DOMAIN, "avengers.com"));
117+
}
118+
}

server/api-service/lowcoder-server/src/test/java/org/lowcoder/api/bundle/BundleApiServiceImplTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
import org.lowcoder.domain.permission.model.ResourceRole;
1717
import org.lowcoder.sdk.exception.BizError;
1818
import org.lowcoder.sdk.exception.BizException;
19+
import org.lowcoder.api.home.SessionUserServiceImpl;
20+
import org.lowcoder.domain.organization.model.MemberRole;
21+
import org.lowcoder.domain.organization.model.OrgMember;
1922
import org.springframework.beans.factory.annotation.Autowired;
2023
import org.springframework.boot.test.context.SpringBootTest;
2124
import org.springframework.test.context.junit4.SpringRunner;

0 commit comments

Comments
 (0)