Remove keycloak-test-helper
module
Closes #584 Signed-off-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
parent
b68cae9fd1
commit
cafc905a1e
13 changed files with 1 additions and 1354 deletions
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
rm -rf $HOME/.m2/repository/org/keycloak
|
|
@ -1,46 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>keycloak-misc-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>999.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-test-helper</artifactId>
|
||||
<name>keycloak-test-helper</name>
|
||||
<description>Helper library to test application using Keycloak.</description>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-client-registration-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-admin-client-tests</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-client</artifactId>
|
||||
<version>${resteasy.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jackson2-provider</artifactId>
|
||||
<version>${resteasy.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-java</artifactId>
|
||||
<version>2.35.0</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-services</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -1,500 +0,0 @@
|
|||
/*
|
||||
* JBoss, Home of Professional Open Source
|
||||
* Copyright 2017, Red Hat, Inc. and/or its affiliates, and individual
|
||||
* contributors by the @authors tag. See the copyright.txt in the
|
||||
* distribution for a full listing of individual contributors.
|
||||
*
|
||||
* 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 org.keycloak.test;
|
||||
|
||||
import static org.keycloak.test.builders.ClientBuilder.AccessType.PUBLIC;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.admin.client.resource.RoleResource;
|
||||
import org.keycloak.client.registration.Auth;
|
||||
import org.keycloak.client.registration.ClientRegistration;
|
||||
import org.keycloak.client.registration.ClientRegistrationException;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessPresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.test.builders.ClientBuilder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* A helper class that makes creating tests a bit easier.
|
||||
*
|
||||
* <p>
|
||||
* Usage example:
|
||||
* <pre>{@code
|
||||
* new FluentTestsHelper()
|
||||
* .init()
|
||||
* .createDirectGrantClient("direct-grant-client")
|
||||
* .deleteClient("direct-grant-client")
|
||||
* .createTestUser("seb", "seb")
|
||||
* .assignRoleWithUser("seb", "user")
|
||||
* .deleteTestUser("seb")
|
||||
* .deleteRole("user");
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
public class FluentTestsHelper implements Closeable {
|
||||
|
||||
protected static class ClientData {
|
||||
private final ClientRepresentation clientRepresentation;
|
||||
private final String registrationCode;
|
||||
|
||||
public ClientData(ClientRepresentation clientRepresentation, String registrationCode) {
|
||||
this.clientRepresentation = clientRepresentation;
|
||||
this.registrationCode = registrationCode;
|
||||
}
|
||||
|
||||
public ClientRepresentation getClientRepresentation() {
|
||||
return clientRepresentation;
|
||||
}
|
||||
|
||||
public String getRegistrationCode() {
|
||||
return registrationCode;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String DEFAULT_KEYCLOAK_URL = "http://localhost:8080/auth";
|
||||
public static final String DEFAULT_ADMIN_USERNAME = "admin";
|
||||
public static final String DEFAULT_ADMIN_PASSWORD = "admin";
|
||||
public static final String DEFAULT_ADMIN_REALM = "master";
|
||||
public static final String DEFAULT_ADMIN_CLIENT = "admin-cli";
|
||||
public static final String DEFAULT_TEST_REALM = DEFAULT_ADMIN_REALM;
|
||||
public static final String DEFAULT_USER_ROLE = "user";
|
||||
|
||||
protected final String keycloakBaseUrl;
|
||||
protected final String adminUserName;
|
||||
protected final String adminPassword;
|
||||
protected final String adminClient;
|
||||
protected final String adminRealm;
|
||||
|
||||
protected String testRealm;
|
||||
protected Keycloak keycloak;
|
||||
protected String accessToken;
|
||||
protected volatile boolean isInitialized;
|
||||
protected Map<String, ClientData> createdClients = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a new helper instance.
|
||||
*/
|
||||
public FluentTestsHelper() {
|
||||
this(DEFAULT_ADMIN_USERNAME, DEFAULT_ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new helper instance.
|
||||
*
|
||||
* @param adminUserName Admin username.
|
||||
* @param adminPassword Admin password.
|
||||
*/
|
||||
public FluentTestsHelper(String adminUserName, String adminPassword) {
|
||||
this(DEFAULT_KEYCLOAK_URL, adminUserName, adminPassword, DEFAULT_ADMIN_REALM, DEFAULT_ADMIN_CLIENT, DEFAULT_TEST_REALM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new helper instance.
|
||||
*
|
||||
* @param keycloakBaseUrl Full keycloak URL.
|
||||
* @param adminUserName Admin username.
|
||||
* @param adminPassword Admin password.
|
||||
* @param adminRealm Master realm name.
|
||||
* @param adminClient Admin Client name.
|
||||
* @param testRealm new instance.
|
||||
*/
|
||||
public FluentTestsHelper(String keycloakBaseUrl, String adminUserName, String adminPassword, String adminRealm, String adminClient, String testRealm) {
|
||||
this.keycloakBaseUrl = keycloakBaseUrl;
|
||||
this.testRealm = testRealm;
|
||||
this.adminUserName = adminUserName;
|
||||
this.adminPassword = adminPassword;
|
||||
this.adminRealm = adminRealm;
|
||||
this.adminClient = adminClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization method.
|
||||
*
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper init() {
|
||||
keycloak = createKeycloakInstance(keycloakBaseUrl, adminRealm, adminUserName, adminPassword, adminClient);
|
||||
accessToken = generateInitialAccessToken();
|
||||
isInitialized = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns <code>true</code> if this helper has been initialized.
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return isInitialized;
|
||||
}
|
||||
|
||||
protected Keycloak createKeycloakInstance(String keycloakBaseUrl, String realm, String username, String password, String clientId) {
|
||||
return Keycloak.getInstance(keycloakBaseUrl, realm, username, password, clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* For more complex test scenarios
|
||||
*
|
||||
* @return Keycloak Client instance
|
||||
*/
|
||||
public Keycloak getKeycloakInstance() {
|
||||
assert isInitialized;
|
||||
return keycloak;
|
||||
}
|
||||
|
||||
protected String generateInitialAccessToken() {
|
||||
ClientInitialAccessCreatePresentation rep = new ClientInitialAccessCreatePresentation();
|
||||
rep.setCount(2);
|
||||
rep.setExpiration(180);
|
||||
ClientInitialAccessPresentation initialAccess = keycloak.realms().realm(testRealm).clientInitialAccess().create(rep);
|
||||
return initialAccess.getToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new client based on its representation.
|
||||
*
|
||||
* @param clientRepresentation Client data.
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper createClient(ClientRepresentation clientRepresentation) throws ClientRegistrationException, JsonProcessingException {
|
||||
assert isInitialized;
|
||||
ClientRegistration reg = ClientRegistration.create()
|
||||
.url(keycloakBaseUrl, testRealm)
|
||||
.build();
|
||||
reg.auth(Auth.token(accessToken));
|
||||
clientRepresentation = reg.create(clientRepresentation);
|
||||
String registrationAccessCode = clientRepresentation.getRegistrationAccessToken();
|
||||
reg.auth(Auth.token(registrationAccessCode));
|
||||
createdClients.put(clientRepresentation.getClientId(), new ClientData(clientRepresentation, registrationAccessCode));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a direct grant client.
|
||||
*
|
||||
* @see {@link #createClient(ClientRepresentation)}
|
||||
*/
|
||||
public FluentTestsHelper createDirectGrantClient(String clientId) throws ClientRegistrationException, JsonProcessingException {
|
||||
assert isInitialized;
|
||||
createClient(ClientBuilder.create(clientId).accessType(PUBLIC));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a client previously created by this helper. This will throw an error if you try to delete an
|
||||
* arbitrary client.
|
||||
*
|
||||
* @param clientId Client id to be deleted.
|
||||
* @return <code>this</code>
|
||||
* @throws ClientRegistrationException Thrown when client registration error occurs.
|
||||
*/
|
||||
public FluentTestsHelper deleteClient(String clientId) throws ClientRegistrationException {
|
||||
assert isInitialized;
|
||||
ClientData clientData = createdClients.get(clientId);
|
||||
if (clientData == null) {
|
||||
throw new ClientRegistrationException("This client wasn't created by this helper!");
|
||||
}
|
||||
ClientRegistration reg = ClientRegistration.create()
|
||||
.url(keycloakBaseUrl, testRealm)
|
||||
.build();
|
||||
reg.auth(Auth.token(clientData.getRegistrationCode()));
|
||||
reg.delete(clientId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #importTestRealm(InputStream)
|
||||
*/
|
||||
public FluentTestsHelper importTestRealm(String realmJsonPath) throws IOException {
|
||||
try (InputStream fis = FluentTestsHelper.class.getResourceAsStream(realmJsonPath)) {
|
||||
return importTestRealm(fis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #importTestRealm(InputStream)
|
||||
*/
|
||||
public FluentTestsHelper importTestRealm(File realmJsonPath) throws IOException {
|
||||
try (FileInputStream fis = new FileInputStream(realmJsonPath)) {
|
||||
return importTestRealm(fis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a test realm.
|
||||
*
|
||||
* @param stream A stream representing a JSON file with an exported realm.
|
||||
* @return <code>this</code>
|
||||
* @throws IOException Thrown in case of parsing error.
|
||||
*/
|
||||
public FluentTestsHelper importTestRealm(InputStream stream) throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
RealmRepresentation realmRepresentation = mapper.readValue(stream, RealmRepresentation.class);
|
||||
return createTestRealm(realmRepresentation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a test realm.
|
||||
*
|
||||
* @param realmRepresentation A test realm representation.
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper createTestRealm(RealmRepresentation realmRepresentation) {
|
||||
assert isInitialized;
|
||||
keycloak.realms().create(realmRepresentation);
|
||||
testRealm = realmRepresentation.getRealm();
|
||||
accessToken = generateInitialAccessToken();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a realm.
|
||||
*
|
||||
* @param realmName Realm to be deleted.
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper deleteRealm(String realmName) {
|
||||
assert isInitialized;
|
||||
keycloak.realms().realm(realmName).remove();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the test realm. Meant to be called after testing has finished.
|
||||
*
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper deleteTestRealm() {
|
||||
deleteRealm(testRealm);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a test user.
|
||||
*
|
||||
* @param username A username to be created.
|
||||
* @param password A password for a user.
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper createTestUser(String username, String password) {
|
||||
assert isInitialized;
|
||||
UserRepresentation userRepresentation = new UserRepresentation();
|
||||
userRepresentation.setUsername(username);
|
||||
userRepresentation.setEnabled(true);
|
||||
Response response = keycloak.realms().realm(testRealm).users().create(userRepresentation);
|
||||
String userId = getCreatedId(response);
|
||||
response.close();
|
||||
CredentialRepresentation rep = new CredentialRepresentation();
|
||||
rep.setType(CredentialRepresentation.PASSWORD);
|
||||
rep.setValue(password);
|
||||
rep.setTemporary(false);
|
||||
keycloak.realms().realm(testRealm).users().get(userId).resetPassword(rep);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates a user with a role. This method also creates a role if that is missing.
|
||||
*
|
||||
* @param userName A username to be associated with a role.
|
||||
* @param roleName A role to be associated with a user name.
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper assignRoleWithUser(String userName, String roleName) {
|
||||
assert isInitialized;
|
||||
if (keycloak.realms().realm(testRealm).roles().get(roleName) == null) {
|
||||
RoleRepresentation representation = new RoleRepresentation();
|
||||
representation.setName(roleName);
|
||||
keycloak.realms().realm(testRealm).roles().create(representation);
|
||||
}
|
||||
UserRepresentation userRepresentation = keycloak.realms().realm(testRealm).users().search(userName).get(0);
|
||||
RoleRepresentation realmRole = keycloak.realms().realm(testRealm).roles().get(roleName).toRepresentation();
|
||||
keycloak.realms().realm(testRealm).users().get(userRepresentation.getId()).roles().realmLevel().add(Arrays.asList(realmRole));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a role.
|
||||
*
|
||||
* @param roleName A Role name to be deleted.
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper deleteRole(String roleName) {
|
||||
assert isInitialized;
|
||||
RoleResource role = keycloak.realms().realm(testRealm).roles().get(roleName);
|
||||
if (role != null) {
|
||||
keycloak.realms().realm(testRealm).roles().deleteRole(roleName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a user.
|
||||
*
|
||||
* @param userName A Username to be deleted.
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public FluentTestsHelper deleteTestUser(String userName) {
|
||||
assert isInitialized;
|
||||
UserRepresentation userInKeycloak = keycloak.realms().realm(testRealm).users().search(userName).get(0);
|
||||
if (userInKeycloak != null) {
|
||||
keycloak.realms().realm(testRealm).users().delete(userInKeycloak.getId());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param response
|
||||
* @return ID of the created record
|
||||
*/
|
||||
public String getCreatedId(Response response) {
|
||||
URI location = response.getLocation();
|
||||
if (!response.getStatusInfo().equals(Response.Status.CREATED)) {
|
||||
Response.StatusType statusInfo = response.getStatusInfo();
|
||||
throw new WebApplicationException("Create method returned status "
|
||||
+ statusInfo.getReasonPhrase() + " (Code: " + statusInfo.getStatusCode() + "); expected status: Created (201)", response);
|
||||
}
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
String path = location.getPath();
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given endpoint returns successfully with supplied token.
|
||||
*
|
||||
* @param endpoint Endpoint to be evaluated,
|
||||
* @param token Token that will be passed into the <code>Authorization</code> header.
|
||||
* @return <code>true</code> if the endpoint returns forbidden.
|
||||
* @throws IOException Thrown by the underlying HTTP Client implementation
|
||||
*/
|
||||
public boolean testGetWithAuth(String endpoint, String token) throws IOException {
|
||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||
|
||||
try {
|
||||
HttpGet get = new HttpGet(keycloakBaseUrl + endpoint);
|
||||
get.addHeader("Authorization", "Bearer " + token);
|
||||
|
||||
HttpResponse response = client.execute(get);
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
return false;
|
||||
}
|
||||
HttpEntity entity = response.getEntity();
|
||||
InputStream is = entity.getContent();
|
||||
try {
|
||||
return true;
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given endpoint returns Forbidden HTTP Code.
|
||||
*
|
||||
* @param endpoint Endpoint to be evaluated,
|
||||
* @return <code>true</code> if the endpoint returns forbidden.
|
||||
* @throws IOException Thrown by the underlying HTTP Client implementation
|
||||
*/
|
||||
public boolean returnsForbidden(String endpoint) throws IOException {
|
||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||
try {
|
||||
HttpGet get = new HttpGet(keycloakBaseUrl + endpoint);
|
||||
HttpResponse response = client.execute(get);
|
||||
if (response.getStatusLine().getStatusCode() == 403 || response.getStatusLine().getStatusCode() == 401) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns an Access Token.
|
||||
*/
|
||||
public String getToken() {
|
||||
assert isInitialized;
|
||||
return keycloak.tokenManager().getAccessTokenString();
|
||||
}
|
||||
|
||||
public String getKeycloakBaseUrl() {
|
||||
return keycloakBaseUrl;
|
||||
}
|
||||
|
||||
public String getAdminUserName() {
|
||||
return adminUserName;
|
||||
}
|
||||
|
||||
public String getAdminPassword() {
|
||||
return adminPassword;
|
||||
}
|
||||
|
||||
public String getAdminClientId() {
|
||||
return adminClient;
|
||||
}
|
||||
|
||||
public String getAdminRealmName() {
|
||||
return adminRealm;
|
||||
}
|
||||
|
||||
public String getTestRealmName() {
|
||||
return testRealm;
|
||||
}
|
||||
|
||||
public RealmResource getTestRealmResource() {
|
||||
assert isInitialized;
|
||||
return keycloak.realm(testRealm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (keycloak != null && !keycloak.isClosed()) {
|
||||
keycloak.close();
|
||||
}
|
||||
isInitialized = false;
|
||||
}
|
||||
}
|
|
@ -1,259 +0,0 @@
|
|||
/*
|
||||
* JBoss, Home of Professional Open Source
|
||||
* Copyright 2017, Red Hat, Inc. and/or its affiliates, and individual
|
||||
* contributors by the @authors tag. See the copyright.txt in the
|
||||
* distribution for a full listing of individual contributors.
|
||||
*
|
||||
* 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 org.keycloak.test;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.client.registration.Auth;
|
||||
import org.keycloak.client.registration.ClientRegistration;
|
||||
import org.keycloak.client.registration.ClientRegistrationException;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessPresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.test.builders.ClientBuilder;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.keycloak.test.builders.ClientBuilder.AccessType.PUBLIC;
|
||||
|
||||
/**
|
||||
* @deprecated This class will be removed in the next major release. Please migrate to {@link FluentTestsHelper}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class TestsHelper {
|
||||
|
||||
public static String baseUrl;
|
||||
|
||||
public static String keycloakBaseUrl = "http://localhost:8180";
|
||||
|
||||
public static String testRealm = "test-realm";
|
||||
|
||||
public static String initialAccessCode;
|
||||
|
||||
public static String appName;
|
||||
|
||||
public static int initialAccessTokenCount = 2;
|
||||
|
||||
protected static String clientConfiguration;
|
||||
|
||||
protected static String registrationAccessCode;
|
||||
|
||||
public static String createClient(ClientRepresentation clientRepresentation) {
|
||||
ClientRegistration reg = ClientRegistration.create()
|
||||
.url(keycloakBaseUrl, testRealm)
|
||||
.build();
|
||||
|
||||
reg.auth(Auth.token(initialAccessCode));
|
||||
try {
|
||||
clientRepresentation = reg.create(clientRepresentation);
|
||||
registrationAccessCode = clientRepresentation.getRegistrationAccessToken();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
reg.auth(Auth.token(registrationAccessCode));
|
||||
clientConfiguration = mapper.writeValueAsString(reg.getAdapterConfig(clientRepresentation.getClientId()));
|
||||
} catch (ClientRegistrationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return clientConfiguration;
|
||||
}
|
||||
|
||||
public static String createDirectGrantClient() {
|
||||
return createClient(ClientBuilder.create("test-dga").accessType(PUBLIC));
|
||||
}
|
||||
|
||||
public static void deleteClient(String clientId) {
|
||||
ClientRegistration reg = ClientRegistration.create()
|
||||
.url(keycloakBaseUrl, testRealm)
|
||||
.build();
|
||||
try {
|
||||
reg.auth(Auth.token(registrationAccessCode));
|
||||
reg.delete(clientId);
|
||||
} catch (ClientRegistrationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean testGetWithAuth(String endpoint, String token) throws IOException {
|
||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||
|
||||
try {
|
||||
HttpGet get = new HttpGet(baseUrl + endpoint);
|
||||
get.addHeader("Authorization", "Bearer " + token);
|
||||
|
||||
HttpResponse response = client.execute(get);
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
return false;
|
||||
}
|
||||
HttpEntity entity = response.getEntity();
|
||||
InputStream is = entity.getContent();
|
||||
try {
|
||||
return true;
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean returnsForbidden(String endpoint) throws IOException {
|
||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||
try {
|
||||
HttpGet get = new HttpGet(baseUrl + endpoint);
|
||||
HttpResponse response = client.execute(get);
|
||||
if (response.getStatusLine().getStatusCode() == 403 || response.getStatusLine().getStatusCode() == 401) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getToken(String username, String password, String realm) {
|
||||
Keycloak keycloak = Keycloak.getInstance(
|
||||
keycloakBaseUrl,
|
||||
realm,
|
||||
username,
|
||||
password,
|
||||
"test-dga");
|
||||
return keycloak.tokenManager().getAccessTokenString();
|
||||
|
||||
}
|
||||
|
||||
public static boolean importTestRealm(String username, String password, String realmJsonPath) throws IOException {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try (InputStream stream = TestsHelper.class.getResourceAsStream(realmJsonPath)) {
|
||||
RealmRepresentation realmRepresentation = mapper.readValue(stream, RealmRepresentation.class);
|
||||
|
||||
Keycloak keycloak = Keycloak.getInstance(
|
||||
keycloakBaseUrl,
|
||||
"master",
|
||||
username,
|
||||
password,
|
||||
"admin-cli");
|
||||
keycloak.realms().create(realmRepresentation);
|
||||
testRealm = realmRepresentation.getRealm();
|
||||
generateInitialAccessToken(keycloak);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean importTestRealm(String username, String password) throws IOException {
|
||||
testRealm = appName + "-realm";
|
||||
RealmRepresentation realmRepresentation = new RealmRepresentation();
|
||||
realmRepresentation.setRealm(testRealm);
|
||||
realmRepresentation.setEnabled(true);
|
||||
Keycloak keycloak = Keycloak.getInstance(
|
||||
keycloakBaseUrl,
|
||||
"master",
|
||||
username,
|
||||
password,
|
||||
"admin-cli");
|
||||
keycloak.realms().create(realmRepresentation);
|
||||
generateInitialAccessToken(keycloak);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void generateInitialAccessToken(Keycloak keycloak) {
|
||||
ClientInitialAccessCreatePresentation rep = new ClientInitialAccessCreatePresentation();
|
||||
rep.setCount(initialAccessTokenCount);
|
||||
rep.setExpiration(100);
|
||||
ClientInitialAccessPresentation initialAccess = keycloak.realms().realm(testRealm).clientInitialAccess().create(rep);
|
||||
initialAccessCode = initialAccess.getToken();
|
||||
}
|
||||
|
||||
public static boolean deleteRealm(String username, String password, String realmName) throws IOException {
|
||||
|
||||
Keycloak keycloak = Keycloak.getInstance(
|
||||
keycloakBaseUrl,
|
||||
"master",
|
||||
username,
|
||||
password,
|
||||
"admin-cli");
|
||||
keycloak.realms().realm(realmName).remove();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public static boolean createTestUser(String username, String password, String realmName) throws IOException {
|
||||
|
||||
Keycloak keycloak = Keycloak.getInstance(
|
||||
keycloakBaseUrl,
|
||||
"master",
|
||||
username,
|
||||
password,
|
||||
"admin-cli");
|
||||
UserRepresentation userRepresentation = new UserRepresentation();
|
||||
userRepresentation.setUsername(username);
|
||||
userRepresentation.setEnabled(Boolean.TRUE);
|
||||
Response response = keycloak.realms().realm(realmName).users().create(userRepresentation);
|
||||
String userId = getCreatedId(response);
|
||||
response.close();
|
||||
CredentialRepresentation rep = new CredentialRepresentation();
|
||||
rep.setType(CredentialRepresentation.PASSWORD);
|
||||
rep.setValue(password);
|
||||
rep.setTemporary(false);
|
||||
keycloak.realms().realm(realmName).users().get(userId).resetPassword(rep);
|
||||
//add roles
|
||||
RoleRepresentation representation = new RoleRepresentation();
|
||||
representation.setName("user");
|
||||
|
||||
keycloak.realms().realm(realmName).roles().create(representation);
|
||||
RoleRepresentation realmRole = keycloak.realms().realm(realmName).roles().get("user").toRepresentation();
|
||||
keycloak.realms().realm(realmName).users().get(userId).roles().realmLevel().add(Arrays.asList(realmRole));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public static String getCreatedId(Response response) {
|
||||
URI location = response.getLocation();
|
||||
if (!response.getStatusInfo().equals(Response.Status.CREATED)) {
|
||||
Response.StatusType statusInfo = response.getStatusInfo();
|
||||
throw new WebApplicationException("Create method returned status "
|
||||
+ statusInfo.getReasonPhrase() + " (Code: " + statusInfo.getStatusCode() + "); expected status: Created (201)", response);
|
||||
}
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
String path = location.getPath();
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.test.builders;
|
||||
|
||||
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>
|
||||
*/
|
||||
public class ClientBuilder {
|
||||
|
||||
private ClientRepresentation rep;
|
||||
|
||||
public enum AccessType { BEARER_ONLY, PUBLIC, CONFIDENTIAL };
|
||||
|
||||
public static ClientBuilder create(String clientId) {
|
||||
ClientRepresentation rep = new ClientRepresentation();
|
||||
rep.setEnabled(Boolean.TRUE);
|
||||
rep.setClientId(clientId);
|
||||
return new ClientBuilder(rep);
|
||||
}
|
||||
|
||||
private ClientBuilder(ClientRepresentation rep) {
|
||||
this.rep = rep;
|
||||
}
|
||||
|
||||
public ClientRepresentation accessType(AccessType accessType) {
|
||||
switch (accessType) {
|
||||
case BEARER_ONLY:
|
||||
rep.setBearerOnly(true);
|
||||
break;
|
||||
case PUBLIC:
|
||||
rep.setPublicClient(true);
|
||||
break;
|
||||
case CONFIDENTIAL:
|
||||
rep.setPublicClient(false);
|
||||
break;
|
||||
}
|
||||
return defaultSettings();
|
||||
}
|
||||
|
||||
public ClientBuilder rootUrl(String rootUrl) {
|
||||
rep.setRootUrl(rootUrl);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientBuilder redirectUri(String redirectUri) {
|
||||
rep.setRedirectUris(Collections.singletonList(redirectUri));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientBuilder baseUrl(String baseUrl) {
|
||||
rep.setBaseUrl(baseUrl);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientBuilder adminUrl(String adminUrl) {
|
||||
rep.setAdminUrl(adminUrl);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientBuilder secret(String secret) {
|
||||
rep.setSecret(secret);
|
||||
return this;
|
||||
}
|
||||
|
||||
private ClientRepresentation defaultSettings() {
|
||||
rep.setFullScopeAllowed(true);
|
||||
rep.setDirectAccessGrantsEnabled(true);
|
||||
rep.setAdminUrl(rep.getRootUrl());
|
||||
|
||||
if (rep.getRedirectUris() == null && rep.getRootUrl() != null)
|
||||
rep.setRedirectUris(Collections.singletonList(rep.getRootUrl().concat("/*")));
|
||||
if (OIDCAdvancedConfigWrapper.fromClientRepresentation(rep).getPostLogoutRedirectUris() == null) {
|
||||
OIDCAdvancedConfigWrapper.fromClientRepresentation(rep).setPostLogoutRedirectUris(Collections.singletonList("+"));
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,206 +0,0 @@
|
|||
/*
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.test.builders;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.keycloak.models.credential.OTPCredentialModel;
|
||||
import org.keycloak.models.utils.HmacOTP;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class UserBuilder {
|
||||
|
||||
private final UserRepresentation rep;
|
||||
|
||||
public static UserBuilder create() {
|
||||
UserRepresentation rep = new UserRepresentation();
|
||||
rep.setEnabled(Boolean.TRUE);
|
||||
return new UserBuilder(rep);
|
||||
}
|
||||
|
||||
public static UserBuilder edit(UserRepresentation rep) {
|
||||
return new UserBuilder(rep);
|
||||
}
|
||||
|
||||
private UserBuilder(UserRepresentation rep) {
|
||||
this.rep = rep;
|
||||
}
|
||||
|
||||
public UserBuilder id(String id) {
|
||||
rep.setId(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder username(String username) {
|
||||
rep.setUsername(username);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder firstName(String firstName) {
|
||||
rep.setFirstName(firstName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder lastName(String lastName) {
|
||||
rep.setLastName(lastName);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds additional passwords to the user.
|
||||
*/
|
||||
public UserBuilder addPassword(String password) {
|
||||
if (rep.getCredentials() == null) {
|
||||
rep.setCredentials(new LinkedList<>());
|
||||
}
|
||||
|
||||
CredentialRepresentation credential = new CredentialRepresentation();
|
||||
credential.setType(CredentialRepresentation.PASSWORD);
|
||||
credential.setValue(password);
|
||||
|
||||
rep.getCredentials().add(credential);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder addAttribute(String name, String... values) {
|
||||
if (rep.getAttributes() == null) {
|
||||
rep.setAttributes(new HashMap<>());
|
||||
}
|
||||
|
||||
rep.getAttributes().put(name, Arrays.asList(values));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method makes sure that there is one single password for the user.
|
||||
*/
|
||||
public UserBuilder password(String password) {
|
||||
rep.setCredentials(null);
|
||||
return addPassword(password);
|
||||
}
|
||||
|
||||
public UserBuilder email(String email) {
|
||||
rep.setEmail(email);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder emailVerified(boolean emailVerified) {
|
||||
rep.setEmailVerified(emailVerified);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder enabled(boolean enabled) {
|
||||
rep.setEnabled(enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder addRoles(String... roles) {
|
||||
if (rep.getRealmRoles() == null) {
|
||||
rep.setRealmRoles(new ArrayList<>());
|
||||
}
|
||||
rep.getRealmRoles().addAll(Arrays.asList(roles));
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder role(String client, String role) {
|
||||
if (rep.getClientRoles() == null) {
|
||||
rep.setClientRoles(new HashMap<>());
|
||||
}
|
||||
if (rep.getClientRoles().get(client) == null) {
|
||||
rep.getClientRoles().put(client, new LinkedList<>());
|
||||
}
|
||||
rep.getClientRoles().get(client).add(role);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder requiredAction(String requiredAction) {
|
||||
if (rep.getRequiredActions() == null) {
|
||||
rep.setRequiredActions(new LinkedList<>());
|
||||
}
|
||||
rep.getRequiredActions().add(requiredAction);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder serviceAccountId(String serviceAccountId) {
|
||||
rep.setServiceAccountClientId(serviceAccountId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder secret(CredentialRepresentation credential) {
|
||||
if (rep.getCredentials() == null) {
|
||||
rep.setCredentials(new LinkedList<>());
|
||||
}
|
||||
|
||||
rep.getCredentials().add(credential);
|
||||
rep.setTotp(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder totpSecret(String totpSecret) {
|
||||
CredentialRepresentation credential = ModelToRepresentation.toRepresentation(
|
||||
OTPCredentialModel.createTOTP(totpSecret, 6, 30, HmacOTP.HMAC_SHA1));
|
||||
return secret(credential);
|
||||
}
|
||||
|
||||
public UserBuilder hotpSecret(String hotpSecret) {
|
||||
CredentialRepresentation credential = ModelToRepresentation.toRepresentation(
|
||||
OTPCredentialModel.createHOTP(hotpSecret, 6, 0, HmacOTP.HMAC_SHA1));
|
||||
return secret(credential);
|
||||
}
|
||||
|
||||
public UserBuilder otpEnabled() {
|
||||
rep.setTotp(Boolean.TRUE);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder addGroups(String... group) {
|
||||
if (rep.getGroups() == null) {
|
||||
rep.setGroups(new ArrayList<>());
|
||||
}
|
||||
rep.getGroups().addAll(Arrays.asList(group));
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder federatedLink(String identityProvider, String federatedUserId) {
|
||||
if (rep.getFederatedIdentities() == null) {
|
||||
rep.setFederatedIdentities(new LinkedList<>());
|
||||
}
|
||||
FederatedIdentityRepresentation federatedIdentity = new FederatedIdentityRepresentation();
|
||||
federatedIdentity.setUserId(federatedUserId);
|
||||
federatedIdentity.setUserName(rep.getUsername());
|
||||
federatedIdentity.setIdentityProvider(identityProvider);
|
||||
|
||||
rep.getFederatedIdentities().add(federatedIdentity);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserRepresentation build() {
|
||||
return rep;
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.test.page;
|
||||
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>
|
||||
*/
|
||||
public class IndexPage {
|
||||
|
||||
public static final String UNAUTHORIZED = "401 Unauthorized";
|
||||
|
||||
@FindBy(name = "loginBtn")
|
||||
private WebElement loginButton;
|
||||
|
||||
@FindBy(name = "logoutBtn")
|
||||
private WebElement logoutButton;
|
||||
|
||||
@FindBy(name = "adminBtn")
|
||||
private WebElement adminButton;
|
||||
|
||||
@FindBy(name = "publicBtn")
|
||||
private WebElement publicButton;
|
||||
|
||||
@FindBy(name = "securedBtn")
|
||||
private WebElement securedBtn;
|
||||
|
||||
public void clickLogin() {
|
||||
loginButton.click();
|
||||
}
|
||||
|
||||
public void clickLogout() {
|
||||
logoutButton.click();
|
||||
}
|
||||
|
||||
public void clickAdmin() {
|
||||
adminButton.click();
|
||||
}
|
||||
|
||||
public void clickPublic() {
|
||||
publicButton.click();
|
||||
}
|
||||
|
||||
public void clickSecured() {
|
||||
securedBtn.click();
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.test.page;
|
||||
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class LoginPage {
|
||||
|
||||
@FindBy(id = "username")
|
||||
private WebElement usernameInput;
|
||||
|
||||
@FindBy(id = "password")
|
||||
private WebElement passwordInput;
|
||||
|
||||
@FindBy(id = "totp")
|
||||
private WebElement totp;
|
||||
|
||||
@FindBy(id = "rememberMe")
|
||||
private WebElement rememberMe;
|
||||
|
||||
@FindBy(name = "login")
|
||||
private WebElement submitButton;
|
||||
|
||||
@FindBy(name = "cancel")
|
||||
private WebElement cancelButton;
|
||||
|
||||
@FindBy(linkText = "Register")
|
||||
private WebElement registerLink;
|
||||
|
||||
@FindBy(linkText = "Forgot Password?")
|
||||
private WebElement resetPasswordLink;
|
||||
|
||||
@FindBy(linkText = "Username")
|
||||
private WebElement recoverUsernameLink;
|
||||
|
||||
@FindBy(className = "alert-error")
|
||||
private WebElement loginErrorMessage;
|
||||
|
||||
@FindBy(className = "alert-warning")
|
||||
private WebElement loginWarningMessage;
|
||||
|
||||
@FindBy(className = "alert-success")
|
||||
private WebElement loginSuccessMessage;
|
||||
|
||||
|
||||
@FindBy(className = "alert-info")
|
||||
private WebElement loginInfoMessage;
|
||||
|
||||
@FindBy(className = "instruction")
|
||||
private WebElement instruction;
|
||||
|
||||
|
||||
@FindBy(id = "kc-current-locale-link")
|
||||
private WebElement languageText;
|
||||
|
||||
@FindBy(id = "kc-locale-dropdown")
|
||||
private WebElement localeDropdown;
|
||||
|
||||
public void login(String username, String password) {
|
||||
usernameInput.clear();
|
||||
usernameInput.sendKeys(username);
|
||||
|
||||
passwordInput.clear();
|
||||
passwordInput.sendKeys(password);
|
||||
|
||||
submitButton.click();
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.test.page;
|
||||
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>
|
||||
*/
|
||||
public class ProfilePage {
|
||||
|
||||
@FindBy(name = "profileBtn")
|
||||
private WebElement profileButton;
|
||||
|
||||
@FindBy(name = "tokenBtn")
|
||||
private WebElement tokenButton;
|
||||
|
||||
@FindBy(name = "logoutBtn")
|
||||
private WebElement logoutButton;
|
||||
|
||||
@FindBy(name = "accountBtn")
|
||||
private WebElement accountButton;
|
||||
|
||||
@FindBy(id = "token-content")
|
||||
private WebElement tokenContent;
|
||||
|
||||
@FindBy(id = "username")
|
||||
private WebElement username;
|
||||
|
||||
public String getUsername() {
|
||||
return username.getText();
|
||||
}
|
||||
|
||||
public void clickProfile() {
|
||||
profileButton.click();
|
||||
}
|
||||
|
||||
public void clickToken() {
|
||||
tokenButton.click();
|
||||
}
|
||||
|
||||
public void clickLogout() {
|
||||
logoutButton.click();
|
||||
}
|
||||
|
||||
public void clickAccount() {
|
||||
accountButton.click();
|
||||
}
|
||||
|
||||
public String getTokenContent() throws Exception {
|
||||
return tokenContent.getText();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import java.util.regex.Pattern;
|
|||
/**
|
||||
* A simple utility class for trimming test output (if successful).
|
||||
*
|
||||
* Created to shrink down the output for Travis.
|
||||
* Created to shrink down the output for GitHub Actions.
|
||||
*
|
||||
* Created by st on 03/07/17.
|
||||
*/
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Move to https://github.com/keycloak/keycloak-misc
|
17
misc/pom.xml
17
misc/pom.xml
|
@ -1,17 +0,0 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>999.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<name>Keycloak Misc</name>
|
||||
<description/>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-misc-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>keycloak-test-helper</module>
|
||||
</modules>
|
||||
</project>
|
1
pom.xml
1
pom.xml
|
@ -299,7 +299,6 @@
|
|||
<module>integration</module>
|
||||
<module>adapters</module>
|
||||
<module>authz</module>
|
||||
<module>misc</module>
|
||||
<module>js</module>
|
||||
<module>test-framework</module>
|
||||
<module>quarkus</module>
|
||||
|
|
Loading…
Reference in a new issue