Skip to content

Commit 085a9d0

Browse files
committed
Add forwarding of oauth token to node service
1 parent 4dbd74d commit 085a9d0

File tree

4 files changed

+86
-10
lines changed

4 files changed

+86
-10
lines changed

server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import org.lowcoder.sdk.config.CommonConfig;
1111
import org.lowcoder.sdk.exception.BizException;
1212
import org.lowcoder.sdk.exception.PluginException;
13+
import org.lowcoder.sdk.models.JsDatasourceConnectionConfig;
14+
import org.lowcoder.sdk.models.Property;
1315
import org.lowcoder.sdk.models.QueryExecutionResult;
1416
import org.lowcoder.sdk.query.QueryExecutionContext;
1517
import org.lowcoder.sdk.query.QueryVisitorContext;
@@ -18,6 +20,7 @@
1820
import reactor.core.publisher.Mono;
1921

2022
import java.time.Duration;
23+
import java.util.HashMap;
2124
import java.util.List;
2225
import java.util.Map;
2326
import java.util.concurrent.TimeoutException;
@@ -94,6 +97,28 @@ private Mono<QueryExecutionResult> executeByNodeJs(Datasource datasource, Map<St
9497
.collect(Collectors.toList());
9598
context.addAll(cookies);
9699

97-
return datasourcePluginClient.executeQuery(datasource.getType(), queryConfig, context, datasource.getDetailConfig());
100+
// forward oauth2 access token in case of oauth2(inherit from login)
101+
102+
if(datasource.getDetailConfig() instanceof JsDatasourceConnectionConfig jsDatasourceConnectionConfig
103+
&& jsDatasourceConnectionConfig.isOauth2InheritFromLogin()) {
104+
return Mono.defer(() -> injectOauth2Token(queryVisitorContext, context))
105+
.then(Mono.defer(() -> datasourcePluginClient.executeQuery(datasource.getType(), queryConfig, context, datasource.getDetailConfig())));
106+
} else {
107+
return datasourcePluginClient.executeQuery(datasource.getType(), queryConfig, context, datasource.getDetailConfig());
108+
}
109+
110+
111+
}
112+
113+
private Mono<Void> injectOauth2Token(QueryVisitorContext queryVisitorContext, List<Map<String, Object>> context) {
114+
return queryVisitorContext.getAuthTokenMono()
115+
.doOnNext(properties -> {
116+
HashMap<String, Object> hashMap = new HashMap<>();
117+
for (Property property : properties) {
118+
hashMap.put(property.getKey(), property.getValue());
119+
}
120+
context.add(hashMap);
121+
})
122+
.then();
98123
}
99124
}

server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/models/JsDatasourceConnectionConfig.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.apache.commons.collections4.MapUtils;
1818
import org.apache.commons.lang3.ObjectUtils;
19+
import org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType;
1920
import org.springframework.data.annotation.Transient;
2021

2122
import lombok.Getter;
@@ -159,6 +160,20 @@ public DatasourceConnectionConfig mergeWithUpdatedConfig(DatasourceConnectionCon
159160
if (this.containsKey("extra") || jsDatasourceConnectionConfig.containsKey("extra")) {
160161
newJsDatasourceConnectionConfig.putIfAbsent("extra", ObjectUtils.firstNonNull(jsDatasourceConnectionConfig.getExtra(), this.getExtra()));
161162
}
163+
164+
// for oauth handling
165+
if(this.containsKey("authConfig")) {
166+
if(jsDatasourceConnectionConfig.containsKey("authConfig")) {
167+
newJsDatasourceConnectionConfig.put("authConfig", jsDatasourceConnectionConfig.get("authConfig"));
168+
} else {
169+
// do nothing, save empty ( this will clear db )
170+
}
171+
} else {
172+
if(jsDatasourceConnectionConfig.containsKey("authConfig")) {
173+
newJsDatasourceConnectionConfig.put("authConfig", jsDatasourceConnectionConfig.get("authConfig"));
174+
}
175+
}
176+
162177
return newJsDatasourceConnectionConfig;
163178
}
164179

@@ -199,4 +214,18 @@ private DatasourceConnectionConfig doEncryptOrDecrypt(Function<String, String> e
199214

200215
return this;
201216
}
217+
218+
public boolean isOauth2InheritFromLogin() {
219+
if (this.get("authConfig") != null) {
220+
return ((HashMap<String, String>)this.get("authConfig")).get("type").equals(RestApiAuthType.OAUTH2_INHERIT_FROM_LOGIN.name());
221+
}
222+
return false;
223+
}
224+
225+
public String getAuthId() {
226+
if(isOauth2InheritFromLogin()) {
227+
return ((HashMap<String, String>)this.get("authConfig")).get("authId");
228+
}
229+
return null;
230+
}
202231
}

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/query/ApplicationQueryApiService.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.lowcoder.infra.util.TupleUtils;
2222
import org.lowcoder.sdk.config.CommonConfig;
2323
import org.lowcoder.sdk.exception.BizError;
24+
import org.lowcoder.sdk.models.JsDatasourceConnectionConfig;
2425
import org.lowcoder.sdk.models.Property;
2526
import org.lowcoder.sdk.models.QueryExecutionResult;
2627
import org.lowcoder.sdk.plugin.graphql.GraphQLDatasourceConfig;
@@ -122,12 +123,18 @@ public Mono<QueryExecutionResult> executeApplicationQuery(ServerWebExchange exch
122123
// Check if oauth inherited from login and save token
123124
if(datasource.getDetailConfig() instanceof RestApiDatasourceConfig restApiDatasourceConfig
124125
&& restApiDatasourceConfig.isOauth2InheritFromLogin()) {
125-
paramsAndHeadersInheritFromLogin = getAuthParamsAndHeadersInheritFromLogin(tuple.getT1(), ((OAuthInheritAuthConfig)restApiDatasourceConfig.getAuthConfig()).getAuthId());
126+
paramsAndHeadersInheritFromLogin = getAuthParamsAndHeadersInheritFromLogin(tuple.getT1(), ((OAuthInheritAuthConfig)restApiDatasourceConfig.getAuthConfig()).getAuthId(), false);
126127
}
127128

128129
if(datasource.getDetailConfig() instanceof GraphQLDatasourceConfig graphQLDatasourceConfig
129130
&& graphQLDatasourceConfig.isOauth2InheritFromLogin()) {
130-
paramsAndHeadersInheritFromLogin = getAuthParamsAndHeadersInheritFromLogin(tuple.getT1(), ((OAuthInheritAuthConfig)graphQLDatasourceConfig.getAuthConfig()).getAuthId());
131+
paramsAndHeadersInheritFromLogin = getAuthParamsAndHeadersInheritFromLogin(tuple.getT1(), ((OAuthInheritAuthConfig)graphQLDatasourceConfig.getAuthConfig()).getAuthId(), false);
132+
}
133+
134+
135+
if(datasource.getDetailConfig() instanceof JsDatasourceConnectionConfig jsDatasourceConnectionConfig
136+
&& jsDatasourceConnectionConfig.isOauth2InheritFromLogin()) {
137+
paramsAndHeadersInheritFromLogin = getAuthParamsAndHeadersInheritFromLogin(tuple.getT1(), jsDatasourceConnectionConfig.getAuthId(), true);
131138
}
132139

133140
QueryVisitorContext queryVisitorContext = new QueryVisitorContext(userId, app.getOrganizationId(), port, cookies, paramsAndHeadersInheritFromLogin, commonConfig.getDisallowedHosts());
@@ -196,7 +203,7 @@ private Mono<BaseQuery> getBaseQueryFromLibraryQuery(ApplicationQuery query) {
196203
.map(LibraryQueryRecord::getQuery);
197204
}
198205

199-
protected Mono<List<Property>> getAuthParamsAndHeadersInheritFromLogin(User user, String authId) {
206+
protected Mono<List<Property>> getAuthParamsAndHeadersInheritFromLogin(User user, String authId, boolean isJsQuery) {
200207
if(authId == null) {
201208
return Mono.empty();
202209
}
@@ -207,7 +214,11 @@ protected Mono<List<Property>> getAuthParamsAndHeadersInheritFromLogin(User user
207214
if(!activeConnectionOptional.isPresent() || activeConnectionOptional.get().getAuthConnectionAuthToken() == null) {
208215
return Mono.empty();
209216
}
210-
return Mono.just(Collections.singletonList(new Property("Authorization","Bearer " + activeConnectionOptional.get().getAuthConnectionAuthToken().getAccessToken(),"header")));
217+
if(isJsQuery) {
218+
return Mono.just(Collections.singletonList(new Property("OAUTH_ACCESS_TOKEN",activeConnectionOptional.get().getAuthConnectionAuthToken().getAccessToken(),"header")));
219+
} else {
220+
return Mono.just(Collections.singletonList(new Property("Authorization","Bearer " + activeConnectionOptional.get().getAuthConnectionAuthToken().getAccessToken(),"header")));
221+
}
211222
}
212223

213224
protected void onNextOrError(QueryExecutionRequest queryExecutionRequest, QueryVisitorContext queryVisitorContext,

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/query/LibraryQueryApiService.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.lowcoder.sdk.config.CommonConfig;
4141
import org.lowcoder.sdk.exception.BizError;
4242
import org.lowcoder.sdk.exception.PluginCommonError;
43+
import org.lowcoder.sdk.models.JsDatasourceConnectionConfig;
4344
import org.lowcoder.sdk.models.Property;
4445
import org.lowcoder.sdk.models.QueryExecutionResult;
4546
import org.lowcoder.sdk.plugin.graphql.GraphQLDatasourceConfig;
@@ -263,7 +264,7 @@ public Mono<QueryExecutionResult> executeLibraryQueryFromJs(ServerWebExchange ex
263264
Datasource datasource = tuple.getT3();
264265
User user = tuple.getT4();
265266
Mono<List<Property>> paramsAndHeadersInheritFromLogin = orgMember.isInvalid()
266-
? Mono.empty() : getParamsAndHeadersInheritFromLogin(user, null);
267+
? Mono.empty() : getParamsAndHeadersInheritFromLogin(user, null, false);
267268

268269
QueryVisitorContext queryVisitorContext = new QueryVisitorContext(userId, orgId, port,
269270
exchange.getRequest().getCookies(),
@@ -313,12 +314,18 @@ public Mono<QueryExecutionResult> executeLibraryQuery(ServerWebExchange exchange
313314
// check if oauth inherited from login and save token
314315
if(datasource.getDetailConfig() instanceof RestApiDatasourceConfig restApiDatasourceConfig && restApiDatasourceConfig.isOauth2InheritFromLogin()) {
315316
paramsAndHeadersInheritFromLogin = getParamsAndHeadersInheritFromLogin
316-
(user, ((OAuthInheritAuthConfig)restApiDatasourceConfig.getAuthConfig()).getAuthId());
317+
(user, ((OAuthInheritAuthConfig)restApiDatasourceConfig.getAuthConfig()).getAuthId(), false);
317318
}
318319

319320
if(datasource.getDetailConfig() instanceof GraphQLDatasourceConfig graphQLDatasourceConfig && graphQLDatasourceConfig.isOauth2InheritFromLogin()) {
320321
paramsAndHeadersInheritFromLogin = getParamsAndHeadersInheritFromLogin
321-
(user, ((OAuthInheritAuthConfig)graphQLDatasourceConfig.getAuthConfig()).getAuthId());
322+
(user, ((OAuthInheritAuthConfig)graphQLDatasourceConfig.getAuthConfig()).getAuthId(), false);
323+
}
324+
325+
if(datasource.getDetailConfig() instanceof JsDatasourceConnectionConfig jsDatasourceConnectionConfig
326+
&& jsDatasourceConnectionConfig.isOauth2InheritFromLogin()) {
327+
paramsAndHeadersInheritFromLogin = getParamsAndHeadersInheritFromLogin
328+
(user, jsDatasourceConnectionConfig.getAuthId(), true);
322329
}
323330

324331
QueryVisitorContext queryVisitorContext = new QueryVisitorContext(userId, orgId, port, cookies, paramsAndHeadersInheritFromLogin,
@@ -348,7 +355,7 @@ private Mono<BaseQuery> getBaseQuery(LibraryQueryCombineId libraryQueryCombineId
348355
.map(LibraryQueryRecord::getQuery);
349356
}
350357

351-
protected Mono<List<Property>> getParamsAndHeadersInheritFromLogin(User user, String authId) {
358+
protected Mono<List<Property>> getParamsAndHeadersInheritFromLogin(User user, String authId, boolean isJsQuery) {
352359
if(authId == null) {
353360
return Mono.empty();
354361
}
@@ -359,7 +366,11 @@ protected Mono<List<Property>> getParamsAndHeadersInheritFromLogin(User user, St
359366
if(!activeConnectionOptional.isPresent() || activeConnectionOptional.get().getAuthConnectionAuthToken() == null) {
360367
return Mono.empty();
361368
}
362-
return Mono.just(Collections.singletonList(new Property("Authorization","Bearer " + activeConnectionOptional.get().getAuthConnectionAuthToken().getAccessToken(),"header")));
369+
if(isJsQuery) {
370+
return Mono.just(Collections.singletonList(new Property("OAUTH_ACCESS_TOKEN",activeConnectionOptional.get().getAuthConnectionAuthToken().getAccessToken(),"header")));
371+
} else {
372+
return Mono.just(Collections.singletonList(new Property("Authorization","Bearer " + activeConnectionOptional.get().getAuthConnectionAuthToken().getAccessToken(),"header")));
373+
}
363374
}
364375

365376
protected void onNextOrError(QueryExecutionRequest queryExecutionRequest, QueryVisitorContext queryVisitorContext, BaseQuery baseQuery,

0 commit comments

Comments
 (0)