Skip to content

Commit e378da7

Browse files
duonglq-tsdvheliocastro
authored andcommitted
fix(Admin): fix OAuth Client deserialization and database operations
1 parent 4ee5a62 commit e378da7

File tree

6 files changed

+144
-29
lines changed

6 files changed

+144
-29
lines changed

libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/cloudantclient/DatabaseConnectorCloudant.java

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
*/
1010
package org.eclipse.sw360.datahandler.cloudantclient;
1111

12+
import com.fasterxml.jackson.core.JsonProcessingException;
13+
import com.fasterxml.jackson.core.type.TypeReference;
14+
import com.fasterxml.jackson.databind.ObjectMapper;
15+
import com.fasterxml.jackson.databind.SerializationFeature;
16+
import com.fasterxml.jackson.databind.DeserializationFeature;
1217
import com.google.common.collect.ImmutableList;
1318
import com.google.common.collect.Lists;
1419
import com.google.common.collect.Sets;
@@ -30,6 +35,8 @@
3035
import java.io.ByteArrayInputStream;
3136
import java.io.InputStream;
3237
import java.lang.reflect.Field;
38+
import java.lang.reflect.InvocationTargetException;
39+
import java.lang.reflect.Method;
3340
import java.lang.reflect.Type;
3441
import java.nio.charset.StandardCharsets;
3542
import java.util.ArrayList;
@@ -665,17 +672,25 @@ public Document getDocumentFromPojo(Object document) {
665672
return (Document) document;
666673
}
667674
Document doc = new Document();
668-
Gson gson = this.instance.getGson();
669-
Type t = new TypeToken<Map<String, Object>>() {}.getType();
670-
Map<String, Object> map = gson.fromJson(gson.toJson(document), t);
675+
Map<String, Object> map;
676+
677+
if (isInstanceOfOAuthClientEntity(document)) {
678+
ObjectMapper objectMapper = new ObjectMapper();
679+
map = objectMapper.convertValue(document, new TypeReference<Map<String, Object>>() {});
680+
} else {
681+
Gson gson = this.instance.getGson();
682+
Type type = new TypeToken<Map<String, Object>>() {}.getType();
683+
map = gson.fromJson(gson.toJson(document), type);
684+
}
685+
671686
if (map.containsKey("id")) {
672687
if (!((String) map.get("id")).isEmpty()) {
673688
doc.setId((String) map.get("id"));
674689
}
675690
map.remove("id");
676691
}
677692
if (map.containsKey("_id")) {
678-
if (!((String) map.get("_id")).isEmpty()) {
693+
if (map.get("_id") != null && !((String) map.get("_id")).isEmpty()) {
679694
doc.setId((String) map.get("_id"));
680695
}
681696
map.remove("_id");
@@ -693,7 +708,7 @@ public Document getDocumentFromPojo(Object document) {
693708
map.remove("revision");
694709
}
695710
if (map.containsKey("_rev")) {
696-
if (!((String) map.get("_rev")).isEmpty()) {
711+
if (map.get("_rev") != null && !((String) map.get("_rev")).isEmpty()) {
697712
doc.setRev((String) map.get("_rev"));
698713
}
699714
map.remove("_rev");
@@ -703,8 +718,18 @@ public Document getDocumentFromPojo(Object document) {
703718
}
704719

705720
public <T> T getPojoFromDocument(@NotNull Document document, Class<T> type) {
706-
T doc = this.instance.getGson().fromJson(document.toString(), type);
707-
updateIdAndRev(doc, document.getId(), document.getRev());
721+
T doc = null;
722+
try {
723+
if (type.getSimpleName().equals("OAuthClientEntity")) {
724+
ObjectMapper objectMapper = new ObjectMapper();
725+
doc = objectMapper.readValue(document.toString(), type);
726+
} else {
727+
doc = this.instance.getGson().fromJson(document.toString(), type);
728+
}
729+
updateIdAndRev(doc, document.getId(), document.getRev());
730+
} catch (JsonProcessingException e) {
731+
log.error(e.getMessage());
732+
}
708733
return doc;
709734
}
710735

@@ -715,9 +740,24 @@ private <T> void updateIdAndRev(@NotNull T doc, String docId, String docRev) {
715740
TFieldIdEnum rev = tbase.fieldForId(2);
716741
tbase.setFieldValue(id, docId);
717742
tbase.setFieldValue(rev, docRev);
743+
} else if (isInstanceOfOAuthClientEntity(doc)) {
744+
Class<?> clazz = doc.getClass();
745+
try {
746+
Method setIdMethod = clazz.getMethod("setId", String.class);
747+
setIdMethod.invoke(doc, docId);
748+
749+
Method setRevMethod = clazz.getMethod("setRev", String.class);
750+
setRevMethod.invoke(doc, docRev);
751+
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
752+
log.error(e.getMessage());
753+
}
718754
}
719755
}
720756

757+
private <T> boolean isInstanceOfOAuthClientEntity(T doc) {
758+
return doc.getClass().getSimpleName().equals("OAuthClientEntity");
759+
}
760+
721761
public boolean contains(@NotNull String docId) {
722762
if (docId.isEmpty()) {
723763
return false;

libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/cloudantclient/DatabaseRepositoryCloudantClient.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
*/
1010
package org.eclipse.sw360.datahandler.cloudantclient;
1111

12+
import java.lang.reflect.InvocationTargetException;
13+
import java.lang.reflect.Method;
1214
import java.lang.reflect.Type;
1315
import java.util.Arrays;
1416
import java.util.Collection;
@@ -370,6 +372,15 @@ public boolean remove(T doc) {
370372
TFieldIdEnum id = tbase.fieldForId(1);
371373
String docId = (String) tbase.getFieldValue(id);
372374
return connector.deleteById(docId);
375+
} else if (doc.getClass().getSimpleName().equals("OAuthClientEntity")) {
376+
Class<?> clazz = doc.getClass();
377+
try {
378+
Method getIdMethod = clazz.getMethod("getId");
379+
String id = (String) getIdMethod.invoke(doc);
380+
return connector.deleteById(id);
381+
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
382+
log.error(e.getMessage());
383+
}
373384
}
374385
return connector.remove(doc);
375386
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (C) TOSHIBA CORPORATION, 2025. Part of the SW360 Frontend Project.
2+
// Copyright (C) Toshiba Software Development (Vietnam) Co., Ltd., 2025. Part of the SW360 Frontend Project.
3+
4+
// This program and the accompanying materials are made
5+
// available under the terms of the Eclipse Public License 2.0
6+
// which is available at https://www.eclipse.org/legal/epl-2.0/
7+
8+
// SPDX-License-Identifier: EPL-2.0
9+
// License-Filename: LICENSE
10+
package org.eclipse.sw360.rest.authserver.client.persistence;
11+
import com.fasterxml.jackson.core.JsonParser;
12+
import com.fasterxml.jackson.core.JsonProcessingException;
13+
import com.fasterxml.jackson.databind.DeserializationContext;
14+
import com.fasterxml.jackson.databind.JsonDeserializer;
15+
import com.fasterxml.jackson.databind.JsonNode;
16+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
17+
import org.springframework.security.core.GrantedAuthority;
18+
import org.springframework.security.core.authority.SimpleGrantedAuthority;
19+
20+
import java.io.IOException;
21+
import java.util.HashSet;
22+
import java.util.Set;
23+
import java.util.stream.Collectors;
24+
25+
public class OAuthClientDeserializer extends JsonDeserializer<OAuthClientEntity> {
26+
27+
@Override
28+
public OAuthClientEntity deserialize(JsonParser p, DeserializationContext ctxt)
29+
throws IOException, JsonProcessingException {
30+
31+
JsonNode node = p.getCodec().readTree(p);
32+
OAuthClientEntity client = new OAuthClientEntity();
33+
34+
client.setId(node.get("_id").asText());
35+
client.setRev(node.get("_rev").asText());
36+
client.setClientId(node.get("client_id").asText());
37+
client.setClientSecret(node.get("client_secret").asText());
38+
client.setDescription(node.get("description").asText());
39+
40+
client.setSecretRequired(node.get("secretRequired").asBoolean());
41+
client.setScoped(node.get("scoped").asBoolean());
42+
43+
client.setResourceIds(jsonNodeToSet(node.get("resource_ids")));
44+
client.setAuthorizedGrantTypes(jsonNodeToSet(node.get("authorized_grant_types")));
45+
client.setScope(jsonNodeToSet(node.get("scope")));
46+
client.setRegisteredRedirectUri(jsonNodeToSet(node.get("redirect_uri")));
47+
client.setAutoApproveScopes(jsonNodeToSet(node.get("autoapprove")));
48+
49+
if (node.has("access_token_validity")) {
50+
client.setAccessTokenValiditySeconds(node.get("access_token_validity").asInt());
51+
}
52+
if (node.has("refresh_token_validity")) {
53+
client.setRefreshTokenValiditySeconds(node.get("refresh_token_validity").asInt());
54+
}
55+
56+
Set<String> authorities = jsonNodeToSet(node.get("authorities"));
57+
client.setAuthorities(authorities);
58+
59+
return client;
60+
}
61+
62+
private Set<String> jsonNodeToSet(JsonNode node) {
63+
if (node == null || !node.isArray()) {
64+
return new HashSet<>();
65+
}
66+
Set<String> result = new HashSet<>();
67+
for (JsonNode element : node) {
68+
if (element.isTextual()) {
69+
result.add(element.asText());
70+
} else if (element.isObject() && element.has("role")) {
71+
result.add(element.get("role").asText());
72+
}
73+
}
74+
return result;
75+
}
76+
}

rest/authorization-server/src/main/java/org/eclipse/sw360/rest/authserver/client/persistence/OAuthClientEntity.java

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@
1111

1212
import java.io.Serial;
1313
import java.io.Serializable;
14-
import java.util.Collection;
1514
import java.util.Set;
1615

17-
import org.springframework.security.core.GrantedAuthority;
18-
import org.springframework.security.core.authority.AuthorityUtils;
19-
2016
import com.fasterxml.jackson.annotation.JsonProperty;
2117
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2218

19+
@JsonDeserialize(using = OAuthClientDeserializer.class)
2320
public class OAuthClientEntity implements Serializable {
2421

2522
@Serial
@@ -31,7 +28,7 @@ public class OAuthClientEntity implements Serializable {
3128
private String description;
3229
private Set<String> resourceIds;
3330
private Set<String> authorizedGrantTypes;
34-
private Collection<GrantedAuthority> authorities;
31+
private Set<String> authorities;
3532
private Set<String> scope;
3633
private boolean secretRequired;
3734
private boolean scoped;
@@ -51,12 +48,12 @@ public String getId() {
5148
}
5249

5350
@JsonProperty("_rev")
54-
public void setRevision(String revision) {
51+
public void setRev(String revision) {
5552
this.revision = revision;
5653
}
5754

5855
@JsonProperty("_rev")
59-
public String getRevision() {
56+
public String getRev() {
6057
return revision;
6158
}
6259

@@ -122,23 +119,14 @@ public void setAuthorizedGrantTypes(Set<String> authorizedGrantTypes) {
122119
this.authorizedGrantTypes=authorizedGrantTypes;
123120
}
124121

125-
public Collection<GrantedAuthority> getAuthorities() {
126-
return authorities;
127-
}
128-
129-
public void setAuthorities(Collection<GrantedAuthority> authorities) {
130-
this.authorities=authorities;
131-
}
132-
133122
@JsonProperty("authorities")
134-
public Set<String> getAuthoritiesAsStrings() {
135-
return AuthorityUtils.authorityListToSet(this.authorities);
123+
public Set<String> getAuthorities() {
124+
return authorities;
136125
}
137126

138127
@JsonProperty("authorities")
139-
@JsonDeserialize()
140-
public void setAuthoritiesAsStrings(Set<String> values) {
141-
this.setAuthorities(AuthorityUtils.createAuthorityList(values.toArray(new String[values.size()])));
128+
public void setAuthorities(Set<String> values) {
129+
this.authorities = values;
142130
}
143131

144132
@JsonProperty("scope")

rest/authorization-server/src/main/java/org/eclipse/sw360/rest/authserver/client/rest/OAuthClientController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public ResponseEntity<?> deleteClient(@PathVariable("clientId") String clientId)
127127
private void updateClientEntityFromResource(OAuthClientEntity clientEntity, OAuthClientResource clientResource) {
128128
// updateable properties (clientId and clientSecret cannot be changed)
129129
clientEntity.setDescription(clientResource.getDescription());
130-
clientEntity.setAuthoritiesAsStrings(clientResource.getAuthorities());
130+
clientEntity.setAuthorities(clientResource.getAuthorities());
131131
clientEntity.setScope(clientResource.getScope());
132132
clientEntity.setAccessTokenValiditySeconds(clientResource.getAccessTokenValidity());
133133
clientEntity.setRefreshTokenValiditySeconds(clientResource.getRefreshTokenValidity());

rest/authorization-server/src/main/java/org/eclipse/sw360/rest/authserver/client/rest/OAuthClientResource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public OAuthClientResource(OAuthClientEntity clientEntity) {
5050
this.description = clientEntity.getDescription();
5151
this.clientId = clientEntity.getClientId();
5252
this.clientSecret = clientEntity.getClientSecret();
53-
this.authorities = clientEntity.getAuthoritiesAsStrings();
53+
this.authorities = clientEntity.getAuthorities();
5454
this.scope = clientEntity.getScope();
5555
this.accessTokenValidity = clientEntity.getAccessTokenValiditySeconds();
5656
this.refreshTokenValidity = clientEntity.getRefreshTokenValiditySeconds();

0 commit comments

Comments
 (0)