Skip to content

Commit 8bba4f1

Browse files
authored
Merge branch 'dev' into fix/style-issues
2 parents 7a16a9d + c6c2d0d commit 8bba4f1

29 files changed

+439
-89
lines changed

client/packages/lowcoder/src/pages/setting/idSource/OAuthForms/GenericOAuthForm.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import Flex from "antd/es/flex";
1717
import Button from "antd/es/button";
1818
import axios from "axios";
1919
import { IconPicker } from "@lowcoder-ee/comps/controls/iconControl";
20+
import Switch from "antd/es/switch";
2021

21-
const sourceMappingKeys = [
22+
export const sourceMappingKeys = [
2223
'uid',
2324
'email',
2425
'username',
@@ -49,7 +50,7 @@ interface OpenIdProvider {
4950
scopes_supported: string[],
5051
}
5152

52-
interface ConfigProvider {
53+
export interface ConfigProvider {
5354
authType: string,
5455
source: string,
5556
sourceName: string,
@@ -223,6 +224,7 @@ function GenericOAuthForm(props: GenericOAuthFormProp) {
223224
const isPassword = valueObject && valueObject.isPassword;
224225
const isIcon = valueObject && valueObject.isIcon;
225226
const isList = valueObject && valueObject.isList;
227+
const isSwitch = valueObject && valueObject.isSwitch;
226228
return (
227229
<div key={key}>
228230
<Form.Item
@@ -255,13 +257,15 @@ function GenericOAuthForm(props: GenericOAuthFormProp) {
255257
placeholder={trans("idSource.encryptedServer")}
256258
autoComplete={"one-time-code"}
257259
/>
258-
) : !isPassword && !isList && isIcon ? (
260+
) : isSwitch ? (
261+
<Switch />
262+
) : isIcon ? (
259263
<IconPicker
260264
onChange={(value) => form1.setFieldValue("sourceIcon", value)}
261265
label={'Source Icon'}
262266
value={form1.getFieldValue('sourceIcon')}
263267
/>
264-
) : !isPassword && isList && !isIcon ? (
268+
) : isList ? (
265269
<CustomSelect
266270
options={(value as ItemType).options}
267271
placeholder={trans("idSource.formSelectPlaceholder", {

client/packages/lowcoder/src/pages/setting/idSource/detail/index.tsx

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ import { ItemType } from "pages/setting/idSource/idSourceConstants";
3838
import _ from "lodash";
3939
import { messageInstance } from "lowcoder-design/src/components/GlobalInstances";
4040
import { IconPicker } from "@lowcoder-ee/comps/controls/iconControl";
41+
import Switch from "antd/es/switch";
42+
import Title from "antd/es/typography/Title";
43+
import { sourceMappingKeys } from "../OAuthForms/GenericOAuthForm";
44+
import Flex from "antd/es/flex";
4145

4246
type IdSourceDetailProps = {
4347
location: Location & { state: ConfigItem };
@@ -68,13 +72,32 @@ export const IdSourceDetail = (props: IdSourceDetailProps) => {
6872
if (!configDetail) {
6973
goList();
7074
}
71-
const handleSuccess = (values: ConfigItem) => {
75+
const handleSuccess = (values: any) => {
7276
setSaveLoading(true);
73-
const params = {
74-
...values,
75-
...(configDetail.ifLocal ? null : { id: configDetail.id }),
77+
let params = {
78+
id: configDetail.id,
7679
authType: configDetail.authType,
80+
enableRegister: configDetail.enableRegister,
7781
};
82+
83+
if (configDetail.authType === AuthType.Generic) {
84+
const { uid, email, avatar, username, ...newValues } = values;
85+
params = {
86+
...newValues,
87+
sourceMappings: {
88+
uid,
89+
email,
90+
avatar,
91+
username,
92+
},
93+
...params,
94+
}
95+
} else {
96+
params = {
97+
...values,
98+
...params,
99+
}
100+
}
78101
IdSourceApi.saveConfig(params)
79102
.then((resp) => {
80103
if (validateResponse(resp)) {
@@ -157,14 +180,16 @@ export const IdSourceDetail = (props: IdSourceDetailProps) => {
157180
>
158181
{Object.entries(authConfig[configDetail.authType].form).map(([key, value]) => {
159182
const valueObject = _.isObject(value) ? (value as ItemType) : false;
160-
let required = configDetail.ifLocal || (key !== "clientSecret" && key !== "publicKey");
183+
// let required = configDetail.ifLocal || (key !== "clientSecret" && key !== "publicKey");
184+
let required = (key === "clientId" || key === "clientSecret" || key === "scope");
161185
required = valueObject ? valueObject.isRequire ?? required : required;
162186
const hasLock = valueObject && valueObject?.hasLock;
163187
const tip = valueObject && valueObject.tip;
164188
const label = valueObject ? valueObject.label : value as string;
165189
const isList = valueObject && valueObject.isList;
166190
const isPassword = valueObject && valueObject.isPassword;
167191
const isIcon = valueObject && valueObject.isIcon;
192+
const isSwitch = valueObject && valueObject.isSwitch;
168193
return (
169194
<div key={key}>
170195
<Form.Item
@@ -208,30 +233,32 @@ export const IdSourceDetail = (props: IdSourceDetailProps) => {
208233
}
209234
autoComplete={"one-time-code"}
210235
/>
211-
) : !isPassword && !isList && !isIcon ? (
212-
<Input
213-
placeholder={trans("idSource.formPlaceholder", {
214-
label,
215-
})}
216-
disabled={hasLock && lock}
217-
prefix={
218-
hasLock &&
219-
(lock ? <LockIcon onClick={() => handleLockClick()} /> : <UnLockIcon />)
220-
}
221-
/>
222-
) : !isPassword && !isList && isIcon ? (
236+
) : isSwitch ? (
237+
<Switch />
238+
) : isIcon ? (
223239
<IconPicker
224240
onChange={(value) => form.setFieldValue("sourceIcon", value)}
225241
label={'Source Icon'}
226242
value={form.getFieldValue('sourceIcon')}
227243
/>
228-
) : (
244+
) : isList ? (
229245
<CustomSelect
230246
options={(value as ItemType).options}
231247
placeholder={trans("idSource.formSelectPlaceholder", {
232248
label,
233249
})}
234250
/>
251+
) : (
252+
<Input
253+
placeholder={trans("idSource.formPlaceholder", {
254+
label,
255+
})}
256+
disabled={hasLock && lock}
257+
prefix={
258+
hasLock &&
259+
(lock ? <LockIcon onClick={() => handleLockClick()} /> : <UnLockIcon />)
260+
}
261+
/>
235262
)}
236263
</Form.Item>
237264
{hasLock && lock && (
@@ -246,6 +273,34 @@ export const IdSourceDetail = (props: IdSourceDetailProps) => {
246273
<CheckboxStyled>{trans("idSource.enableRegister")}</CheckboxStyled>
247274
</Form.Item> */}
248275

276+
{configDetail.authType === AuthType.Generic && (
277+
<>
278+
<Title level={5}>Source Mappings</Title>
279+
{sourceMappingKeys.map(sourceKey => (
280+
<Flex gap="10px" align="start" key={sourceKey} >
281+
<Input
282+
readOnly
283+
disabled
284+
value={sourceKey}
285+
style={{flex: 1}}
286+
/>
287+
<span> &#8594; </span>
288+
<Form.Item
289+
name={sourceKey}
290+
rules={[{ required: true }]}
291+
style={{flex: 1}}
292+
>
293+
<Input
294+
placeholder={trans("idSource.formPlaceholder", {
295+
label: sourceKey,
296+
})}
297+
/>
298+
</Form.Item>
299+
</Flex>
300+
))}
301+
</>
302+
)}
303+
249304
<Form.Item>
250305
<SaveButton loading={saveLoading} disabled={saveDisable} htmlType="submit">
251306
{configDetail.enable ? trans("idSource.save") : trans("idSource.saveBtn")}

client/packages/lowcoder/src/pages/setting/idSource/idSourceConstants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export const authConfig = {
100100
userInfoEndpoint: { label: 'UserInfo Endpoint', isRequire: true },
101101
// jwks: { label: 'Authorize URL', isRequire: true },
102102
scope: "Scope",
103+
userInfoIntrospection: { label: 'Use OpenID User Introspection', isSwitch: true, isRequire: false},
103104
// baseUrl: "Base URL",
104105
// realm: "Realm",
105106
},
@@ -126,6 +127,7 @@ export type ItemType = {
126127
isRequire?: boolean;
127128
isPassword?: boolean;
128129
isIcon?: boolean;
130+
isSwitch?: boolean;
129131
hasLock?: boolean;
130132
tip?: string;
131133
}

deploy/docker/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ RUN mkdir -p /etc/apt/keyrings \
204204
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y bash gnupg curl lsb-release \
205205
&& curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg \
206206
&& echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb bookworm main" | tee /etc/apt/sources.list.d/redis.list \
207-
&& curl -fsSL https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-archive-keyring.gpg \
208-
&& echo "deb [signed-by=/usr/share/keyrings/mongodb-archive-keyring.gpg] https://repo.mongodb.org/apt/debian bookworm/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list \
207+
&& curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-archive-keyring.gpg \
208+
&& echo "deb [signed-by=/usr/share/keyrings/mongodb-archive-keyring.gpg] https://repo.mongodb.org/apt/debian bookworm/mongodb-org/7.0 main" | tee /etc/apt/sources.list.d/mongodb-org-7.0.list \
209209
&& apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends -y \
210210
mongodb-org \
211211
redis \

deploy/docker/docker-compose-multi.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ services:
6060
#
6161
LOWCODER_API_KEY_SECRET: "5a41b090758b39b226603177ef48d73ae9839dd458ccb7e66f7e7cc028d5a50b"
6262
LOWCODER_WORKSPACE_MODE: SAAS
63+
# Lowcoder notification emails setup
64+
LOWCODER_ADMIN_SMTP_HOST: smtp.gmail.com
65+
LOWCODER_ADMIN_SMTP_PORT: 587
66+
LOWCODER_ADMIN_SMTP_USERNAME:
67+
LOWCODER_ADMIN_SMTP_PASSWORD:
68+
LOWCODER_ADMIN_SMTP_AUTH: true
69+
LOWCODER_ADMIN_SMTP_SSL_ENABLED: false
70+
LOWCODER_ADMIN_SMTP_STARTTLS_ENABLED: true
71+
LOWCODER_ADMIN_SMTP_STARTTLS_REQUIRED: true
72+
# Email used as sender in lost password email
73+
LOWCODER_EMAIL_NOTIFICATIONS_SENDER: info@localhost
6374
restart: unless-stopped
6475
depends_on:
6576
- mongodb

deploy/docker/docker-compose.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ services:
1212
- "3443:3443"
1313
# - "27017:27017"
1414
environment:
15+
# Public base url
16+
LOWCODER_PUBLIC_URL: "http://localhost:3000/"
1517
# enable services
1618
LOWCODER_REDIS_ENABLED: "true"
1719
LOWCODER_MONGODB_ENABLED: "true"
@@ -59,6 +61,17 @@ services:
5961
LOWCODER_MAX_REQUEST_SIZE: 20m
6062
LOWCODER_MAX_QUERY_TIMEOUT: 120
6163
LOWCODER_WORKSPACE_MODE: SAAS
64+
# Lowcoder notification emails setup
65+
LOWCODER_ADMIN_SMTP_HOST: smtp.gmail.com
66+
LOWCODER_ADMIN_SMTP_PORT: 587
67+
LOWCODER_ADMIN_SMTP_USERNAME:
68+
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
73+
# Email used as sender in lost password email
74+
LOWCODER_EMAIL_NOTIFICATIONS_SENDER: info@localhost
6275
volumes:
6376
- ./lowcoder-stacks:/lowcoder-stacks
6477
- ./lowcoder-stacks/assets:/lowcoder/assets

server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/repository/ApplicationRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public interface ApplicationRepository extends ReactiveMongoRepository<Applicati
3232

3333
Flux<Application> findByIdIn(Collection<String> ids);
3434

35+
Flux<Application> findByCreatedByAndIdIn(String userId, Collection<String> ids);
36+
3537
/**
3638
* Filter public applications from list of supplied IDs
3739
*/

server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ public interface ApplicationService {
5252

5353
@NonEmptyMono
5454
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
55-
Mono<Set<String>> getFilteredPublicApplicationIds(ApplicationRequestType requestType, Collection<String> applicationIds, boolean isAnonymous, Boolean isPrivateMarketplace);
55+
Mono<Set<String>> getFilteredPublicApplicationIds(ApplicationRequestType requestType, Collection<String> applicationIds, String userId, Boolean isPrivateMarketplace);
5656

5757
@NonEmptyMono
5858
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
5959
Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationIds);
6060

6161
@NonEmptyMono
6262
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
63-
Mono<Set<String>> getPrivateApplicationIds(Collection<String> applicationIds);
63+
Mono<Set<String>> getPrivateApplicationIds(Collection<String> applicationIds, String userId);
6464

6565
@NonEmptyMono
6666
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")

server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/application/service/ApplicationServiceImpl.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@
77
import java.util.stream.Collectors;
88

99
import lombok.RequiredArgsConstructor;
10+
import org.apache.commons.lang3.StringUtils;
1011
import org.lowcoder.domain.application.model.Application;
1112
import org.lowcoder.domain.application.model.ApplicationRequestType;
1213
import org.lowcoder.domain.application.model.ApplicationStatus;
1314
import org.lowcoder.domain.application.repository.ApplicationRepository;
15+
import org.lowcoder.domain.organization.repository.OrganizationRepository;
16+
import org.lowcoder.domain.organization.service.OrgMemberService;
1417
import org.lowcoder.domain.permission.model.ResourceRole;
1518
import org.lowcoder.domain.permission.service.ResourcePermissionService;
19+
import org.lowcoder.domain.user.repository.UserRepository;
20+
import org.lowcoder.domain.user.service.UserService;
1621
import org.lowcoder.infra.annotation.NonEmptyMono;
1722
import org.lowcoder.infra.mongo.MongoUpsertHelper;
1823
import org.lowcoder.sdk.constants.FieldName;
@@ -37,6 +42,7 @@ public class ApplicationServiceImpl implements ApplicationService {
3742
private final MongoUpsertHelper mongoUpsertHelper;
3843
private final ResourcePermissionService resourcePermissionService;
3944
private final ApplicationRepository repository;
45+
private final UserRepository userRepository;
4046

4147
@Override
4248
public Mono<Application> findById(String id) {
@@ -219,8 +225,8 @@ public Mono<Boolean> setApplicationAsAgencyProfile(String applicationId, boolean
219225
@Override
220226
@NonEmptyMono
221227
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
222-
public Mono<Set<String>> getFilteredPublicApplicationIds(ApplicationRequestType requestType, Collection<String> applicationIds, boolean isAnonymous, Boolean isPrivateMarketplace) {
223-
228+
public Mono<Set<String>> getFilteredPublicApplicationIds(ApplicationRequestType requestType, Collection<String> applicationIds, String userId, Boolean isPrivateMarketplace) {
229+
boolean isAnonymous = StringUtils.isBlank(userId);
224230
switch(requestType)
225231
{
226232
case PUBLIC_TO_ALL:
@@ -230,7 +236,7 @@ public Mono<Set<String>> getFilteredPublicApplicationIds(ApplicationRequestType
230236
}
231237
else
232238
{
233-
return getPrivateApplicationIds(applicationIds);
239+
return getPrivateApplicationIds(applicationIds, userId);
234240
}
235241
case PUBLIC_TO_MARKETPLACE:
236242
return getPublicMarketplaceApplicationIds(applicationIds, isAnonymous, isPrivateMarketplace);
@@ -262,11 +268,16 @@ public Mono<Set<String>> getPublicApplicationIds(Collection<String> applicationI
262268
@Override
263269
@NonEmptyMono
264270
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
265-
public Mono<Set<String>> getPrivateApplicationIds(Collection<String> applicationIds) {
271+
public Mono<Set<String>> getPrivateApplicationIds(Collection<String> applicationIds, String userId) {
272+
266273
// TODO: in 2.4.0 we need to check whether the app was published or not
267-
return repository.findByIdIn(applicationIds)
274+
return repository.findByCreatedByAndIdIn(userId, applicationIds)
268275
.map(HasIdAndAuditing::getId)
269276
.collect(Collectors.toSet());
277+
278+
// return repository.findByIdIn(applicationIds)
279+
// .map(HasIdAndAuditing::getId)
280+
// .collect(Collectors.toSet());
270281
}
271282

272283

server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/permission/service/ApplicationPermissionHandler.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserPermission
5353
// This is for PTM apps that are public but only available to logged-in users
5454
@Override
5555
protected Mono<Map<String, List<ResourcePermission>>> getNonAnonymousUserPublicResourcePermissions
56-
(Collection<String> resourceIds, ResourceAction resourceAction) {
56+
(Collection<String> resourceIds, ResourceAction resourceAction, String userId) {
5757

5858
Set<String> applicationIds = newHashSet(resourceIds);
59-
return Mono.zip(applicationService.getPrivateApplicationIds(applicationIds),
59+
return Mono.zip(applicationService.getPrivateApplicationIds(applicationIds, userId),
6060
templateSolutionService.getTemplateApplicationIds(applicationIds))
6161
.map(tuple -> {
6262
Set<String> publicAppIds = tuple.getT1();
@@ -75,7 +75,7 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserApplicatio
7575
}
7676

7777
Set<String> applicationIds = newHashSet(resourceIds);
78-
return Mono.zip(applicationService.getFilteredPublicApplicationIds(requestType, applicationIds, Boolean.TRUE, config.getMarketplace().isPrivateMode())
78+
return Mono.zip(applicationService.getFilteredPublicApplicationIds(requestType, applicationIds, null, config.getMarketplace().isPrivateMode())
7979
.defaultIfEmpty(new HashSet<>()),
8080
templateSolutionService.getTemplateApplicationIds(applicationIds)
8181
.defaultIfEmpty(new HashSet<>())
@@ -88,9 +88,9 @@ protected Mono<Map<String, List<ResourcePermission>>> getAnonymousUserApplicatio
8888

8989
@Override
9090
protected Mono<Map<String, List<ResourcePermission>>> getNonAnonymousUserApplicationPublicResourcePermissions(
91-
Collection<String> resourceIds, ResourceAction resourceAction, ApplicationRequestType requestType) {
91+
Collection<String> resourceIds, ResourceAction resourceAction, ApplicationRequestType requestType, String userId) {
9292
Set<String> applicationIds = newHashSet(resourceIds);
93-
return Mono.zip(applicationService.getFilteredPublicApplicationIds(requestType, applicationIds, Boolean.FALSE, config.getMarketplace().isPrivateMode()),
93+
return Mono.zip(applicationService.getFilteredPublicApplicationIds(requestType, applicationIds, userId, config.getMarketplace().isPrivateMode()),
9494
templateSolutionService.getTemplateApplicationIds(applicationIds))
9595
.map(tuple -> {
9696
Set<String> publicAppIds = tuple.getT1();

0 commit comments

Comments
 (0)