All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.airavata.KeycloakIdentityServerClient Maven / Gradle / Ivy

The newest version!
/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.airavata;

/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;

import javax.ws.rs.core.Response;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class KeycloakIdentityServerClient {

    private Keycloak client;

    public KeycloakIdentityServerClient(String adminUrl, String adminUserName, String adminUserPassword, String trustStorePath, String trustStorePassword) {
        KeyStore trustKeyStore = loadKeyStore(trustStorePath, trustStorePassword);
        this.client = getClient(
                adminUrl,
                "master", // the realm to log in to
                adminUserName, adminUserPassword,  // the user
                "admin-cli", // admin-cli is the client ID used for keycloak admin operations.
                trustKeyStore);
    }
    private Keycloak getClient(String adminUrl, String realm, String adminUserName, String adminUserPassword, String clientId, KeyStore trustKeyStore) {

        ResteasyClient resteasyClient = new ResteasyClientBuilder()
                .connectionPoolSize(10)
                .trustStore(trustKeyStore)
                .build();
        return KeycloakBuilder.builder()
                .serverUrl(adminUrl)
                .realm(realm)
                .username(adminUserName)
                .password(adminUserPassword)
                .clientId(clientId)
                .resteasyClient(resteasyClient)
                .build();
    }

    private KeyStore loadKeyStore(String trustStorePath, String trustStorePassword) {

        FileInputStream fis = null;
        try {
            fis = new java.io.FileInputStream(trustStorePath);
            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(fis, trustStorePassword.toCharArray());
            return ks;
        } catch (Exception e) {
            throw new RuntimeException("Failed to load trust store KeyStore instance", e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    throw new RuntimeException("Failed to close trust store FileInputStream", e);
                }
            }
        }
    }

    void migrateUserStore(List userProfiles, String targetRealm, String tempPassword, Map roleConversionMap){

        Map allRealmRoles = getRealmRoleNameMap(targetRealm);

        for(UserProfileDAO userProfile : userProfiles){
            UserRepresentation user = new UserRepresentation();
            user.setUsername(userProfile.getUserName());
            user.setFirstName(userProfile.getFirstName());
            user.setLastName(userProfile.getLastName());
            user.setEmail(userProfile.getEmail());
            user.setEmailVerified(true);
            user.setEnabled(true);
            List requiredActionList = new ArrayList<>();
            requiredActionList.add("UPDATE_PASSWORD");
            user.setRequiredActions(requiredActionList);
            Response httpResponse = this.client.realm(targetRealm).users().create(user);
            System.out.println(httpResponse.getStatus());
            if(httpResponse.getStatus() == 201){ //HTTP code for record creation: HTTP 201
                List retrieveCreatedUserList = this.client.realm(targetRealm).users().search(user.getUsername(),
                        user.getFirstName(),
                        user.getLastName(),
                        user.getEmail(),
                        0,1);
                UserResource retirievedUser = this.client.realm(targetRealm).users().get(retrieveCreatedUserList.get(0).getId());

                // Add user to realm roles
                List userRealmRoles = userProfile.getRoles().stream()
                        .filter(r -> roleConversionMap.containsKey(r))
                        // Convert from IS role name to Keycloak role name
                        .map(r -> roleConversionMap.get(r))
                        // Convert from Keycloak role name to RoleRepresentation
                        .map(r -> allRealmRoles.get(r))
                        .collect(Collectors.toList());
                retirievedUser.roles().realmLevel().add(userRealmRoles);

                CredentialRepresentation credential = new CredentialRepresentation();
                credential.setType(CredentialRepresentation.PASSWORD);
                credential.setValue(tempPassword);
                credential.setTemporary(true);
                retirievedUser.resetPassword(credential);
                System.out.println("User profile for user " + userProfile.getUserName() + " successfully migrated");
            } else {
                String response = httpResponse.readEntity(String.class);
                System.err.println("Failed to add user [" + userProfile.getUserName() + "] to Keycloak");
                System.err.println("Response: " + response);
            }
            if (httpResponse != null) {
                httpResponse.close();
            }
        }
    }

    public void setUserPassword(String realmId, String username, String newPassword) {
        List retrieveUserList = client.realm(realmId).users().search(username,
                null,
                null,
                null,
                0, 1);
        if (!retrieveUserList.isEmpty()) {
            UserResource retrievedUser = client.realm(realmId).users().get(retrieveUserList.get(0).getId());
            CredentialRepresentation credential = new CredentialRepresentation();
            credential.setType(CredentialRepresentation.PASSWORD);
            credential.setValue(newPassword);
            credential.setTemporary(false);
            retrievedUser.resetPassword(credential);
            // Remove the UPDATE_PASSWORD required action
            UserRepresentation userRepresentation = retrievedUser.toRepresentation();
            userRepresentation.getRequiredActions().remove("UPDATE_PASSWORD");
            retrievedUser.update(userRepresentation);
        } else {
            throw new RuntimeException("Requested user not found");
        }
    }

    private Map getRealmRoleNameMap(String targetRealm) {
        return this.client.realm(targetRealm).roles().list()
                .stream()
                .collect(Collectors.toMap(r -> r.getName(), r -> r));
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy