validate configuration before saving it
This commit is contained in:
parent
769fdd704a
commit
88ffb9b9f4
2 changed files with 75 additions and 22 deletions
|
|
@ -1,15 +1,23 @@
|
||||||
package de.ccc.hamburg.keycloak.attribute_endpoints;
|
package de.ccc.hamburg.keycloak.attribute_endpoints;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
|
import org.keycloak.component.ComponentValidationException;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.provider.ProviderConfigProperty;
|
import org.keycloak.provider.ProviderConfigProperty;
|
||||||
import org.keycloak.provider.ProviderConfigurationBuilder;
|
import org.keycloak.provider.ProviderConfigurationBuilder;
|
||||||
|
import org.keycloak.representations.userprofile.config.UPConfig;
|
||||||
import org.keycloak.services.ui.extend.UiPageProvider;
|
import org.keycloak.services.ui.extend.UiPageProvider;
|
||||||
import org.keycloak.services.ui.extend.UiPageProviderFactory;
|
import org.keycloak.services.ui.extend.UiPageProviderFactory;
|
||||||
|
import org.keycloak.userprofile.UserProfileProvider;
|
||||||
|
|
||||||
import java.util.List;
|
import com.google.auto.service.AutoService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements UiPageProvider to show a config page in the admin
|
* Implements UiPageProvider to show a config page in the admin
|
||||||
|
|
@ -35,18 +43,70 @@ public class AdminUiPage implements UiPageProvider, UiPageProviderFactory<Compon
|
||||||
return PROVIDER_ID;
|
return PROVIDER_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHelpText() {
|
public String getHelpText() {
|
||||||
return "Configure endpoints of the Attribute Endpoint Provider.";
|
return "Configure endpoints of the Attribute Endpoint Provider.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel model) {
|
||||||
|
String errorString = "\n";
|
||||||
|
Boolean hasError = false;
|
||||||
|
|
||||||
|
Pattern slugPattern = Pattern.compile("^[a-zA-Z0-9_-]*$");
|
||||||
|
String configAttributeSlug = model.getConfig().getFirst("slug");
|
||||||
|
|
||||||
|
if (!slugPattern.matcher(configAttributeSlug).matches()) {
|
||||||
|
hasError = true;
|
||||||
|
errorString += " • [Slug] can only contain anlphanumeric characters, dash and underscore (a-z A-Z 0-9 _ - )\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
String configAuthRole = model.getConfig().getFirst("auth-role");
|
||||||
|
RoleModel authRole = realm.getRole(configAuthRole);
|
||||||
|
if (authRole == null) {
|
||||||
|
hasError = true;
|
||||||
|
errorString += " • [Auth Role] does not exist\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
String configMatchRole = model.getConfig().getFirst("match-role");
|
||||||
|
RoleModel matchRole = realm.getRole(configMatchRole);
|
||||||
|
if (matchRole == null) {
|
||||||
|
hasError = true;
|
||||||
|
errorString += " • [Match Role] does not exist\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
UserProfileProvider profileProvider = session.getProvider(UserProfileProvider.class);
|
||||||
|
UPConfig upconfig = profileProvider.getConfiguration();
|
||||||
|
String configAttributeGroup = model.getConfig().getFirst("attribute-group");
|
||||||
|
if (!upconfig.getGroups().stream().anyMatch(g -> g.getName().equals(configAttributeGroup))) {
|
||||||
|
hasError = true;
|
||||||
|
errorString += " • [Attribute Group] does not exist\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
String configAttributeRegex = model.getConfig().getFirst("attribute-regex");
|
||||||
|
Boolean regexIsBlank = configAttributeRegex == null;
|
||||||
|
|
||||||
|
if (!regexIsBlank) {
|
||||||
|
try {
|
||||||
|
Pattern.compile(configAttributeRegex);
|
||||||
|
} catch (Exception e) {
|
||||||
|
hasError = true;
|
||||||
|
errorString += " • [Attribute RegEx] is not a valid regex pattern\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasError) {
|
||||||
|
throw new ComponentValidationException(errorString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ProviderConfigProperty> getConfigProperties() {
|
public List<ProviderConfigProperty> getConfigProperties() {
|
||||||
return ProviderConfigurationBuilder.create()
|
return ProviderConfigurationBuilder.create()
|
||||||
.property()
|
.property()
|
||||||
.name("slug")
|
.name("slug")
|
||||||
.label("Slug")
|
.label("Slug")
|
||||||
.helpText("The slug in the path of the API endpoint (e.g. /realms/:realm/attribute-endpoint-provider/export/:slug)")
|
.helpText(
|
||||||
|
"The slug in the path of the API endpoint (e.g. /realms/:realm/attribute-endpoint-provider/export/:slug)")
|
||||||
.type(ProviderConfigProperty.STRING_TYPE)
|
.type(ProviderConfigProperty.STRING_TYPE)
|
||||||
.add()
|
.add()
|
||||||
|
|
||||||
|
|
@ -80,4 +140,5 @@ public class AdminUiPage implements UiPageProvider, UiPageProviderFactory<Compon
|
||||||
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package de.ccc.hamburg.keycloak.attribute_endpoints;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
@ -23,7 +22,7 @@ import org.keycloak.services.managers.AuthenticationManager.AuthResult;
|
||||||
import org.keycloak.services.resource.RealmResourceProvider;
|
import org.keycloak.services.resource.RealmResourceProvider;
|
||||||
import org.keycloak.userprofile.UserProfileProvider;
|
import org.keycloak.userprofile.UserProfileProvider;
|
||||||
|
|
||||||
import io.quarkus.security.UnauthorizedException;
|
import jakarta.ws.rs.ForbiddenException;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.NotAuthorizedException;
|
import jakarta.ws.rs.NotAuthorizedException;
|
||||||
import jakarta.ws.rs.NotFoundException;
|
import jakarta.ws.rs.NotFoundException;
|
||||||
|
|
@ -102,16 +101,9 @@ public class AttributeEndpointsResourceProvider implements RealmResourceProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
UserModel authUser = auth.getUser();
|
||||||
|
if (!authUser.hasRole(authRole)) {
|
||||||
{
|
throw new ForbiddenException("User does not have required auth role.");
|
||||||
UserModel user = auth.getUser();
|
|
||||||
if (!user.hasRole(authRole)) {
|
|
||||||
throw new UnauthorizedException("User does not have required auth role.");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println(e);
|
|
||||||
return Response.status(403, e.getMessage()).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (componentList.size() > 1) {
|
if (componentList.size() > 1) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue