Skip to content

Commit 40a3a9c

Browse files
committed
feat:
1. Support ui for auth config enable/disable. 2. Identify the auth config by id instead of source. 3. Move the code of form register from service to FormAuthRequest. 4. Support the Google and GitHub authentication type. 5. Store tokens under the connections of the user.
1 parent 0ab1205 commit 40a3a9c

File tree

73 files changed

+1884
-345
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1884
-345
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.openblocks.domain.authentication;
2+
3+
import reactor.core.publisher.Flux;
4+
import reactor.core.publisher.Mono;
5+
6+
public interface AuthenticationService {
7+
8+
Mono<FindAuthConfig> findAuthConfigByAuthId(String authId);
9+
10+
Mono<FindAuthConfig> findAuthConfigBySource(String source);
11+
12+
Flux<FindAuthConfig> findAllAuthConfigs(boolean enableOnly);
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.openblocks.domain.authentication;
2+
3+
import static com.openblocks.sdk.exception.BizError.LOG_IN_SOURCE_NOT_SUPPORTED;
4+
import static com.openblocks.sdk.util.ExceptionUtils.ofError;
5+
6+
import java.util.Objects;
7+
import java.util.function.Function;
8+
import java.util.stream.Collectors;
9+
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.stereotype.Service;
12+
13+
import com.openblocks.domain.organization.service.OrganizationService;
14+
import com.openblocks.sdk.auth.AbstractAuthConfig;
15+
import com.openblocks.sdk.config.AuthProperties;
16+
import com.openblocks.sdk.config.CommonConfig;
17+
import com.openblocks.sdk.constants.WorkspaceMode;
18+
19+
import lombok.extern.slf4j.Slf4j;
20+
import reactor.core.publisher.Flux;
21+
import reactor.core.publisher.Mono;
22+
23+
@Slf4j
24+
@Service
25+
public class AuthenticationServiceImpl implements AuthenticationService {
26+
27+
@Autowired
28+
private OrganizationService organizationService;
29+
@Autowired
30+
private CommonConfig commonConfig;
31+
@Autowired
32+
private AuthProperties authProperties;
33+
34+
@Override
35+
public Mono<FindAuthConfig> findAuthConfigByAuthId(String authId) {
36+
return findAuthConfig(abstractAuthConfig -> Objects.equals(authId, abstractAuthConfig.getId()));
37+
}
38+
39+
@Override
40+
@Deprecated
41+
public Mono<FindAuthConfig> findAuthConfigBySource(String source) {
42+
return findAuthConfig(abstractAuthConfig -> Objects.equals(source, abstractAuthConfig.getSource()));
43+
}
44+
45+
private Mono<FindAuthConfig> findAuthConfig(Function<AbstractAuthConfig, Boolean> condition) {
46+
return findAllAuthConfigs(true)
47+
.filter(findAuthConfig -> condition.apply(findAuthConfig.authConfig()))
48+
.next()
49+
.switchIfEmpty(ofError(LOG_IN_SOURCE_NOT_SUPPORTED, "LOG_IN_SOURCE_NOT_SUPPORTED"));
50+
}
51+
52+
@Override
53+
public Flux<FindAuthConfig> findAllAuthConfigs(boolean enableOnly) {
54+
return findAllAuthConfigsByDomain()
55+
.switchIfEmpty(findAllAuthConfigsForEnterpriseMode())
56+
.switchIfEmpty(findAllAuthConfigsForSaasMode())
57+
.filter(findAuthConfig -> {
58+
if (enableOnly) {
59+
return findAuthConfig.authConfig().isEnable();
60+
}
61+
return true;
62+
});
63+
}
64+
65+
private Flux<FindAuthConfig> findAllAuthConfigsByDomain() {
66+
return organizationService.getByDomain()
67+
.flatMapIterable(organization ->
68+
organization.getAuthConfigs()
69+
.stream()
70+
.map(abstractAuthConfig -> new FindAuthConfig(abstractAuthConfig, organization))
71+
.collect(Collectors.toList())
72+
)
73+
.doOnNext(__ -> log.info("find auth configs by domain"));
74+
}
75+
76+
protected Flux<FindAuthConfig> findAllAuthConfigsForEnterpriseMode() {
77+
if (commonConfig.getWorkspace().getMode() == WorkspaceMode.SAAS) {
78+
return Flux.empty();
79+
}
80+
return organizationService.getOrganizationInEnterpriseMode()
81+
.flatMapIterable(organization ->
82+
organization.getAuthConfigs()
83+
.stream()
84+
.map(abstractAuthConfig -> new FindAuthConfig(abstractAuthConfig, organization))
85+
.collect(Collectors.toList())
86+
)
87+
.doOnNext(__ -> log.info("find auth configs for enterprise mode."));
88+
}
89+
90+
private Flux<FindAuthConfig> findAllAuthConfigsForSaasMode() {
91+
if (commonConfig.getWorkspace().getMode() == WorkspaceMode.SAAS) {
92+
return Flux.fromIterable(authProperties.getAuthConfigs())
93+
.map(abstractAuthConfig -> new FindAuthConfig(abstractAuthConfig, null))
94+
.doOnNext(__ -> log.info("find auth configs for saas mode"));
95+
}
96+
return Flux.empty();
97+
}
98+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.openblocks.domain.authentication;
2+
3+
import javax.annotation.Nullable;
4+
5+
import com.openblocks.domain.organization.model.Organization;
6+
import com.openblocks.sdk.auth.AbstractAuthConfig;
7+
8+
public record FindAuthConfig(AbstractAuthConfig authConfig, @Nullable Organization organization) {
9+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.openblocks.api.authentication.request;
1+
package com.openblocks.domain.authentication.context;
22

33
import javax.annotation.Nullable;
44

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.openblocks.domain.authentication.context;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public class FormAuthRequestContext extends AuthRequestContext {
7+
8+
/**
9+
* phone or email for now.
10+
*/
11+
private final String loginId;
12+
private final String password;
13+
private final boolean register;
14+
15+
public FormAuthRequestContext(String loginId, String password, boolean register) {
16+
this.loginId = loginId;
17+
this.password = password;
18+
this.register = register;
19+
}
20+
}

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/encryption/ModelEncryptionEventListener.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.openblocks.domain.encryption;
22

3+
import org.springframework.context.event.EventListener;
34
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
45
import org.springframework.data.mongodb.core.mapping.event.AfterConvertEvent;
56
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
67

8+
import com.openblocks.infra.mongo.MongoUpsertHelper;
9+
import com.openblocks.sdk.event.BeforeSaveEvent;
10+
711
import lombok.extern.slf4j.Slf4j;
812

913
@Slf4j
@@ -33,4 +37,15 @@ public void onAfterConvert(AfterConvertEvent<E> event) {
3337
}
3438
}
3539

40+
/**
41+
* Only for {@link MongoUpsertHelper}
42+
*/
43+
@EventListener
44+
public <T> void onBeforeSaveEvent(BeforeSaveEvent<T> beforeSaveEvent) {
45+
T source = beforeSaveEvent.source();
46+
47+
if (source instanceof EncryptRequired encryptRequired) {
48+
encryptRequired.encrypt(encryptionService);
49+
}
50+
}
3651
}

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/organization/model/Organization.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import static java.util.Optional.ofNullable;
55
import static org.apache.commons.lang3.ObjectUtils.firstNonNull;
66

7+
import java.util.Collections;
78
import java.util.HashMap;
9+
import java.util.List;
10+
import java.util.Optional;
811

912
import org.apache.commons.lang3.builder.ToStringBuilder;
1013
import org.apache.commons.lang3.builder.ToStringStyle;
@@ -15,6 +18,7 @@
1518
import com.openblocks.domain.encryption.DecryptRequired;
1619
import com.openblocks.domain.encryption.EncryptRequired;
1720
import com.openblocks.domain.encryption.EncryptionService;
21+
import com.openblocks.sdk.auth.AbstractAuthConfig;
1822
import com.openblocks.sdk.models.HasIdAndAuditing;
1923

2024
import lombok.Getter;
@@ -92,4 +96,10 @@ public static class OrganizationCommonSettings extends HashMap<String, Object> {
9296
public long getCreateTime() {
9397
return createdAt != null ? createdAt.toEpochMilli() : 0;
9498
}
99+
100+
public List<AbstractAuthConfig> getAuthConfigs() {
101+
return Optional.ofNullable(organizationDomain)
102+
.map(OrganizationDomain::getAuthConfigs)
103+
.orElse(Collections.emptyList());
104+
}
95105
}

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/organization/model/OrganizationDomain.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package com.openblocks.domain.organization.model;
22

3+
import java.util.ArrayList;
34
import java.util.List;
45
import java.util.function.Function;
56

6-
import org.apache.commons.collections4.ListUtils;
7-
87
import com.openblocks.sdk.auth.AbstractAuthConfig;
98

109
import lombok.Getter;
@@ -19,7 +18,10 @@ public class OrganizationDomain implements EnterpriseConnectionConfig {
1918

2019
@Override
2120
public List<AbstractAuthConfig> getAuthConfigs() {
22-
return ListUtils.emptyIfNull(this.authConfigs);
21+
if (authConfigs == null) {
22+
authConfigs = new ArrayList<>();
23+
}
24+
return authConfigs;
2325
}
2426

2527
OrganizationDomain doEncrypt(Function<String, String> encryptFunc) {

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/organization/repository/OrganizationRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ public interface OrganizationRepository extends ReactiveMongoRepository<Organiza
2222
Mono<Organization> findBySourceAndThirdPartyCompanyIdAndState(String source, String tpCompanyId, OrganizationState state);
2323

2424
Mono<Organization> findByOrganizationDomain_DomainAndState(String domain, OrganizationState state);
25+
26+
Flux<Organization> findByOrganizationDomainIsNotNull();
2527
}

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/organization/service/OrgMemberServiceImpl.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,13 @@ public Flux<OrgMember> getAllActiveOrgs(String userId) {
8282
.flatMap(orgIds -> {
8383
Workspace workspace = commonConfig.getWorkspace();
8484
if (workspace.getMode() == WorkspaceMode.ENTERPRISE) {
85-
if (StringUtils.isNotBlank(workspace.getEnterpriseOrgId())) {
86-
if (orgIds.contains(workspace.getEnterpriseOrgId())) {
87-
return Mono.just(List.of(workspace.getEnterpriseOrgId()));
85+
String enterpriseOrgId = workspace.getEnterpriseOrgId();
86+
if (StringUtils.isNotBlank(enterpriseOrgId)) {
87+
if (orgIds.contains(enterpriseOrgId)) {
88+
return Mono.just(List.of(enterpriseOrgId));
8889
}
89-
return addMember(workspace.getEnterpriseOrgId(), userId, MemberRole.MEMBER)
90-
.thenReturn(List.of(workspace.getEnterpriseOrgId()));
90+
return addMember(enterpriseOrgId, userId, MemberRole.MEMBER)
91+
.thenReturn(List.of(enterpriseOrgId));
9192
}
9293
if (orgIds.size() > 1) {
9394
return Mono.just(orgIds.subList(0, 1));

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/organization/service/OrganizationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public interface OrganizationService {
4040
Mono<Organization> getBySourceAndTpCompanyId(String source, String companyId);
4141

4242
@PossibleEmptyMono
43-
Mono<Organization> getByDomain(String domain);
43+
Mono<Organization> getByDomain();
4444

4545
Mono<Boolean> updateCommonSettings(String orgId, String key, Object value);
4646
}

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/organization/service/OrganizationServiceImpl.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.openblocks.sdk.constants.WorkspaceMode;
4343
import com.openblocks.sdk.exception.BizError;
4444
import com.openblocks.sdk.exception.BizException;
45+
import com.openblocks.sdk.util.UriUtils;
4546

4647
import lombok.extern.slf4j.Slf4j;
4748
import reactor.core.publisher.Flux;
@@ -255,8 +256,9 @@ public Mono<Organization> getBySourceAndTpCompanyId(String source, String compan
255256
}
256257

257258
@Override
258-
public Mono<Organization> getByDomain(String domain) {
259-
return repository.findByOrganizationDomain_DomainAndState(domain, ACTIVE);
259+
public Mono<Organization> getByDomain() {
260+
return UriUtils.getRefererDomainFromContext()
261+
.flatMap(domain -> repository.findByOrganizationDomain_DomainAndState(domain, ACTIVE));
260262
}
261263

262264
@Override
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.openblocks.domain.user.model;
2+
3+
import java.io.Serializable;
4+
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
import lombok.Setter;
10+
11+
@Getter
12+
@Setter
13+
@Builder
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
public class AuthToken implements Serializable {
17+
private String accessToken;
18+
private int expireIn;
19+
private String refreshToken;
20+
private int refreshTokenExpireIn;
21+
22+
private String openId;
23+
private String code;
24+
}

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/user/model/AuthorizedUser.java renamed to server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/user/model/AuthenticationUser.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
package com.openblocks.domain.user.model;
22

33
import java.util.Map;
4+
import java.util.Optional;
45
import java.util.Set;
56

67
import javax.annotation.Nullable;
78

89
import org.apache.commons.lang3.StringUtils;
910

11+
import com.openblocks.domain.authentication.context.AuthRequestContext;
12+
13+
import lombok.AllArgsConstructor;
1014
import lombok.Builder;
1115
import lombok.Getter;
16+
import lombok.NoArgsConstructor;
1217
import lombok.Setter;
1318

1419
@Setter
1520
@Getter
1621
@Builder
17-
public class AuthorizedUser {
22+
@NoArgsConstructor
23+
@AllArgsConstructor
24+
public class AuthenticationUser {
1825

19-
private String source;
2026
private String uid;
2127
private String username;
2228
private String avatar;
@@ -25,26 +31,27 @@ public class AuthorizedUser {
2531

2632
private String orgId;
2733

28-
/**
29-
* while user login by email or phone with password, we authenticated it by self-db which return a user directly.
30-
* we store it here to avoid querying it from db again.
31-
*/
32-
@Nullable
33-
private User user;
34+
private AuthRequestContext authContext;
3435

3536
/**
3637
* While user is authenticated by oauth 2.0, we store the token information which may be used in the future datasource or query.
3738
*/
38-
private ConnectionAuthToken authConnectionAuthToken;
39+
@Nullable
40+
private AuthToken authToken;
41+
42+
public String getSource() {
43+
return getAuthContext().getAuthConfig().getSource();
44+
}
3945

4046
public Connection toAuthConnection() {
4147
return Connection.builder()
48+
.authId(getAuthContext().getAuthConfig().getId())
4249
.source(getSource())
4350
.name(getUsername())
4451
.rawId(getUid())
4552
.avatar(getAvatar())
4653
.orgIds(StringUtils.isBlank(getOrgId()) ? Set.of() : Set.of(getOrgId()))
47-
.authConnectionAuthToken(authConnectionAuthToken)
54+
.authConnectionAuthToken(Optional.ofNullable(authToken).map(ConnectionAuthToken::of).orElse(null))
4855
.rawUserInfo(getRawUserInfo())
4956
.build();
5057
}

0 commit comments

Comments
 (0)