Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configuration document and add manage realm rights #57

Merged
merged 2 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ A keycloak plugin to support advanced group management features:
* Roles within groups

## General configuration options
All web services to be executed needs realm management rights role.

For general group management configuarion options execute following web service (necessary during first time deployed):
1. You should define realm attribute 'keycloakUrl' (Keycloak main url)
2. (optional) For general group management configuration options execute following web service (necessary during first time deployed):

`curl --request PUT \
--url {server_url}/realms/{realmName}/agm/admin/configuration \
Expand All @@ -28,10 +30,47 @@ For general group management configuarion options execute following web service
}'`

Parameter explanation:
- invitation-expiration-period = After how many hours the invitation will be expired.
- expiration-notification-period = How many days before Group Membership expiration (or aup expiration) notification email will be sent to user. Can be overridden per Group.
- invitation-expiration-period = After how many hours the invitation will be expired. (default value is 72)
- expiration-notification-period = How many days before Group Membership expiration (or aup expiration) notification email will be sent to user. Can be overridden per Group. (default value is 21)

3. For configuring entitlements user attribute you must execute the following web service :
`curl --request POST \
--url {server_url}/realms/{realmName}/agm/admin/member-user-attribute/configuration \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {admin_access_token}' \
--header 'Content-Type: application/json' \
--data '{
"userAttribute" : "eduPersonEntitlement",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should change to entitlements

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

"urnNamespace" : "urn%3Agrnett%3Aeosc-portal.eu",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to "urn%3Amace%3Aexample.org"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

"authority" : "aai.eosc-portal.eu"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to "authority" : "rciam.example.org" // Optional. It will be omitted from the group entitlements if not specified

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}'`

Only authority is optional.

4. Configuration rules exists for group configuration options. Web service example:
`curl --request POST \
--url {server_url}/realms/{realmName}/agm/admin/configuration-rules \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {admin_access_token}' \
--header 'Content-Type: application/json' \
--data '{
"field" : "membershipExpirationDays" ,
"type" : "TOP_LEVEL" ,
"required" : true,
"defaultValue" : "30",
"max" : "45"
}'`

Fields explanation :
- *field* : field of group management (required)
NicolasLiampotis marked this conversation as resolved.
Show resolved Hide resolved
- *type* : "TOP_LEVEL" or "SUBGROUP" (required)
- *required* : required field (required)
- *defaultValue* : default value
- *max* : max value

With PUT *{server_url}/realms/{realmName}/agm/admin/configuration-rules/{id}* you could update a configuration rule.
With GET *{server_url}/realms/{realmName}/agm/admin/configuration-rules* you could get all configuration rules.

You should define realm attribute 'keycloakUrl' (Keycloak main url)

## REST API

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.keycloak.models.RealmModel;
import org.keycloak.models.jpa.entities.RealmEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
import org.rciam.plugins.groups.helpers.EntityToRepresentation;
import org.rciam.plugins.groups.jpa.entities.GroupEnrollmentConfigurationRulesEntity;
import org.rciam.plugins.groups.jpa.repositories.GroupEnrollmentConfigurationRulesRepository;
Expand All @@ -30,22 +31,26 @@ public class AdminEnrollmentConfigurationRules {
private final RealmModel realm;
private final GroupEnrollmentConfigurationRulesRepository groupEnrollmentConfigurationRulesRepository;
private final AdminEventBuilder adminEvent;
private final AdminPermissionEvaluator realmAuth;

public AdminEnrollmentConfigurationRules(RealmModel realm, KeycloakSession session, AdminEventBuilder adminEvent) {
public AdminEnrollmentConfigurationRules(RealmModel realm, KeycloakSession session, AdminEventBuilder adminEvent, AdminPermissionEvaluator realmAuth) {
this.realm = realm;
this.groupEnrollmentConfigurationRulesRepository = new GroupEnrollmentConfigurationRulesRepository(session);
this.adminEvent = adminEvent;
this.realmAuth = realmAuth;
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<GroupEnrollmentConfigurationRulesRepresentation> getEnrollmentConfigurationRules() {
realmAuth.realm().requireViewRealm();
return groupEnrollmentConfigurationRulesRepository.getByRealm(realm.getId()).map(EntityToRepresentation::toRepresentation).collect(Collectors.toList());
}

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response configureRule(GroupEnrollmentConfigurationRulesRepresentation rep) {
realmAuth.realm().requireManageRealm();
GroupEnrollmentConfigurationRulesEntity entity = new GroupEnrollmentConfigurationRulesEntity();
entity.setId(KeycloakModelUtils.generateId());
RealmEntity realmEntity = new RealmEntity();
Expand All @@ -64,6 +69,7 @@ public Response configureRule(GroupEnrollmentConfigurationRulesRepresentation re
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response updateConfigureRule(GroupEnrollmentConfigurationRulesRepresentation rep, @PathParam("id") String id) {
realmAuth.realm().requireManageRealm();
GroupEnrollmentConfigurationRulesEntity entity = groupEnrollmentConfigurationRulesRepository.getEntity(id);
if (entity == null) {
throw new NotFoundException("Could not find GroupEnrollmentConfigurationRules by id");
Expand All @@ -81,6 +87,7 @@ public Response updateConfigureRule(GroupEnrollmentConfigurationRulesRepresentat
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public GroupEnrollmentConfigurationRulesRepresentation getConfigureRule(@PathParam("id") String id) {
realmAuth.realm().requireViewRealm();
GroupEnrollmentConfigurationRulesEntity entity = groupEnrollmentConfigurationRulesRepository.getEntity(id);
if (entity == null) {
throw new NotFoundException("Could not find GroupEnrollmentConfigurationRules by id");
Expand All @@ -92,6 +99,7 @@ public GroupEnrollmentConfigurationRulesRepresentation getConfigureRule(@PathPar
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response deleteConfigureRule(@PathParam("id") String id) {
realmAuth.realm().requireManageRealm();
groupEnrollmentConfigurationRulesRepository.deleteEntity(id);
return Response.noContent().build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public Response configureGroupManagement(Map<String, String> attributes) {
@Path("/member-user-attribute/configuration")
@Produces(MediaType.APPLICATION_JSON)
public MemberUserAttributeConfigurationRepresentation memberUserAttributeConfiguration() {
realmAuth.realm().requireManageRealm();
MemberUserAttributeConfigurationEntity memberUserAttributeEntity = memberUserAttributeConfigurationRepository.getByRealm(realm.getId());
return memberUserAttributeEntity != null ? EntityToRepresentation.toRepresentation(memberUserAttributeEntity) : new MemberUserAttributeConfigurationRepresentation();
}
Expand All @@ -101,6 +102,7 @@ public MemberUserAttributeConfigurationRepresentation memberUserAttributeConfigu
@Path("/member-user-attribute/configuration")
@Consumes(MediaType.APPLICATION_JSON)
public Response configureMemberUserAttribute(MemberUserAttributeConfigurationRepresentation rep) {
realmAuth.realm().requireManageRealm();
MemberUserAttributeConfigurationEntity memberUserAttributeEntity = memberUserAttributeConfigurationRepository.getByRealm(realm.getId());
memberUserAttributeEntity.setUserAttribute(rep.getUserAttribute());
memberUserAttributeEntity.setUrnNamespace(rep.getUrnNamespace());
Expand All @@ -120,7 +122,7 @@ public Response calculateMemberUserAttribute(){

@Path("/configuration-rules")
public AdminEnrollmentConfigurationRules adminEnrollmentConfigurationRules() {
AdminEnrollmentConfigurationRules service = new AdminEnrollmentConfigurationRules(realm, session, adminEvent);
AdminEnrollmentConfigurationRules service = new AdminEnrollmentConfigurationRules(realm, session, adminEvent, realmAuth);
ResteasyProviderFactory.getInstance().injectProperties(service);
return service;
}
Expand Down
Loading