use of org.keycloak.models.RealmModel in project keycloak by keycloak.
the class GroupLDAPStorageMapper method syncFlatGroupStructure.
private void syncFlatGroupStructure(RealmModel realm, SynchronizationResult syncResult, Map<String, LDAPObject> ldapGroupsMap) {
Set<String> visitedGroupIds = new HashSet<>();
// Just add flat structure of groups with all groups at groups path
LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig();
final int groupsPerTransaction = ldapConfig.getBatchSizeForSync();
Set<Map.Entry<String, LDAPObject>> entries = ldapGroupsMap.entrySet();
for (Iterator<Map.Entry<String, LDAPObject>> it = entries.iterator(); it.hasNext(); ) {
KeycloakModelUtils.runJobInTransaction(ldapProvider.getSession().getKeycloakSessionFactory(), session -> {
// KEYCLOAK-8253 The retrieval of the current realm to operate at, was intentionally left
// outside the following for loop! This prevents the scenario, when LDAP group sync time
// initially improves, but during the time (after ~20K groups are synced) degrades again
// due to the realm cache being bloated with huge amount of (temporary) realm entities
RealmModel currentRealm = session.realms().getRealm(realm.getId());
// List of group path groups known to the whole transaction
Map<String, GroupModel> transactionGroupPathGroups = getKcSubGroups(currentRealm, null).collect(Collectors.toMap(GroupModel::getName, Function.identity()));
for (int i = 0; i < groupsPerTransaction && it.hasNext(); i++) {
Map.Entry<String, LDAPObject> groupEntry = it.next();
String groupName = groupEntry.getKey();
GroupModel kcExistingGroup = transactionGroupPathGroups.get(groupName);
if (kcExistingGroup != null) {
syncExistingGroup(kcExistingGroup, groupEntry, syncResult, visitedGroupIds, groupName);
} else {
syncNonExistingGroup(realm, groupEntry, syncResult, visitedGroupIds, groupName);
}
}
});
}
// Possibly remove keycloak groups, which don't exist in LDAP
if (config.isDropNonExistingGroupsDuringSync()) {
dropNonExistingKcGroups(realm, syncResult, visitedGroupIds);
}
}
use of org.keycloak.models.RealmModel in project keycloak by keycloak.
the class RoleLDAPStorageMapper method syncDataFromKeycloakToFederationProvider.
// Sync roles from Keycloak back to LDAP
@Override
public SynchronizationResult syncDataFromKeycloakToFederationProvider(RealmModel realm) {
SynchronizationResult syncResult = new SynchronizationResult() {
@Override
public String getStatus() {
return String.format("%d roles imported to LDAP, %d roles already existed in LDAP", getAdded(), getUpdated());
}
};
if (config.getMode() != LDAPGroupMapperMode.LDAP_ONLY) {
logger.warnf("Ignored sync for federation mapper '%s' as it's mode is '%s'", mapperModel.getName(), config.getMode().toString());
return syncResult;
}
logger.debugf("Syncing roles from Keycloak into LDAP. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getName());
// Send LDAP query to see which roles exists there
try (LDAPQuery ldapQuery = createRoleQuery(false)) {
List<LDAPObject> ldapRoles = LDAPUtils.loadAllLDAPObjects(ldapQuery, ldapProvider);
Set<String> ldapRoleNames = new HashSet<>();
String rolesRdnAttr = config.getRoleNameLdapAttribute();
for (LDAPObject ldapRole : ldapRoles) {
String roleName = ldapRole.getAttributeAsString(rolesRdnAttr);
ldapRoleNames.add(roleName);
}
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
Stream<RoleModel> keycloakRoles = roleContainer.getRolesStream();
Consumer<String> syncRoleFromKCToLDAP = roleName -> {
if (ldapRoleNames.contains(roleName)) {
syncResult.increaseUpdated();
} else {
logger.debugf("Syncing role [%s] from Keycloak to LDAP", roleName);
createLDAPRole(roleName);
syncResult.increaseAdded();
}
};
keycloakRoles.map(RoleModel::getName).forEach(syncRoleFromKCToLDAP);
return syncResult;
}
}
use of org.keycloak.models.RealmModel in project keycloak by keycloak.
the class JpaRealmProvider method addClientScopes.
@Override
public void addClientScopes(RealmModel realm, ClientModel client, Set<ClientScopeModel> clientScopes, boolean defaultScope) {
// Defaults to openid-connect
String clientProtocol = client.getProtocol() == null ? OIDCLoginProtocol.LOGIN_PROTOCOL : client.getProtocol();
Map<String, ClientScopeModel> existingClientScopes = getClientScopes(realm, client, true);
existingClientScopes.putAll(getClientScopes(realm, client, false));
clientScopes.stream().filter(clientScope -> !existingClientScopes.containsKey(clientScope.getName())).filter(clientScope -> Objects.equals(clientScope.getProtocol(), clientProtocol)).forEach(clientScope -> {
ClientScopeClientMappingEntity entity = new ClientScopeClientMappingEntity();
entity.setClientScopeId(clientScope.getId());
entity.setClientId(client.getId());
entity.setDefaultScope(defaultScope);
em.persist(entity);
em.flush();
em.detach(entity);
});
}
use of org.keycloak.models.RealmModel in project keycloak by keycloak.
the class JpaRealmProvider method removeRole.
@Override
public boolean removeRole(RoleModel role) {
RealmModel realm;
if (role.getContainer() instanceof RealmModel) {
realm = (RealmModel) role.getContainer();
} else if (role.getContainer() instanceof ClientModel) {
realm = ((ClientModel) role.getContainer()).getRealm();
} else {
throw new IllegalStateException("RoleModel's container isn not instance of either RealmModel or ClientModel");
}
session.users().preRemove(realm, role);
RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId());
if (roleEntity == null || !roleEntity.getRealmId().equals(realm.getId())) {
// Throw model exception to ensure transaction rollback and revert previous operations (removing default roles) as well
throw new ModelException("Role not found or trying to remove role from incorrect realm");
}
String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
em.createNamedQuery("deleteClientScopeRoleMappingByRole").setParameter("role", roleEntity).executeUpdate();
em.flush();
em.remove(roleEntity);
session.getKeycloakSessionFactory().publish(roleRemovedEvent(role));
em.flush();
return true;
}
use of org.keycloak.models.RealmModel in project keycloak by keycloak.
the class JpaUserSessionPersisterProvider method getUserSessionsCountsByClients.
@Override
public Map<String, Long> getUserSessionsCountsByClients(RealmModel realm, boolean offline) {
String offlineStr = offlineToString(offline);
TypedQuery<Object[]> query = em.createNamedQuery("findClientSessionsClientIds", Object[].class);
query.setParameter("offline", offlineStr);
query.setParameter("realmId", realm.getId());
return closing(query.getResultStream()).collect(Collectors.toMap(row -> {
String clientId = row[0].toString();
if (clientId.equals(PersistentClientSessionEntity.EXTERNAL)) {
final String externalClientId = row[1].toString();
final String clientStorageProvider = row[2].toString();
clientId = new StorageId(clientStorageProvider, externalClientId).getId();
}
return clientId;
}, row -> (Long) row[3]));
}
Aggregations