Skip to content

Commit f396277

Browse files
committed
Add ldap-groups to sync ldap group
1 parent 452959b commit f396277

File tree

5 files changed

+142
-144
lines changed

5 files changed

+142
-144
lines changed

src/main/java/com/scality/keycloak/groupFederationLink/GroupWithLinkLDAPStorageMapper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ private EntityManager getEntityManager() {
2929
protected GroupModel createKcGroup(RealmModel realm, String ldapGroupName, GroupModel parentGroup) {
3030
GroupModel groupModel = super.createKcGroup(realm, ldapGroupName, parentGroup);
3131

32+
EntityManager em = getEntityManager();
3233
GroupFederationLinkEntity groupFederationLinkEntity = new GroupFederationLinkEntity();
3334
groupFederationLinkEntity.setGroupId(groupModel.getId());
3435
groupFederationLinkEntity.setFederationLink(ldapProvider.getModel().getId());
35-
getEntityManager().persist(groupFederationLinkEntity);
36+
em.persist(groupFederationLinkEntity);
37+
em.flush();
3638

3739
return groupModel;
3840
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.scality.keycloak.groupSync;
2+
3+
import java.util.HashMap;
4+
5+
import org.eclipse.microprofile.openapi.annotations.extensions.Extension;
6+
import org.jboss.logging.Logger;
7+
import org.jboss.resteasy.reactive.NoCache;
8+
import org.keycloak.component.ComponentModel;
9+
import org.keycloak.events.admin.OperationType;
10+
import org.keycloak.models.KeycloakSession;
11+
import org.keycloak.models.RealmModel;
12+
import org.keycloak.services.ErrorResponse;
13+
import org.keycloak.services.ServicesLogger;
14+
import org.keycloak.services.resources.KeycloakOpenAPI;
15+
import org.keycloak.services.resources.admin.AdminEventBuilder;
16+
import org.keycloak.services.resources.admin.UserStorageProviderResource;
17+
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
18+
import org.keycloak.storage.UserStorageProvider;
19+
import org.keycloak.storage.ldap.LDAPStorageProvider;
20+
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
21+
import org.keycloak.storage.user.SynchronizationResult;
22+
23+
import jakarta.ws.rs.BadRequestException;
24+
import jakarta.ws.rs.NotFoundException;
25+
import jakarta.ws.rs.POST;
26+
import jakarta.ws.rs.Path;
27+
import jakarta.ws.rs.PathParam;
28+
import jakarta.ws.rs.Produces;
29+
import jakarta.ws.rs.QueryParam;
30+
import jakarta.ws.rs.core.MediaType;
31+
import jakarta.ws.rs.core.Response;
32+
33+
@Extension(name = KeycloakOpenAPI.Profiles.ADMIN, value = "")
34+
public class GroupSyncAdminResource {
35+
protected static final Logger logger = Logger.getLogger(GroupSyncAdminResource.class);
36+
protected final AdminPermissionEvaluator auth;
37+
protected final KeycloakSession session;
38+
protected final RealmModel realm;
39+
40+
public GroupSyncAdminResource(KeycloakSession session, AdminPermissionEvaluator auth,
41+
AdminEventBuilder adminEvent) {
42+
this.session = session;
43+
this.auth = auth;
44+
this.realm = session.getContext().getRealm();
45+
}
46+
47+
/**
48+
* Trigger sync of mapper data related to ldap mapper (roles, groups, ...)
49+
*
50+
* direction is "fedToKeycloak" or "keycloakToFed"
51+
*
52+
* @return
53+
*/
54+
@POST
55+
@Path("{parentId}/mappers/{id}/sync")
56+
@NoCache
57+
@Produces(MediaType.APPLICATION_JSON)
58+
public SynchronizationResult syncMapperData(@PathParam("parentId") String parentId,
59+
@PathParam("id") String mapperId, @QueryParam("direction") String direction) {
60+
auth.users().requireManage();
61+
62+
ComponentModel parentModel = realm.getComponent(parentId);
63+
if (parentModel == null)
64+
throw new NotFoundException("Parent model not found");
65+
ComponentModel mapperModel = realm.getComponent(mapperId);
66+
if (mapperModel == null)
67+
throw new NotFoundException("Mapper model not found");
68+
69+
LDAPStorageProvider ldapProvider = (LDAPStorageProvider) session.getProvider(UserStorageProvider.class,
70+
parentModel);
71+
LDAPStorageMapper mapper = session.getProvider(LDAPStorageMapper.class, mapperModel);
72+
73+
ServicesLogger.LOGGER.syncingDataForMapper(mapperModel.getName(), mapperModel.getProviderId(), direction);
74+
75+
SynchronizationResult syncResult;
76+
if ("fedToKeycloak".equals(direction)) {
77+
try {
78+
syncResult = mapper.syncDataFromFederationProviderToKeycloak(realm);
79+
} catch (Exception e) {
80+
String errorMsg = UserStorageProviderResource.getErrorCode(e);
81+
throw ErrorResponse.error(errorMsg, Response.Status.BAD_REQUEST);
82+
}
83+
} else if ("keycloakToFed".equals(direction)) {
84+
try {
85+
syncResult = mapper.syncDataFromKeycloakToFederationProvider(realm);
86+
} catch (Exception e) {
87+
String errorMsg = UserStorageProviderResource.getErrorCode(e);
88+
throw ErrorResponse.error(errorMsg, Response.Status.BAD_REQUEST);
89+
}
90+
} else {
91+
throw new BadRequestException("Unknown direction: " + direction);
92+
}
93+
94+
return syncResult;
95+
}
96+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.scality.keycloak.groupSync;
2+
3+
import org.keycloak.Config.Scope;
4+
import org.keycloak.models.KeycloakSession;
5+
import org.keycloak.models.KeycloakSessionFactory;
6+
import org.keycloak.models.RealmModel;
7+
import org.keycloak.services.resources.admin.AdminEventBuilder;
8+
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProvider;
9+
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProviderFactory;
10+
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
11+
12+
public class GroupSyncAdminResourceProvider implements AdminRealmResourceProviderFactory, AdminRealmResourceProvider {
13+
14+
@Override
15+
public AdminRealmResourceProvider create(KeycloakSession session) {
16+
return this;
17+
}
18+
19+
@Override
20+
public void init(Scope config) {
21+
}
22+
23+
@Override
24+
public void postInit(KeycloakSessionFactory factory) {
25+
}
26+
27+
@Override
28+
public void close() {
29+
}
30+
31+
@Override
32+
public String getId() {
33+
return "ldap-groups";
34+
}
35+
36+
@Override
37+
public Object getResource(KeycloakSession session, RealmModel realm, AdminPermissionEvaluator auth,
38+
AdminEventBuilder adminEvent) {
39+
return new GroupSyncAdminResource(session, auth, adminEvent);
40+
}
41+
42+
}

src/main/java/org/keycloak/storage/ldap/mappers/membership/MembershipType.java

Lines changed: 0 additions & 143 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
com.scality.keycloak.truststore.TruststoreAdminResourceProvider
22
com.scality.keycloak.groupFederationLink.GroupWithLinkAdminResourceProvider
3+
com.scality.keycloak.groupSync.GroupSyncAdminResourceProvider

0 commit comments

Comments
 (0)