Compare commits
7 commits
05785661d7
...
324fe35f5a
| Author | SHA1 | Date | |
|---|---|---|---|
|
324fe35f5a |
|||
|
bd9e5a6f3e |
|||
|
964a593dbd |
|||
|
85bd0c6572 |
|||
|
5e791af057 |
|||
|
393284ebdc |
|||
|
ffa6c92c65 |
5 changed files with 29 additions and 5212 deletions
10
README.md
10
README.md
|
|
@ -5,10 +5,10 @@ For this it will provide API endpoints for every configured attribute-group.
|
||||||
The configuration of the provider is possible via an admin page.
|
The configuration of the provider is possible via an admin page.
|
||||||
|
|
||||||
Every endpoint responds with a list of all attribute values, that:
|
Every endpoint responds with a list of all attribute values, that:
|
||||||
- is in the attribute group matching `attribute-group`
|
- are in the attribute group matching `attribute-group`
|
||||||
- matches an optional RegEx Pattern `attribute-regex`
|
- match an optional RegEx Pattern `attribute-regex`
|
||||||
- belongs to a user with a role matching `match-role`
|
- belong to a user with a role matching `match-role`
|
||||||
- is non-empty
|
- are non-empty
|
||||||
|
|
||||||
Multivalue attributes are flattened in the response.
|
Multivalue attributes are flattened in the response.
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ We assume an unconfigured, fresh Keycloak installation running under `http://loc
|
||||||
- After creating:
|
- After creating:
|
||||||
- give it the role `myattribute-export`
|
- give it the role `myattribute-export`
|
||||||
- set a password in the users settings `Creadentials > Set password`. For Example `"password"`
|
- set a password in the users settings `Creadentials > Set password`. For Example `"password"`
|
||||||
8. Under `🪪 Attribute Endpoints 🚀 > Create item`, add a new endpoint to the provider
|
8. Under `Attribute Endpoints > Create item`, add a new endpoint to the provider
|
||||||
Example:
|
Example:
|
||||||
- `Slug` = `"ssh_keys"`
|
- `Slug` = `"ssh_keys"`
|
||||||
- `Attribute Group` = `"my-attributes-group"`
|
- `Attribute Group` = `"my-attributes-group"`
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import com.google.auto.service.AutoService;
|
||||||
*/
|
*/
|
||||||
@AutoService(UiPageProviderFactory.class)
|
@AutoService(UiPageProviderFactory.class)
|
||||||
public class AdminUiPage implements UiPageProvider, UiPageProviderFactory<ComponentModel> {
|
public class AdminUiPage implements UiPageProvider, UiPageProviderFactory<ComponentModel> {
|
||||||
public static final String PROVIDER_ID = "🪪 Attribute Endpoints 🚀";
|
public static final String PROVIDER_ID = "Attribute Endpoints";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
|
|
@ -54,22 +54,28 @@ public class AdminUiPage implements UiPageProvider, UiPageProviderFactory<Compon
|
||||||
|
|
||||||
Pattern slugPattern = Pattern.compile("^[a-zA-Z0-9_-]*$");
|
Pattern slugPattern = Pattern.compile("^[a-zA-Z0-9_-]*$");
|
||||||
String configAttributeSlug = model.getConfig().getFirst("slug");
|
String configAttributeSlug = model.getConfig().getFirst("slug");
|
||||||
|
if (configAttributeSlug == null) {
|
||||||
if (!slugPattern.matcher(configAttributeSlug).matches()) {
|
hasError = true;
|
||||||
|
errorString += " • [Slug] can not be empty\n";
|
||||||
|
} else if (!slugPattern.matcher(configAttributeSlug).matches()) {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
errorString += " • [Slug] can only contain anlphanumeric characters, dash and underscore (a-z A-Z 0-9 _ - )\n";
|
errorString += " • [Slug] can only contain anlphanumeric characters, dash and underscore (a-z A-Z 0-9 _ - )\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
String configAuthRole = model.getConfig().getFirst("auth-role");
|
String configAuthRole = model.getConfig().getFirst("auth-role");
|
||||||
RoleModel authRole = realm.getRole(configAuthRole);
|
if (configAuthRole == null) {
|
||||||
if (authRole == null) {
|
hasError = true;
|
||||||
|
errorString += " • [Auth Role] can not be empty\n";
|
||||||
|
} else if (realm.getRole(configAuthRole) == null) {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
errorString += " • [Auth Role] does not exist\n";
|
errorString += " • [Auth Role] does not exist\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
String configMatchRole = model.getConfig().getFirst("match-role");
|
String configMatchRole = model.getConfig().getFirst("match-role");
|
||||||
RoleModel matchRole = realm.getRole(configMatchRole);
|
if (configMatchRole == null) {
|
||||||
if (matchRole == null) {
|
hasError = true;
|
||||||
|
errorString += " • [Match Role] can not be empty\n";
|
||||||
|
} else if (realm.getRole(configMatchRole) == null) {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
errorString += " • [Match Role] does not exist\n";
|
errorString += " • [Match Role] does not exist\n";
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +83,10 @@ public class AdminUiPage implements UiPageProvider, UiPageProviderFactory<Compon
|
||||||
UserProfileProvider profileProvider = session.getProvider(UserProfileProvider.class);
|
UserProfileProvider profileProvider = session.getProvider(UserProfileProvider.class);
|
||||||
UPConfig upconfig = profileProvider.getConfiguration();
|
UPConfig upconfig = profileProvider.getConfiguration();
|
||||||
String configAttributeGroup = model.getConfig().getFirst("attribute-group");
|
String configAttributeGroup = model.getConfig().getFirst("attribute-group");
|
||||||
if (!upconfig.getGroups().stream().anyMatch(g -> g.getName().equals(configAttributeGroup))) {
|
if (configAttributeGroup == null) {
|
||||||
|
hasError = true;
|
||||||
|
errorString += " • [Attribute Group] can not be empty\n";
|
||||||
|
} else if (!upconfig.getGroups().stream().anyMatch(g -> g.getName().equals(configAttributeGroup))) {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
errorString += " • [Attribute Group] does not exist\n";
|
errorString += " • [Attribute Group] does not exist\n";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ public class AttributeEndpointsResourceProvider implements RealmResourceProvider
|
||||||
@GET
|
@GET
|
||||||
@Path("export/{slug}")
|
@Path("export/{slug}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Response exportKeys(@PathParam("slug") String slug) {
|
public Response exportAttributeValues(@PathParam("slug") String slug) {
|
||||||
KeycloakContext context = session.getContext();
|
KeycloakContext context = session.getContext();
|
||||||
RealmModel realm = context.getRealm();
|
RealmModel realm = context.getRealm();
|
||||||
|
|
||||||
|
|
@ -62,11 +62,16 @@ public class AttributeEndpointsResourceProvider implements RealmResourceProvider
|
||||||
.filter(c -> c.getConfig().getFirst("slug").equals(slug))
|
.filter(c -> c.getConfig().getFirst("slug").equals(slug))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
Auth auth = AttributeEndpointsResourceProvider.getAuth(session);
|
||||||
|
|
||||||
if (componentList.isEmpty()) {
|
if (componentList.isEmpty()) {
|
||||||
throw new NotFoundException("Endpoint not found.");
|
throw new NotFoundException("Endpoint not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Auth auth = AttributeEndpointsResourceProvider.getAuth(session);
|
if (componentList.size() > 1) {
|
||||||
|
throw new NotFoundException(
|
||||||
|
"Endpoint Configuration Error - Multiple configurations exist for this endpoint.");
|
||||||
|
}
|
||||||
|
|
||||||
ComponentModel component = componentList.get(0);
|
ComponentModel component = componentList.get(0);
|
||||||
|
|
||||||
|
|
@ -106,11 +111,6 @@ public class AttributeEndpointsResourceProvider implements RealmResourceProvider
|
||||||
throw new ForbiddenException("User does not have required auth role.");
|
throw new ForbiddenException("User does not have required auth role.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (componentList.size() > 1) {
|
|
||||||
throw new NotFoundException(
|
|
||||||
"Endpoint Configuration Error - Multiple configurations exist for this endpoint.");
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> attributeNames = upconfig.getAttributes()
|
List<String> attributeNames = upconfig.getAttributes()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(a -> a.getGroup() != null && a.getGroup().equals(configAttributeGroup))
|
.filter(a -> a.getGroup() != null && a.getGroup().equals(configAttributeGroup))
|
||||||
|
|
|
||||||
2667
realm-export.json
2667
realm-export.json
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue