<commit_before>/*
 * Copyright 2017 Red Hat Inc.
 *
 * Licensed 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 io.enmasse.systemtest;

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.RealmResource;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;

import javax.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class KeycloakClient {

    private final Endpoint endpoint;
    private final KeycloakCredentials credentials;
    private final KeyStore trustStore;

    private static KeyStore createTrustStore(String keycloakCaCert) throws Exception {
        try {
            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(null);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            keyStore.setCertificateEntry("standard-authservice",
                    cf.generateCertificate(new ByteArrayInputStream(keycloakCaCert.getBytes("UTF-8"))));

            return keyStore;
        } catch (Exception ignored) {
            Logging.log.warn("Error creating keystore for authservice CA", ignored);
            throw ignored;
        }
    }

    public KeycloakClient(Endpoint endpoint, KeycloakCredentials credentials, String keycloakCaCert) throws Exception {
        this.endpoint = endpoint;
        this.credentials = credentials;
        this.trustStore = createTrustStore(keycloakCaCert);
    }

    public void joinGroup(String realm, String groupName, String username) throws Exception {
        joinGroup(realm, groupName, username, 3, TimeUnit.MINUTES);
    }

    public void joinGroup(String realm, String groupName, String username, long timeout, TimeUnit timeUnit) throws Exception {
        int maxRetries = 10;
        try (CloseableKeycloak keycloak = new CloseableKeycloak(endpoint, credentials, trustStore)) {
            RealmResource realmResource = waitForRealm(keycloak.get(), realm, timeout, timeUnit);
            if (realmResource.groups().group("admin") != null) {
                for (int retries = 0; retries < maxRetries; retries++) {
                    try {
                        List<UserRepresentation> users = keycloak.get().realm(realm).users().search(username);
                        if (!users.isEmpty()) {
                            String clientId = users.get(0).getId();
                            keycloak.get().realm(realm).users().get(clientId).joinGroup(groupName);
                            Logging.log.info("User '{}' successfully joined into group '{}'", username, groupName);
                            break;
                        } else {
                            throw new RuntimeException("Unable to find user: " + username);
                        }
                    } catch (Exception e) {
                        Logging.log.info("Exception querying keycloak ({}), retrying", e.getMessage());
                        Thread.sleep(2000);
                    }
                }
            } else {
                throw new RuntimeException("group doesn't exist:" + groupName);
            }
        }
    }

    public void leaveGroup(String realm, String groupName, String username) throws Exception {
        leaveGroup(realm, groupName, username, 3, TimeUnit.MINUTES);
    }

    public void leaveGroup(String realm, String groupName, String username, long timeout, TimeUnit timeUnit) throws Exception {
        int maxRetries = 10;
        try (CloseableKeycloak keycloak = new CloseableKeycloak(endpoint, credentials, trustStore)) {
            RealmResource realmResource = waitForRealm(keycloak.get(), realm, timeout, timeUnit);
            if (realmResource.groups().group("admin") != null) {
                for (int retries = 0; retries < maxRetries; retries++) {
                    try {
                        List<UserRepresentation> users = keycloak.get().realm(realm).users().search("username");
                        if (!users.isEmpty()) {
                            String clientId = users.get(0).getId();
                            keycloak.get().realm(realm).users().get(clientId).leaveGroup(groupName);
                            Logging.log.info("User '{}' successfully joined into group '{}'", username, groupName);
                            break;
                        } else {
                            throw new RuntimeException("Unable to find user: " + username);
                        }
                    } catch (Exception e) {
                        Logging.log.info("Exception querying keycloak ({}), retrying", e.getMessage());
                        Thread.sleep(2000);
                    }
                }
            } else {
                throw new RuntimeException("group doesn't exist:" + groupName);
            }
        }
    }

    public void createGroup(String realm, String groupName) throws Exception {
        createGroup(realm, groupName, 3, TimeUnit.MINUTES);
    }

    public void createGroup(String realm, String groupName, long timeout, TimeUnit timeUnit) throws Exception {
        int maxRetries = 10;
        try (CloseableKeycloak keycloak = new CloseableKeycloak(endpoint, credentials, trustStore)) {
            RealmResource realmResource = waitForRealm(keycloak.get(), realm, timeout, timeUnit);

            for (int retries = 0; retries < maxRetries; retries++) {
                try {<commit_msg>FIX KeycloakClient - join/leave group fixed<commit_after>/*
 * Copyright 2017 Red Hat Inc.
 *
 * Licensed 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 io.enmasse.systemtest;

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.RealmResource;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;

import javax.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

public class KeycloakClient {

    private final Endpoint endpoint;
    private final KeycloakCredentials credentials;
    private final KeyStore trustStore;

    private static KeyStore createTrustStore(String keycloakCaCert) throws Exception {
        try {
            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(null);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            keyStore.setCertificateEntry("standard-authservice",
                    cf.generateCertificate(new ByteArrayInputStream(keycloakCaCert.getBytes("UTF-8"))));

            return keyStore;
        } catch (Exception ignored) {
            Logging.log.warn("Error creating keystore for authservice CA", ignored);
            throw ignored;
        }
    }

    public KeycloakClient(Endpoint endpoint, KeycloakCredentials credentials, String keycloakCaCert) throws Exception {
        this.endpoint = endpoint;
        this.credentials = credentials;
        this.trustStore = createTrustStore(keycloakCaCert);
    }

    public void joinGroup(String realm, String groupName, String username) throws Exception {
        joinGroup(realm, groupName, username, 3, TimeUnit.MINUTES);
    }

    public void joinGroup(String realm, String groupName, String username, long timeout, TimeUnit timeUnit) throws Exception {
        int maxRetries = 10;
        try (CloseableKeycloak keycloak = new CloseableKeycloak(endpoint, credentials, trustStore)) {
            RealmResource realmResource = waitForRealm(keycloak.get(), realm, timeout, timeUnit);
            for (int retries = 0; retries < maxRetries; retries++) {
                try {
                    List<UserRepresentation> users = keycloak.get().realm(realm).users().search(username);
                    if (!users.isEmpty()) {
                        String clientId = users.get(0).getId();
                        String groupId = null;
                        List<GroupRepresentation> groups =
                                keycloak.get().realm(realm).groups()
                                        .groups()
                                        .stream()
                                        .filter(group -> group.getName().equals(groupName))
                                        .collect(Collectors.toList());

                        if (!groups.isEmpty()) {
                            realmResource.users().get(clientId).joinGroup(groupId);
                            Logging.log.info("User '{}' successfully joined into group '{}'", username, groupName);
                            break;
                        } else {
                            throw new RuntimeException("Unable to find group: " + groupName);
                        }
                    } else {
                        throw new RuntimeException("Unable to find user: " + username);
                    }
                } catch (Exception e) {
                    Logging.log.info("Exception querying keycloak ({}), retrying", e.getMessage());
                    Thread.sleep(2000);
                }
            }
        }
    }

    public void leaveGroup(String realm, String groupName, String username) throws Exception {
        leaveGroup(realm, groupName, username, 3, TimeUnit.MINUTES);
    }

    public void leaveGroup(String realm, String groupName, String username, long timeout, TimeUnit timeUnit) throws Exception {
        int maxRetries = 10;
        try (CloseableKeycloak keycloak = new CloseableKeycloak(endpoint, credentials, trustStore)) {
            RealmResource realmResource = waitForRealm(keycloak.get(), realm, timeout, timeUnit);
            for (int retries = 0; retries < maxRetries; retries++) {
                try {
                    List<UserRepresentation> users = keycloak.get().realm(realm).users().search(username);
                    if (!users.isEmpty()) {
                        String clientId = users.get(0).getId();
                        String groupId = null;
                        List<GroupRepresentation> groups =
                                keycloak.get().realm(realm).groups()
                                        .groups()
                                        .stream()
                                        .filter(group -> group.getName().equals(groupName))
                                        .collect(Collectors.toList());

                        if (!groups.isEmpty()) {
                            realmResource.users().get(clientId).leaveGroup(groupId);
                            Logging.log.info("User '{}' successfully leaved into group '{}'", username, groupName);
                            break;
                        } else {
                            throw new RuntimeException("Unable to find group: " + groupName);
                        }
                    } else {
                        throw new RuntimeException("Unable to find user: " + username);
                    }
                } catch (Exception e) {
                    Logging.log.info("Exception querying keycloak ({}), retrying", e.getMessage());
                    Thread.sleep(2000);
                }
            }
        }
    }

    public void createGroup(String realm, String groupName) throws Exception {
        createGroup(realm, groupName, 3, TimeUnit.MINUTES);
    }

    public void createGroup(String realm, String groupName, long timeout, TimeUnit timeUnit) throws Exception {
        int maxRetries = 10;
        try (CloseableKeycloak keycloak = new CloseableKeycloak(endpoint, credentials, trustStore)) {
            RealmResource realmResource = waitForRealm(keycloak.get(), realm, timeout, timeUnit);

            for (int retries = 0; retries < maxRetries; retries++) {
                try {
{'fraction_non_alphanumeric': 0.09240005857372968, 'fraction_numerical': 0.004978767022990189, 'mean_word_length': 2.119205298013245, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7590475', 'n_tokens_mistral': 3518, 'n_tokens_neox': 3294, 'n_words': 872}