Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bf3bc70

Browse files
Merge branch 'main' into layout-component
2 parents bb5cefd + 14d26d5 commit bf3bc70

File tree

12 files changed

+240
-19
lines changed

12 files changed

+240
-19
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.lowcoder.sdk.auth;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonView;
5+
import lombok.Getter;
6+
import org.apache.commons.lang3.StringUtils;
7+
import org.lowcoder.sdk.auth.constants.AuthTypeConstants;
8+
import org.lowcoder.sdk.auth.constants.Oauth2Constants;
9+
import org.lowcoder.sdk.config.SerializeConfig.JsonViews;
10+
11+
import javax.annotation.Nullable;
12+
import java.util.function.Function;
13+
14+
import static org.lowcoder.sdk.auth.constants.Oauth2Constants.CLIENT_ID_PLACEHOLDER;
15+
import static org.lowcoder.sdk.auth.constants.Oauth2Constants.INSTANCE_ID_PLACEHOLDER;
16+
17+
/**
18+
* OAuth2 ORY auth config.
19+
*/
20+
@Getter
21+
public class Oauth2OryAuthConfig extends Oauth2SimpleAuthConfig {
22+
23+
protected String instanceId;
24+
25+
@JsonCreator
26+
public Oauth2OryAuthConfig(
27+
@Nullable String id,
28+
Boolean enable,
29+
Boolean enableRegister,
30+
String source,
31+
String sourceName,
32+
String clientId,
33+
String clientSecret,
34+
String instanceId,
35+
String authType) {
36+
super(id, enable, enableRegister, source, sourceName, clientId, clientSecret, authType);
37+
this.instanceId = instanceId;
38+
}
39+
40+
@Override
41+
public String replaceAuthUrlClientIdPlaceholder(String url) {
42+
return super.replaceAuthUrlClientIdPlaceholder(url).replace(INSTANCE_ID_PLACEHOLDER, instanceId);
43+
}
44+
}

‎server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/auth/Oauth2SimpleAuthConfig.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public String getAuthorizeUrl() {
5252
return switch (authType) {
5353
case AuthTypeConstants.GOOGLE -> replaceAuthUrlClientIdPlaceholder(Oauth2Constants.GOOGLE_AUTHORIZE_URL);
5454
case AuthTypeConstants.GITHUB -> replaceAuthUrlClientIdPlaceholder(Oauth2Constants.GITHUB_AUTHORIZE_URL);
55+
case AuthTypeConstants.ORY -> replaceAuthUrlClientIdPlaceholder(Oauth2Constants.ORY_AUTHORIZE_URL);
5556
default -> null;
5657
};
5758
}
@@ -73,7 +74,7 @@ public void merge(AbstractAuthConfig oldConfig) {
7374
}
7475
}
7576

76-
private String replaceAuthUrlClientIdPlaceholder(String url) {
77+
public String replaceAuthUrlClientIdPlaceholder(String url) {
7778
return url.replace(CLIENT_ID_PLACEHOLDER, clientId);
7879
}
7980
}

‎server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/auth/constants/AuthTypeConstants.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ public class AuthTypeConstants {
88
public static final String FORM = "FORM";
99
public static final String GOOGLE = "GOOGLE";
1010
public static final String GITHUB = "GITHUB";
11+
public static final String ORY = "ORY";
1112
}

‎server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/auth/constants/Oauth2Constants.java‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ public class Oauth2Constants {
77
public static final String REDIRECT_URL_PLACEHOLDER = "$REDIRECT_URL";
88
public static final String STATE_PLACEHOLDER = "$STATE";
99

10+
public static final String INSTANCE_ID_PLACEHOLDER = "INSTANCE_ID";
11+
1012
// authorize url
1113
public static final String GITHUB_AUTHORIZE_URL = "https://github.com/login/oauth/authorize"
1214
+ "?response_type=code"
@@ -23,4 +25,11 @@ public class Oauth2Constants {
2325
+ "&access_type=offline"
2426
+ "&scope=openid email profile"
2527
+ "&prompt=select_account";
28+
29+
public static final String ORY_AUTHORIZE_URL = "https://" + INSTANCE_ID_PLACEHOLDER + "/oauth2/auth"
30+
+ "?response_type=code"
31+
+ "&client_id=" + CLIENT_ID_PLACEHOLDER
32+
+ "&redirect_uri=" + REDIRECT_URL_PLACEHOLDER
33+
+ "&state=" + STATE_PLACEHOLDER
34+
+ "&scope=openid email profile offline_access";
2635
}

‎server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/constants/AuthSourceConstants.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ public class AuthSourceConstants {
1010
public static final String PHONE = "PHONE";
1111
public static final String GOOGLE = "GOOGLE";
1212
public static final String GITHUB = "GITHUB";
13+
public static final String ORY = "ORY";
1314

1415
// source name
1516
public static final String GOOGLE_NAME = "Google";
1617
public static final String GITHUB_NAME = "Github";
18+
public static final String ORY_NAME = "Ory";
1719

1820
// default source and source name for common protocol
1921
// oauth 2.0

‎server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/util/JsonUtils.java‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package org.lowcoder.sdk.util;
22

3-
import static org.lowcoder.sdk.auth.constants.AuthTypeConstants.FORM;
4-
import static org.lowcoder.sdk.auth.constants.AuthTypeConstants.GITHUB;
5-
import static org.lowcoder.sdk.auth.constants.AuthTypeConstants.GOOGLE;
6-
73
import java.nio.charset.StandardCharsets;
84
import java.util.List;
95
import java.util.Map;
@@ -12,6 +8,7 @@
128
import javax.annotation.Nullable;
139

1410
import org.lowcoder.sdk.auth.EmailAuthConfig;
11+
import org.lowcoder.sdk.auth.Oauth2OryAuthConfig;
1512
import org.lowcoder.sdk.auth.Oauth2SimpleAuthConfig;
1613

1714
import com.fasterxml.jackson.annotation.JsonCreator;
@@ -32,6 +29,8 @@
3229

3330
import lombok.extern.slf4j.Slf4j;
3431

32+
import static org.lowcoder.sdk.auth.constants.AuthTypeConstants.*;
33+
3534
@Slf4j
3635
public final class JsonUtils {
3736

@@ -46,6 +45,7 @@ public final class JsonUtils {
4645
OBJECT_MAPPER.registerSubtypes(new NamedType(EmailAuthConfig.class, FORM));
4746
OBJECT_MAPPER.registerSubtypes(new NamedType(Oauth2SimpleAuthConfig.class, GITHUB));
4847
OBJECT_MAPPER.registerSubtypes(new NamedType(Oauth2SimpleAuthConfig.class, GOOGLE));
48+
OBJECT_MAPPER.registerSubtypes(new NamedType(Oauth2OryAuthConfig.class, ORY));
4949
}
5050

5151
public static final JsonNode EMPTY_JSON_NODE = createObjectNode();

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/authentication/dto/AuthConfigRequest.java‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ public boolean isEnableRegister() {
2828
return MapUtils.getBoolean(this, "enableRegister", true);
2929
}
3030

31+
@Nullable
32+
public String getInstanceId() {
33+
return getString("instanceId");
34+
}
35+
3136
@Nullable
3237
public String getClientId() {
3338
return getString("clientId");

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
package org.lowcoder.api.authentication.request.oauth2;
22

3-
import static org.lowcoder.sdk.auth.constants.AuthTypeConstants.GITHUB;
4-
import static org.lowcoder.sdk.auth.constants.AuthTypeConstants.GOOGLE;
5-
63
import java.util.Set;
74

85
import org.lowcoder.api.authentication.request.AuthRequest;
96
import org.lowcoder.api.authentication.request.AuthRequestFactory;
107
import org.lowcoder.api.authentication.request.oauth2.request.AbstractOauth2Request;
118
import org.lowcoder.api.authentication.request.oauth2.request.GithubRequest;
129
import org.lowcoder.api.authentication.request.oauth2.request.GoogleRequest;
10+
import org.lowcoder.api.authentication.request.oauth2.request.OryRequest;
11+
import org.lowcoder.sdk.auth.Oauth2OryAuthConfig;
1312
import org.lowcoder.sdk.auth.Oauth2SimpleAuthConfig;
1413
import org.springframework.stereotype.Component;
1514

1615
import reactor.core.publisher.Mono;
1716

17+
import static org.lowcoder.sdk.auth.constants.AuthTypeConstants.*;
18+
1819
@Component
1920
public class Oauth2AuthRequestFactory implements AuthRequestFactory<OAuth2RequestContext> {
2021

@@ -27,6 +28,7 @@ private AbstractOauth2Request<? extends Oauth2SimpleAuthConfig> buildRequest(OAu
2728
return switch (context.getAuthConfig().getAuthType()) {
2829
case GITHUB -> new GithubRequest((Oauth2SimpleAuthConfig) context.getAuthConfig());
2930
case GOOGLE -> new GoogleRequest((Oauth2SimpleAuthConfig) context.getAuthConfig());
31+
case ORY -> new OryRequest((Oauth2OryAuthConfig) context.getAuthConfig());
3032
default -> throw new UnsupportedOperationException(context.getAuthConfig().getAuthType());
3133
};
3234
}
@@ -35,6 +37,7 @@ private AbstractOauth2Request<? extends Oauth2SimpleAuthConfig> buildRequest(OAu
3537
public Set<String> supportedAuthTypes() {
3638
return Set.of(
3739
GITHUB,
38-
GOOGLE);
40+
GOOGLE,
41+
ORY);
3942
}
4043
}

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

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

3+
import org.lowcoder.sdk.auth.constants.Oauth2Constants;
4+
35
public enum Oauth2DefaultSource implements Oauth2Source {
46

57
GITHUB {
@@ -35,5 +37,23 @@ public String refresh() {
3537
return "https://www.googleapis.com/oauth2/v4/token";
3638
}
3739

40+
},
41+
42+
ORY {
43+
@Override
44+
public String accessToken() {
45+
return "https://" + Oauth2Constants.INSTANCE_ID_PLACEHOLDER + "/oauth2/token";
46+
}
47+
48+
@Override
49+
public String userInfo() {
50+
return "https://" + Oauth2Constants.INSTANCE_ID_PLACEHOLDER + "/userinfo";
51+
}
52+
53+
@Override
54+
public String refresh() {
55+
return "https://" + Oauth2Constants.INSTANCE_ID_PLACEHOLDER + "/oauth2/token";
56+
}
57+
3858
}
3959
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package org.lowcoder.api.authentication.request.oauth2.request;
2+
3+
import org.apache.commons.collections4.MapUtils;
4+
import org.apache.http.client.utils.URIBuilder;
5+
import org.lowcoder.api.authentication.request.AuthException;
6+
import org.lowcoder.api.authentication.request.oauth2.OAuth2RequestContext;
7+
import org.lowcoder.api.authentication.request.oauth2.Oauth2DefaultSource;
8+
import org.lowcoder.domain.user.model.AuthToken;
9+
import org.lowcoder.domain.user.model.AuthUser;
10+
import org.lowcoder.sdk.auth.Oauth2OryAuthConfig;
11+
import org.lowcoder.sdk.util.JsonUtils;
12+
import org.lowcoder.sdk.webclient.WebClientBuildHelper;
13+
import org.springframework.core.ParameterizedTypeReference;
14+
import org.springframework.http.MediaType;
15+
import reactor.core.publisher.Mono;
16+
17+
import java.net.URI;
18+
import java.net.URISyntaxException;
19+
import java.util.Map;
20+
21+
import static org.springframework.web.reactive.function.BodyInserters.fromFormData;
22+
23+
public class OryRequest extends AbstractOauth2Request<Oauth2OryAuthConfig> {
24+
25+
public OryRequest(Oauth2OryAuthConfig config) {
26+
super(config, Oauth2DefaultSource.ORY);
27+
}
28+
29+
@Override
30+
protected Mono<AuthToken> getAuthToken(OAuth2RequestContext context) {
31+
URI uri;
32+
try {
33+
uri = new URIBuilder(config.replaceAuthUrlClientIdPlaceholder(source.accessToken())).build();
34+
} catch (URISyntaxException e) {
35+
throw new RuntimeException(e);
36+
}
37+
38+
return WebClientBuildHelper.builder()
39+
.systemProxy()
40+
.build()
41+
.post()
42+
.uri(uri)
43+
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
44+
.body(fromFormData("code", context.getCode())
45+
.with("client_id", config.getClientId())
46+
.with("client_secret", config.getClientSecret())
47+
.with("grant_type", "authorization_code")
48+
.with("redirect_uri", context.getRedirectUrl()))
49+
.exchangeToMono(response -> response.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
50+
}))
51+
.flatMap(map -> {
52+
if (map.containsKey("error") || map.containsKey("error_description")) {
53+
throw new AuthException(JsonUtils.toJson(map));
54+
}
55+
AuthToken authToken = AuthToken.builder()
56+
.accessToken(MapUtils.getString(map, "access_token"))
57+
.expireIn(MapUtils.getIntValue(map, "expires_in"))
58+
.refreshToken(MapUtils.getString(map, "refresh_token"))
59+
.build();
60+
return Mono.just(authToken);
61+
});
62+
}
63+
64+
@Override
65+
protected Mono<AuthToken> refreshAuthToken(String refreshToken) {
66+
67+
URI uri;
68+
try {
69+
uri = new URIBuilder(config.replaceAuthUrlClientIdPlaceholder(source.refresh())).build();
70+
} catch (URISyntaxException e) {
71+
throw new RuntimeException(e);
72+
}
73+
74+
return WebClientBuildHelper.builder()
75+
.systemProxy()
76+
.build()
77+
.post()
78+
.uri(uri)
79+
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
80+
.body(fromFormData("refresh_token", refreshToken)
81+
.with("client_id", config.getClientId())
82+
.with("client_secret", config.getClientSecret())
83+
.with("grant_type", "refresh_token"))
84+
.exchangeToMono(response -> response.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
85+
}))
86+
.flatMap(map -> {
87+
if (map.containsKey("error") || map.containsKey("error_description")) {
88+
throw new AuthException(JsonUtils.toJson(map));
89+
}
90+
AuthToken authToken = AuthToken.builder()
91+
.accessToken(MapUtils.getString(map, "access_token"))
92+
.expireIn(MapUtils.getIntValue(map, "expires_in"))
93+
.refreshToken(MapUtils.getString(map, "refresh_token"))
94+
.build();
95+
return Mono.just(authToken);
96+
});
97+
98+
}
99+
100+
@Override
101+
protected Mono<AuthUser> getAuthUser(AuthToken authToken) {
102+
return WebClientBuildHelper.builder()
103+
.systemProxy()
104+
.build()
105+
.post()
106+
.uri(config.replaceAuthUrlClientIdPlaceholder(source.userInfo()))
107+
.header("Authorization", "Bearer " + authToken.getAccessToken())
108+
.exchangeToMono(response -> response.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
109+
}))
110+
.flatMap(map -> {
111+
if (map.containsKey("error") || map.containsKey("error_description")) {
112+
throw new AuthException(JsonUtils.toJson(map));
113+
}
114+
AuthUser authUser = AuthUser.builder()
115+
.uid(MapUtils.getString(map, "sub"))
116+
.username(MapUtils.getString(map, "name"))
117+
.avatar(MapUtils.getString(map, "picture"))
118+
.rawUserInfo(map)
119+
.build();
120+
return Mono.just(authUser);
121+
});
122+
}
123+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /