Search in sources :

Example 1 with UserProvider

use of org.keycloak.models.UserProvider in project keycloak by keycloak.

the class JpaUserProvider method searchForUserStream.

@Override
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<UserEntity> queryBuilder = builder.createQuery(UserEntity.class);
    Root<UserEntity> root = queryBuilder.from(UserEntity.class);
    List<Predicate> predicates = new ArrayList<>();
    List<Predicate> attributePredicates = new ArrayList<>();
    predicates.add(builder.equal(root.get("realmId"), realm.getId()));
    if (!session.getAttributeOrDefault(UserModel.INCLUDE_SERVICE_ACCOUNT, true)) {
        predicates.add(root.get("serviceAccountClientLink").isNull());
    }
    Join<Object, Object> federatedIdentitiesJoin = null;
    for (Map.Entry<String, String> entry : attributes.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        if (value == null) {
            continue;
        }
        switch(key) {
            case UserModel.SEARCH:
                for (String stringToSearch : value.trim().split("\\s+")) {
                    predicates.add(builder.or(getSearchOptionPredicateArray(stringToSearch, builder, root)));
                }
                break;
            case USERNAME:
            case FIRST_NAME:
            case LAST_NAME:
            case EMAIL:
                if (Boolean.valueOf(attributes.getOrDefault(UserModel.EXACT, Boolean.FALSE.toString()))) {
                    predicates.add(builder.equal(builder.lower(root.get(key)), value.toLowerCase()));
                } else {
                    predicates.add(builder.like(builder.lower(root.get(key)), "%" + value.toLowerCase() + "%"));
                }
                break;
            case EMAIL_VERIFIED:
                predicates.add(builder.equal(root.get(key), Boolean.parseBoolean(value.toLowerCase())));
                break;
            case UserModel.ENABLED:
                predicates.add(builder.equal(root.get(key), Boolean.parseBoolean(value)));
                break;
            case UserModel.IDP_ALIAS:
                if (federatedIdentitiesJoin == null) {
                    federatedIdentitiesJoin = root.join("federatedIdentities");
                }
                predicates.add(builder.equal(federatedIdentitiesJoin.get("identityProvider"), value));
                break;
            case UserModel.IDP_USER_ID:
                if (federatedIdentitiesJoin == null) {
                    federatedIdentitiesJoin = root.join("federatedIdentities");
                }
                predicates.add(builder.equal(federatedIdentitiesJoin.get("userId"), value));
                break;
            case UserModel.EXACT:
                break;
            // All unknown attributes will be assumed as custom attributes
            default:
                Join<UserEntity, UserAttributeEntity> attributesJoin = root.join("attributes", JoinType.LEFT);
                attributePredicates.add(builder.and(builder.equal(builder.lower(attributesJoin.get("name")), key.toLowerCase()), builder.equal(builder.lower(attributesJoin.get("value")), value.toLowerCase())));
                break;
        }
    }
    if (!attributePredicates.isEmpty()) {
        predicates.add(builder.and(attributePredicates.toArray(new Predicate[0])));
    }
    Set<String> userGroups = (Set<String>) session.getAttribute(UserModel.GROUPS);
    if (userGroups != null) {
        Subquery subquery = queryBuilder.subquery(String.class);
        Root<UserGroupMembershipEntity> from = subquery.from(UserGroupMembershipEntity.class);
        subquery.select(builder.literal(1));
        List<Predicate> subPredicates = new ArrayList<>();
        subPredicates.add(from.get("groupId").in(userGroups));
        subPredicates.add(builder.equal(from.get("user").get("id"), root.get("id")));
        Subquery subquery1 = queryBuilder.subquery(String.class);
        subquery1.select(builder.literal(1));
        Root from1 = subquery1.from(ResourceEntity.class);
        List<Predicate> subs = new ArrayList<>();
        Expression<String> groupId = from.get("groupId");
        subs.add(builder.like(from1.get("name"), builder.concat("group.resource.", groupId)));
        subquery1.where(subs.toArray(new Predicate[subs.size()]));
        subPredicates.add(builder.exists(subquery1));
        subquery.where(subPredicates.toArray(new Predicate[subPredicates.size()]));
        predicates.add(builder.exists(subquery));
    }
    queryBuilder.where(predicates.toArray(new Predicate[predicates.size()])).orderBy(builder.asc(root.get(UserModel.USERNAME)));
    TypedQuery<UserEntity> query = em.createQuery(queryBuilder);
    UserProvider users = session.users();
    return closing(paginateQuery(query, firstResult, maxResults).getResultStream()).map(userEntity -> users.getUserById(realm, userEntity.getId()));
}
Also used : CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) UserAttributeEntity(org.keycloak.models.jpa.entities.UserAttributeEntity) UserGroupMembershipEntity(org.keycloak.models.jpa.entities.UserGroupMembershipEntity) Set(java.util.Set) HashSet(java.util.HashSet) Root(javax.persistence.criteria.Root) ArrayList(java.util.ArrayList) Subquery(javax.persistence.criteria.Subquery) UserEntity(org.keycloak.models.jpa.entities.UserEntity) Predicate(javax.persistence.criteria.Predicate) UserProvider(org.keycloak.models.UserProvider) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with UserProvider

use of org.keycloak.models.UserProvider in project keycloak by keycloak.

the class UserPolicyProviderFactory method updateUsers.

private void updateUsers(Policy policy, AuthorizationProvider authorization, Set<String> users) {
    KeycloakSession session = authorization.getKeycloakSession();
    RealmModel realm = authorization.getRealm();
    UserProvider userProvider = session.users();
    Set<String> updatedUsers = new HashSet<>();
    if (users != null) {
        for (String userId : users) {
            UserModel user = null;
            try {
                user = userProvider.getUserByUsername(realm, userId);
            } catch (Exception ignore) {
            }
            if (user == null) {
                user = userProvider.getUserById(realm, userId);
            }
            if (user == null) {
                throw new RuntimeException("Error while updating policy [" + policy.getName() + "]. User [" + userId + "] could not be found.");
            }
            updatedUsers.add(user.getId());
        }
    }
    try {
        policy.putConfig("users", JsonSerialization.writeValueAsString(updatedUsers));
    } catch (IOException cause) {
        throw new RuntimeException("Failed to serialize users", cause);
    }
}
Also used : RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) UserProvider(org.keycloak.models.UserProvider) KeycloakSession(org.keycloak.models.KeycloakSession) IOException(java.io.IOException) IOException(java.io.IOException) HashSet(java.util.HashSet)

Example 3 with UserProvider

use of org.keycloak.models.UserProvider in project keycloak by keycloak.

the class InfinispanUserSessionProvider method getUserSessionsStream.

protected Stream<UserSessionModel> getUserSessionsStream(RealmModel realm, UserSessionPredicate predicate, boolean offline) {
    if (offline && loadOfflineSessionsFromDatabase) {
        // fetch the offline user-sessions from the persistence provider
        UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
        if (predicate.getUserId() != null) {
            UserModel user = session.users().getUserById(realm, predicate.getUserId());
            if (user != null) {
                return persister.loadUserSessionsStream(realm, user, true, 0, null);
            }
        }
        if (predicate.getBrokerUserId() != null) {
            String[] idpAliasSessionId = predicate.getBrokerUserId().split("\\.");
            Map<String, String> attributes = new HashMap<>();
            attributes.put(UserModel.IDP_ALIAS, idpAliasSessionId[0]);
            attributes.put(UserModel.IDP_USER_ID, idpAliasSessionId[1]);
            UserProvider userProvider = session.getProvider(UserProvider.class);
            UserModel userModel = userProvider.searchForUserStream(realm, attributes, 0, null).findFirst().orElse(null);
            return userModel != null ? persister.loadUserSessionsStream(realm, userModel, true, 0, null) : Stream.empty();
        }
        if (predicate.getBrokerSessionId() != null) {
            // currently it is not possible to access the brokerSessionId in offline user-session in a database agnostic way
            throw new ModelException("Dynamic database lookup for offline user-sessions by broker session ID is currently only supported for preloaded sessions. " + "Set preloadOfflineSessionsFromDatabase option to \"true\" in " + UserSessionSpi.NAME + " SPI in " + InfinispanUserSessionProviderFactory.PROVIDER_ID + " provider to enable the lookup.");
        }
    }
    Cache<String, SessionEntityWrapper<UserSessionEntity>> cache = getCache(offline);
    cache = CacheDecorators.skipCacheLoaders(cache);
    // and then mapped locally to avoid serialization issues when trying to manipulate the cache stream directly.
    return StreamSupport.stream(cache.entrySet().stream().filter(predicate).spliterator(), false).map(Mappers.userSessionEntity()).map(entity -> this.wrap(realm, entity, offline));
}
Also used : UserModel(org.keycloak.models.UserModel) UserSessionPersisterProvider(org.keycloak.models.session.UserSessionPersisterProvider) ModelException(org.keycloak.models.ModelException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) UserProvider(org.keycloak.models.UserProvider) SessionEntityWrapper(org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper)

Example 4 with UserProvider

use of org.keycloak.models.UserProvider in project keycloak by keycloak.

the class KeycloakApplication method importAddUser.

public void importAddUser() {
    String configDir = System.getProperty("jboss.server.config.dir");
    if (configDir != null) {
        File addUserFile = new File(configDir + File.separator + "keycloak-add-user.json");
        if (addUserFile.isFile()) {
            ServicesLogger.LOGGER.imprtingUsersFrom(addUserFile);
            List<RealmRepresentation> realms;
            try {
                realms = JsonSerialization.readValue(new FileInputStream(addUserFile), new TypeReference<List<RealmRepresentation>>() {
                });
            } catch (IOException e) {
                ServicesLogger.LOGGER.failedToLoadUsers(e);
                return;
            }
            for (RealmRepresentation realmRep : realms) {
                for (UserRepresentation userRep : realmRep.getUsers()) {
                    KeycloakSession session = sessionFactory.create();
                    try {
                        session.getTransactionManager().begin();
                        RealmModel realm = session.realms().getRealmByName(realmRep.getRealm());
                        if (realm == null) {
                            ServicesLogger.LOGGER.addUserFailedRealmNotFound(userRep.getUsername(), realmRep.getRealm());
                        }
                        UserProvider users = session.users();
                        if (users.getUserByUsername(realm, userRep.getUsername()) != null) {
                            ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername());
                        } else {
                            UserModel user = users.addUser(realm, userRep.getUsername());
                            user.setEnabled(userRep.isEnabled());
                            RepresentationToModel.createCredentials(userRep, session, realm, user, false);
                            RepresentationToModel.createRoleMappings(userRep, user, realm);
                            ServicesLogger.LOGGER.addUserSuccess(userRep.getUsername(), realmRep.getRealm());
                        }
                        session.getTransactionManager().commit();
                    } catch (ModelDuplicateException e) {
                        session.getTransactionManager().rollback();
                        ServicesLogger.LOGGER.addUserFailedUserExists(userRep.getUsername(), realmRep.getRealm());
                    } catch (Throwable t) {
                        session.getTransactionManager().rollback();
                        ServicesLogger.LOGGER.addUserFailed(t, userRep.getUsername(), realmRep.getRealm());
                    } finally {
                        session.close();
                    }
                }
            }
            if (!addUserFile.delete()) {
                ServicesLogger.LOGGER.failedToDeleteFile(addUserFile.getAbsolutePath());
            }
        }
    }
}
Also used : RealmRepresentation(org.keycloak.representations.idm.RealmRepresentation) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) UserProvider(org.keycloak.models.UserProvider) KeycloakSession(org.keycloak.models.KeycloakSession) ModelDuplicateException(org.keycloak.models.ModelDuplicateException) TypeReference(com.fasterxml.jackson.core.type.TypeReference) File(java.io.File) UserRepresentation(org.keycloak.representations.idm.UserRepresentation)

Example 5 with UserProvider

use of org.keycloak.models.UserProvider in project keycloak by keycloak.

the class LDAPSyncTest method test01LDAPSync.

// @Test
// public void test01runit() throws Exception {
// Thread.sleep(10000000);
// }
@Test
public void test01LDAPSync() {
    // wait a bit
    WaitUtils.pause(getLDAPRule().getSleepTime());
    // Sync 5 users from LDAP
    testingClient.server().run(session -> {
        LDAPTestContext ctx = LDAPTestContext.init(session);
        UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
        KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
        SynchronizationResult syncResult = usersSyncManager.syncAllUsers(sessionFactory, "test", ctx.getLdapModel());
        LDAPTestAsserts.assertSyncEquals(syncResult, 5, 0, 0, 0);
    });
    testingClient.server().run(session -> {
        LDAPTestContext ctx = LDAPTestContext.init(session);
        RealmModel testRealm = ctx.getRealm();
        UserProvider userProvider = session.userLocalStorage();
        // Assert users imported
        LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user1", "User1FN", "User1LN", "user1@email.org", "121");
        LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user2", "User2FN", "User2LN", "user2@email.org", "122");
        LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user3", "User3FN", "User3LN", "user3@email.org", "123");
        LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user4", "User4FN", "User4LN", "user4@email.org", "124");
        LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org", "125");
        // Assert lastSync time updated
        Assert.assertTrue(ctx.getLdapModel().getLastSync() > 0);
        testRealm.getUserStorageProvidersStream().forEachOrdered(persistentFedModel -> {
            if (LDAPStorageProviderFactory.PROVIDER_NAME.equals(persistentFedModel.getProviderId())) {
                Assert.assertTrue(persistentFedModel.getLastSync() > 0);
            } else {
                // Dummy provider has still 0
                Assert.assertEquals(0, persistentFedModel.getLastSync());
            }
        });
    });
    // wait a bit
    WaitUtils.pause(getLDAPRule().getSleepTime());
    testingClient.server().run(session -> {
        LDAPTestContext ctx = LDAPTestContext.init(session);
        RealmModel testRealm = ctx.getRealm();
        UserProvider userProvider = session.userLocalStorage();
        UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
        // Add user to LDAP and update 'user5' in LDAP
        LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), testRealm, "user6", "User6FN", "User6LN", "user6@email.org", null, "126");
        LDAPObject ldapUser5 = ctx.getLdapProvider().loadLDAPUserByUsername(testRealm, "user5");
        // NOTE: Changing LDAP attributes directly here
        ldapUser5.setSingleAttribute(LDAPConstants.EMAIL, "user5Updated@email.org");
        ldapUser5.setSingleAttribute(LDAPConstants.POSTAL_CODE, "521");
        ctx.getLdapProvider().getLdapIdentityStore().update(ldapUser5);
        // Assert still old users in local provider
        LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org", "125");
        Assert.assertNull(userProvider.getUserByUsername(testRealm, "user6"));
        // Trigger partial sync
        KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
        SynchronizationResult syncResult = usersSyncManager.syncChangedUsers(sessionFactory, "test", ctx.getLdapModel());
        LDAPTestAsserts.assertSyncEquals(syncResult, 1, 1, 0, 0);
    });
    testingClient.server().run(session -> {
        RealmModel testRealm = session.realms().getRealm("test");
        UserProvider userProvider = session.userLocalStorage();
        // Assert users updated in local provider
        LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5updated@email.org", "521");
        LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user6", "User6FN", "User6LN", "user6@email.org", "126");
    });
}
Also used : RealmModel(org.keycloak.models.RealmModel) UserStorageSyncManager(org.keycloak.services.managers.UserStorageSyncManager) UserProvider(org.keycloak.models.UserProvider) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) SynchronizationResult(org.keycloak.storage.user.SynchronizationResult) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) Test(org.junit.Test)

Aggregations

UserProvider (org.keycloak.models.UserProvider)12 UserModel (org.keycloak.models.UserModel)10 RealmModel (org.keycloak.models.RealmModel)9 KeycloakSession (org.keycloak.models.KeycloakSession)4 IOException (java.io.IOException)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 Test (org.junit.Test)3 KeycloakSessionFactory (org.keycloak.models.KeycloakSessionFactory)3 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 Set (java.util.Set)2 UserStorageSyncManager (org.keycloak.services.managers.UserStorageSyncManager)2 LDAPObject (org.keycloak.storage.ldap.idm.model.LDAPObject)2 SynchronizationResult (org.keycloak.storage.user.SynchronizationResult)2 TypeReference (com.fasterxml.jackson.core.type.TypeReference)1 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1