Skip to content

Commit

Permalink
SHIBUI-2380
Browse files Browse the repository at this point in the history
Incremental commit:
- unit tests and code corrections
  • Loading branch information
chasegawa committed Sep 23, 2022
1 parent fa27801 commit b36a3a2
Show file tree
Hide file tree
Showing 18 changed files with 703 additions and 96 deletions.
3 changes: 2 additions & 1 deletion backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ dependencies {
testCompile "org.springframework.boot:spring-boot-starter-test:${project.'springbootVersion'}"
testCompile "org.springframework.security:spring-security-test:${project.'springSecurityVersion'}"
testCompile 'org.skyscreamer:jsonassert:1.5.0'
testCompile "org.xmlunit:xmlunit-core:2.5.1"
testImplementation "org.xmlunit:xmlunit-core:2.9.0"
testImplementation "org.xmlunit:xmlunit-assertj:2.9.0"
testRuntime 'cglib:cglib-nodep:3.2.5'

compile "net.shibboleth.ext:spring-extensions:6.2.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,4 @@ public class Audience extends AbstractXMLObject implements org.opensaml.saml.sam
@Getter
@Setter
private String URI;

public Audience(String value) {
this.setURI(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ public boolean isSupportedProtocol(String s) {

@Override
public void addSupportedProtocol(String supportedProtocol) {
supportedProtocols.add(supportedProtocol);
if (!supportedProtocols.contains(supportedProtocol)) {
supportedProtocols.add(supportedProtocol);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,4 @@
@NoArgsConstructor
@Audited
public class DefaultAcrValue extends AbstractValueXMLObject implements net.shibboleth.oidc.saml.xmlobject.DefaultAcrValue {
public DefaultAcrValue(String value) {
this.setValue(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,4 @@
@NoArgsConstructor
@Audited
public class PostLogoutRedirectUri extends AbstractValueXMLObject implements net.shibboleth.oidc.saml.xmlobject.PostLogoutRedirectUri {
public PostLogoutRedirectUri(String value) {
this.setValue(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,4 @@
@NoArgsConstructor
@Audited
public class RequestUri extends AbstractValueXMLObject implements net.shibboleth.oidc.saml.xmlobject.RequestUri {
public RequestUri(String value) {
this.setValue(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ public EntityDescriptorRepresentation createNew(EntityDescriptor ed) throws Forb
public EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(EntityDescriptor ed) {
ed.setIdOfOwner(userService.getCurrentUserGroup().getOwnerId());
ed.setProtocol(determineEntityDescriptorProtocol(ed));
if (ed.getProtocol() == EntityDescriptorProtocol.OIDC) {
ed.getSPSSODescriptor("").addSupportedProtocol("http://openid.net/specs/openid-connect-core-1_0.html");
}
EntityDescriptor savedEntity = entityDescriptorRepository.save(ed);
return createRepresentationFromDescriptor(savedEntity);
}
Expand All @@ -204,8 +207,7 @@ public EntityDescriptorRepresentation updateGroupForEntityDescriptor(String reso
}

@Override
public EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRep)
throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException {
public EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRep) throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException {
if (edRep.isServiceEnabled() && !userService.currentUserIsAdmin()) {
throw new ForbiddenException("You do not have the permissions necessary to enable this service.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.common.base.Strings;
import edu.internet2.tier.shibboleth.admin.ui.domain.AssertionConsumerService;
import edu.internet2.tier.shibboleth.admin.ui.domain.Audience;
import edu.internet2.tier.shibboleth.admin.ui.domain.AudienceBuilder;
import edu.internet2.tier.shibboleth.admin.ui.domain.ContactPerson;
import edu.internet2.tier.shibboleth.admin.ui.domain.ContactPersonBuilder;
import edu.internet2.tier.shibboleth.admin.ui.domain.Description;
Expand All @@ -14,9 +15,11 @@
import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor;
import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptorProtocol;
import edu.internet2.tier.shibboleth.admin.ui.domain.Extensions;
import edu.internet2.tier.shibboleth.admin.ui.domain.ExtensionsBuilder;
import edu.internet2.tier.shibboleth.admin.ui.domain.GivenName;
import edu.internet2.tier.shibboleth.admin.ui.domain.InformationURL;
import edu.internet2.tier.shibboleth.admin.ui.domain.KeyDescriptor;
import edu.internet2.tier.shibboleth.admin.ui.domain.KeyName;
import edu.internet2.tier.shibboleth.admin.ui.domain.Logo;
import edu.internet2.tier.shibboleth.admin.ui.domain.NameIDFormat;
import edu.internet2.tier.shibboleth.admin.ui.domain.Organization;
Expand All @@ -37,11 +40,17 @@
import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.SecurityInfoRepresentation;
import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ServiceProviderSsoDescriptorRepresentation;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.AbstractValueXMLObject;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.ClientSecret;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.ClientSecretKeyReference;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.DefaultAcrValue;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.DefaultAcrValueBuilder;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.JwksData;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.JwksUri;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.OAuthRPExtensions;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.PostLogoutRedirectUri;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.PostLogoutRedirectUriBuilder;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.RequestUri;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.RequestUriBuilder;
import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.ValueXMLObject;
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects;
import edu.internet2.tier.shibboleth.admin.ui.service.EntityService;
Expand Down Expand Up @@ -75,16 +84,18 @@ public class EntityDescriptorConversionUtils {

public static KeyDescriptor createKeyDescriptor(String name, String usageType, String value, KeyDescriptorRepresentation.ElementType elementType) {
KeyDescriptor keyDescriptor = openSamlObjects.buildDefaultInstanceOfType(KeyDescriptor.class);

KeyInfo keyInfo = openSamlObjects.buildDefaultInstanceOfType(KeyInfo.class);
if (!Strings.isNullOrEmpty(name)) {
keyDescriptor.setName(name);
KeyName keyName = openSamlObjects.buildDefaultInstanceOfType(KeyName.class);
keyName.setValue(name);
keyInfo.getXMLObjects().add(keyName);
}

if (!"both".equals(usageType)) {
keyDescriptor.setUsageType(usageType);
}

KeyInfo keyInfo = openSamlObjects.buildDefaultInstanceOfType(KeyInfo.class);
AbstractValueXMLObject xmlObject;
switch (elementType) {
case X509Data:
Expand All @@ -100,17 +111,17 @@ public static KeyDescriptor createKeyDescriptor(String name, String usageType, S
keyInfo.getXMLObjects().add(xmlObject);
break;
case jwksUri:
xmlObject = openSamlObjects.buildDefaultInstanceOfType(JwksData.class);
xmlObject = openSamlObjects.buildDefaultInstanceOfType(JwksUri.class);
xmlObject.setValue(value);
keyInfo.getXMLObjects().add(xmlObject);
break;
case clientSecret:
xmlObject = openSamlObjects.buildDefaultInstanceOfType(JwksData.class);
xmlObject = openSamlObjects.buildDefaultInstanceOfType(ClientSecret.class);
xmlObject.setValue(value);
keyInfo.getXMLObjects().add(xmlObject);
break;
case clientSecretKeyReference:
xmlObject = openSamlObjects.buildDefaultInstanceOfType(JwksData.class);
xmlObject = openSamlObjects.buildDefaultInstanceOfType(ClientSecretKeyReference.class);
xmlObject.setValue(value);
keyInfo.getXMLObjects().add(xmlObject);
break;
Expand Down Expand Up @@ -349,55 +360,55 @@ public static void setupSPSSODescriptor(EntityDescriptor ed, EntityDescriptorRep
}

private static Extensions buildOAuthRPExtensionsFromRepresentation(@NonNull ServiceProviderSsoDescriptorRepresentation representation) {
Extensions result = new Extensions();
Extensions result = new ExtensionsBuilder().buildObject();
HashMap<String, Object> oauthrpextMap = (HashMap<String, Object>) representation.getExtensions().get("OAuthRPExtensions");
OAuthRPExtensions oAuthRPExtensions = new OAuthRPExtensions();
oauthrpextMap.keySet().forEach(key -> {
try {
if ("requestUris".equals(key) || "defaultAcrValues".equals(key) || "postLogoutRedirectUris".equals(key) || "audience".equals(key)){
Field field = oAuthRPExtensions.getClass().getDeclaredField(key);
field.setAccessible(true);
((List<String>) oauthrpextMap.get(key)).forEach(value -> {
switch (key) {
case "requestUris":
oAuthRPExtensions.addRequestUri(new RequestUri((value)));
break;
case "defaultAcrValues":
oAuthRPExtensions.addDefaultAcrValue(new DefaultAcrValue((value)));
break;
case "postLogoutRedirectUris":
oAuthRPExtensions.addPostLogoutRedirectUri(new PostLogoutRedirectUri((value)));
break;
case "audience":
oAuthRPExtensions.addAudience(new Audience(value));
break;
}
});
}
else if ("attributes".equals(key)) {
HashMap<String, Object> attributes = (HashMap<String, Object>) oauthrpextMap.get(key);
attributes.keySet().forEach(attKey -> {
try {
Field attField = oAuthRPExtensions.getClass().getDeclaredField(attKey);
attField.setAccessible(true);
if ("requireAuthTime".equals(attKey)) {
Boolean value = Boolean.valueOf(attributes.get(attKey).toString());
attField.set(oAuthRPExtensions, value);
} else if ("defaultMaxAge".equals(attKey)) {
Integer value = Integer.valueOf(attributes.get(attKey).toString());
attField.setInt(oAuthRPExtensions, value);
} else {
attField.set(oAuthRPExtensions, attributes.get(attKey).toString());
}
}
catch (IllegalAccessException | NoSuchFieldException e) {
// skip it
if ("requestUris".equals(key) || "defaultAcrValues".equals(key) || "postLogoutRedirectUris".equals(key) || "audiences".equals(key)) {
((List<String>) oauthrpextMap.get(key)).forEach(value -> {
switch (key) {
case "requestUris":
RequestUri ru = new RequestUriBuilder().buildObject();
ru.setValue(value);
oAuthRPExtensions.addRequestUri(ru);
break;
case "defaultAcrValues":
DefaultAcrValue dav = new DefaultAcrValueBuilder().buildObject();
dav.setValue(value);
oAuthRPExtensions.addDefaultAcrValue(dav);
break;
case "postLogoutRedirectUris":
PostLogoutRedirectUri plru = new PostLogoutRedirectUriBuilder().buildObject();
plru.setValue(value);
oAuthRPExtensions.addPostLogoutRedirectUri(plru);
break;
case "audiences":
Audience audience = new AudienceBuilder().buildObject();
audience.setURI(value);
oAuthRPExtensions.addAudience(audience);
break;
}
});
} else if ("attributes".equals(key)) {
HashMap<String, Object> attributes = (HashMap<String, Object>) oauthrpextMap.get(key);
attributes.keySet().forEach(attKey -> {
try {
Field attField = oAuthRPExtensions.getClass().getDeclaredField(attKey);
attField.setAccessible(true);
if ("requireAuthTime".equals(attKey)) {
Boolean value = Boolean.valueOf(attributes.get(attKey).toString());
attField.set(oAuthRPExtensions, value);
} else if ("defaultMaxAge".equals(attKey)) {
Integer value = Integer.valueOf(attributes.get(attKey).toString());
attField.setInt(oAuthRPExtensions, value);
} else {
attField.set(oAuthRPExtensions, attributes.get(attKey).toString());
}
});
}
}
catch (NoSuchFieldException e) {
// skip it
}
catch (IllegalAccessException | NoSuchFieldException e) {
// skip it
}
});
}
});
result.addUnknownXMLObject(oAuthRPExtensions);
Expand Down
Loading

0 comments on commit b36a3a2

Please sign in to comment.