Skip to content

Commit 1575b04

Browse files
committed
Fixes #495
1 parent 0461133 commit 1575b04

File tree

6 files changed

+51
-6
lines changed

6 files changed

+51
-6
lines changed

manage-server/src/main/java/manage/hook/OidcValidationHook.java

+13
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import manage.model.MetaData;
77
import org.everit.json.schema.Schema;
88
import org.everit.json.schema.ValidationException;
9+
import org.springframework.util.StringUtils;
910

1011
import java.util.ArrayList;
1112
import java.util.Arrays;
@@ -44,6 +45,8 @@ private void validate(MetaData newMetaData) {
4445
Map<String, Object> metaDataFields = newMetaData.metaDataFields();
4546
List<String> redirectUrls = (List<String>) metaDataFields.getOrDefault("redirectUrls", new ArrayList<String>());
4647
List<String> grants = (List<String>) metaDataFields.getOrDefault("grants", new ArrayList<String>());
48+
boolean isPublicClient = (boolean) metaDataFields.getOrDefault("isPublicClient", false);
49+
String secret = (String) metaDataFields.get("secret");
4750
Schema schema = metaDataAutoConfiguration.schema(EntityType.RP.getType());
4851
if (grants.stream().anyMatch(grant -> Arrays.asList("authorization_code", "implicit").contains(grant)) &&
4952
redirectUrls.isEmpty()) {
@@ -58,6 +61,16 @@ private void validate(MetaData newMetaData) {
5861
if (metaDataFields.get("refreshTokenValidity") != null && grants.stream().noneMatch(grant -> grant.equals("refresh_token"))) {
5962
throw new ValidationException(schema, "refreshTokenValidity specified, but no refresh_token grant. Either remove refreshTokenValidity or add refresh_token grant type", "refreshTokenValidity");
6063
}
64+
if (isPublicClient && StringUtils.hasText(secret)) {
65+
throw new ValidationException(schema, "Public clients are not allowed a secret", "isPublicClient");
66+
}
67+
if (!isPublicClient && !StringUtils.hasText(secret)) {
68+
throw new ValidationException(schema, "Non-public clients are required a secret", "secret");
69+
}
70+
if (grants.size() == 1 && grants.get(0).equals("urn:ietf:params:oauth:grant-type:device_code") && StringUtils.hasText(secret)) {
71+
throw new ValidationException(schema, "Device Code RP is not allowed a secret", "redirectUris");
72+
}
73+
6174
}
6275

6376
}

manage-server/src/main/java/manage/service/ImporterService.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
import javax.xml.stream.XMLStreamException;
2121
import java.io.IOException;
22+
import java.net.URI;
23+
import java.net.URISyntaxException;
2224
import java.net.URL;
2325
import java.nio.charset.Charset;
2426
import java.util.*;
@@ -102,12 +104,12 @@ public Map<String, Object> importJson(String type, Map<String, Object> json) thr
102104

103105
public Map<String, Object> importJsonUrl(String type, Import importRequest) {
104106
try {
105-
Resource resource = new SaveURLResource(new URL(importRequest.getUrl()),
107+
Resource resource = new SaveURLResource(new URI(importRequest.getUrl()).toURL(),
106108
environment.acceptsProfiles(Profiles.of("dev")), autoRefreshUserAgent);
107109
String json = IOUtils.toString(resource.getInputStream(), Charset.defaultCharset());
108110
Map<String, Object> map = objectMapper.readValue(json, Map.class);
109111
return importJson(type, map);
110-
} catch (IOException e) {
112+
} catch (IOException | URISyntaxException e) {
111113
return singletonMap("errors", singletonList(e.getClass().getName()));
112114
}
113115
}

manage-server/src/main/java/manage/service/MetaDataService.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import javax.xml.stream.XMLStreamException;
3636
import java.io.IOException;
3737
import java.io.UnsupportedEncodingException;
38+
import java.net.URI;
39+
import java.net.URISyntaxException;
3840
import java.net.URL;
3941
import java.net.URLDecoder;
4042
import java.time.Instant;
@@ -109,7 +111,7 @@ public Map<String, List> importFeed(Import importRequest) {
109111
.map(ServiceProvider::new)
110112
.collect(Collectors.toMap(ServiceProvider::getEntityId, sp -> sp));
111113
String feedUrl = importRequest.getUrl();
112-
Resource resource = new SaveURLResource(new URL(feedUrl), environment.acceptsProfiles(Profiles.of("dev")), null);
114+
Resource resource = new SaveURLResource(new URI(feedUrl).toURL(), environment.acceptsProfiles(Profiles.of("dev")), null);
113115

114116
List<Map<String, Object>> allImports = importerService.importFeed(resource);
115117
List<Map<String, Object>> imports =
@@ -179,7 +181,7 @@ public Map<String, List> importFeed(Import importRequest) {
179181
results.put("total", Collections.singletonList(imports.size()));
180182

181183
return results;
182-
} catch (IOException | XMLStreamException e) {
184+
} catch (IOException | XMLStreamException | URISyntaxException e) {
183185
LOG.error("Error in client/import/feed", e);
184186
return singletonMap("errors", singletonList(e.getClass().getName()));
185187
}

manage-server/src/main/resources/metadata_configuration/oidc10_rp.schema.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@
516516
"authorization_code",
517517
"implicit",
518518
"refresh_token",
519-
"client_credentials"
519+
"client_credentials",
520+
"urn:ietf:params:oauth:grant-type:device_code"
520521
]
521522
},
522523
"info": "The authorisation grant type's of this Relying Party."
@@ -651,7 +652,7 @@
651652
},
652653
"required": [
653654
"name:en",
654-
"secret",
655+
"OrganizationName:en",
655656
"grants"
656657
],
657658
"additionalProperties": false

manage-server/src/main/resources/metadata_templates/oidc10_rp.template.json

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"metaDataFields": {
1010
"name:en": "",
1111
"secret": "",
12+
"OrganizationName:en": "",
1213
"redirectUrls": [],
1314
"grants": [
1415
"authorization_code"

manage-server/src/test/java/manage/hook/OidcValidationHookTest.java

+26
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,38 @@ public void clientCredentialsWithRedirect() {
7272
subject.prePut(null, metaData(singletonList("client_credentials"), singletonList("https://redirect")), apiUser()));
7373
}
7474

75+
@Test
76+
public void isPublicWithSecret() {
77+
assertThrows(ValidationException.class, () ->
78+
subject.prePut(null, metaData(Map.of("secret", "verySecret", "isPublicClient", true)), apiUser()));
79+
}
80+
81+
@Test
82+
public void privateWithoutSecret() {
83+
assertThrows(ValidationException.class, () ->
84+
subject.prePut(null, metaData(Map.of("secret", "", "isPublicClient", false)), apiUser()));
85+
}
86+
87+
@Test
88+
public void deviceCodeWithoutSecret() {
89+
assertThrows(ValidationException.class, () ->
90+
subject.prePut(null, metaData(Map.of("grants", List.of("urn:ietf:params:oauth:grant-type:device_code"),
91+
"secret", "verySecret")), apiUser()));
92+
}
93+
7594
@SuppressWarnings("unchecked")
7695
private MetaData metaData(List<String> grants, List<String> redirectUrls) {
7796
Map<String, Object> data = new HashMap<>();
7897
Map<String, Object> metaDataFields = (Map<String, Object>) data.computeIfAbsent("metaDataFields", key -> new HashMap<String, Object>());
7998
metaDataFields.put("redirectUrls", redirectUrls);
8099
metaDataFields.put("grants", grants);
100+
metaDataFields.put("secret", "verySecret");
101+
return new MetaData(EntityType.RP.getType(), data);
102+
}
103+
104+
private MetaData metaData(Map<String, Object> metaDataFields) {
105+
Map<String, Object> data = new HashMap<>();
106+
data.put("metaDataFields", metaDataFields);
81107
return new MetaData(EntityType.RP.getType(), data);
82108
}
83109
}

0 commit comments

Comments
 (0)