Skip to content

Commit

Permalink
Merge pull request #12 from scality/debug
Browse files Browse the repository at this point in the history
ldap-groups
  • Loading branch information
ChengYanJin authored May 3, 2024
2 parents 9a941fa + f396277 commit e0f3f0e
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG TAG=23.0.1
ARG TAG=24.0.3

FROM quay.io/keycloak/keycloak:${TAG}

Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.scality.keycloak</groupId>
<artifactId>keycloak-extensions</artifactId>
<version>23.0.1-SNAPSHOT</version>
<version>24.0.3-SNAPSHOT</version>

<name>Keycloak: Scality Extensions</name>
<description>Scality owned extensions to support multiple hostname</description>
Expand Down Expand Up @@ -45,7 +45,7 @@
<maven.compiler.release>17</maven.compiler.release>

<!-- For compilation -->
<version.keycloak>23.0.3</version.keycloak>
<version.keycloak>24.0.3</version.keycloak>

<!-- For compatibility tests -->
<keycloak.version>${version.keycloak}</keycloak.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ private EntityManager getEntityManager() {
protected GroupModel createKcGroup(RealmModel realm, String ldapGroupName, GroupModel parentGroup) {
GroupModel groupModel = super.createKcGroup(realm, ldapGroupName, parentGroup);

EntityManager em = getEntityManager();
GroupFederationLinkEntity groupFederationLinkEntity = new GroupFederationLinkEntity();
groupFederationLinkEntity.setGroupId(groupModel.getId());
groupFederationLinkEntity.setFederationLink(ldapProvider.getModel().getId());
getEntityManager().persist(groupFederationLinkEntity);
em.persist(groupFederationLinkEntity);
em.flush();

return groupModel;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.scality.keycloak.groupSync;

import java.util.HashMap;

import org.eclipse.microprofile.openapi.annotations.extensions.Extension;
import org.jboss.logging.Logger;
import org.jboss.resteasy.reactive.NoCache;
import org.keycloak.component.ComponentModel;
import org.keycloak.events.admin.OperationType;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.ErrorResponse;
import org.keycloak.services.ServicesLogger;
import org.keycloak.services.resources.KeycloakOpenAPI;
import org.keycloak.services.resources.admin.AdminEventBuilder;
import org.keycloak.services.resources.admin.UserStorageProviderResource;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
import org.keycloak.storage.user.SynchronizationResult;

import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

@Extension(name = KeycloakOpenAPI.Profiles.ADMIN, value = "")
public class GroupSyncAdminResource {
protected static final Logger logger = Logger.getLogger(GroupSyncAdminResource.class);
protected final AdminPermissionEvaluator auth;
protected final KeycloakSession session;
protected final RealmModel realm;

public GroupSyncAdminResource(KeycloakSession session, AdminPermissionEvaluator auth,
AdminEventBuilder adminEvent) {
this.session = session;
this.auth = auth;
this.realm = session.getContext().getRealm();
}

/**
* Trigger sync of mapper data related to ldap mapper (roles, groups, ...)
*
* direction is "fedToKeycloak" or "keycloakToFed"
*
* @return
*/
@POST
@Path("{parentId}/mappers/{id}/sync")
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public SynchronizationResult syncMapperData(@PathParam("parentId") String parentId,
@PathParam("id") String mapperId, @QueryParam("direction") String direction) {
auth.users().requireManage();

ComponentModel parentModel = realm.getComponent(parentId);
if (parentModel == null)
throw new NotFoundException("Parent model not found");
ComponentModel mapperModel = realm.getComponent(mapperId);
if (mapperModel == null)
throw new NotFoundException("Mapper model not found");

LDAPStorageProvider ldapProvider = (LDAPStorageProvider) session.getProvider(UserStorageProvider.class,
parentModel);
LDAPStorageMapper mapper = session.getProvider(LDAPStorageMapper.class, mapperModel);

ServicesLogger.LOGGER.syncingDataForMapper(mapperModel.getName(), mapperModel.getProviderId(), direction);

SynchronizationResult syncResult;
if ("fedToKeycloak".equals(direction)) {
try {
syncResult = mapper.syncDataFromFederationProviderToKeycloak(realm);
} catch (Exception e) {
String errorMsg = UserStorageProviderResource.getErrorCode(e);
throw ErrorResponse.error(errorMsg, Response.Status.BAD_REQUEST);
}
} else if ("keycloakToFed".equals(direction)) {
try {
syncResult = mapper.syncDataFromKeycloakToFederationProvider(realm);
} catch (Exception e) {
String errorMsg = UserStorageProviderResource.getErrorCode(e);
throw ErrorResponse.error(errorMsg, Response.Status.BAD_REQUEST);
}
} else {
throw new BadRequestException("Unknown direction: " + direction);
}

return syncResult;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.scality.keycloak.groupSync;

import org.keycloak.Config.Scope;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.services.resources.admin.AdminEventBuilder;
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProvider;
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProviderFactory;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;

public class GroupSyncAdminResourceProvider implements AdminRealmResourceProviderFactory, AdminRealmResourceProvider {

@Override
public AdminRealmResourceProvider create(KeycloakSession session) {
return this;
}

@Override
public void init(Scope config) {
}

@Override
public void postInit(KeycloakSessionFactory factory) {
}

@Override
public void close() {
}

@Override
public String getId() {
return "ldap-groups";
}

@Override
public Object getResource(KeycloakSession session, RealmModel realm, AdminPermissionEvaluator auth,
AdminEventBuilder adminEvent) {
return new GroupSyncAdminResource(session, auth, adminEvent);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

import org.jboss.logging.Logger;
import org.keycloak.models.KeycloakSession;
import org.keycloak.truststore.HostnameVerificationPolicy;
import org.keycloak.common.enums.HostnameVerificationPolicy;
import org.keycloak.truststore.TruststoreProvider;

public class DBTruststoreProvider implements TruststoreProvider {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
com.scality.keycloak.truststore.TruststoreAdminResourceProvider
com.scality.keycloak.groupFederationLink.GroupWithLinkAdminResourceProvider
com.scality.keycloak.groupSync.GroupSyncAdminResourceProvider

0 comments on commit e0f3f0e

Please sign in to comment.