KEYCLOAK-9014 Fix displayed applications
This commit is contained in:
parent
8204509b0c
commit
dad12635f6
15 changed files with 353 additions and 115 deletions
|
@ -29,6 +29,13 @@ public interface OrderedModel {
|
|||
|
||||
class OrderedModelComparator<OM extends OrderedModel> implements Comparator<OM> {
|
||||
|
||||
public static final OrderedModelComparator INSTANCE = new OrderedModelComparator();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends OrderedModel> OrderedModelComparator<T> getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(OM o1, OM o2) {
|
||||
int o1order = parseOrder(o1);
|
||||
|
|
|
@ -18,13 +18,11 @@
|
|||
package org.keycloak.forms.account.freemarker.model;
|
||||
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.forms.login.freemarker.model.OAuthGrantBean;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.OrderedModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
|
@ -39,7 +37,6 @@ import java.util.HashSet;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -47,36 +44,44 @@ import java.util.stream.Collectors;
|
|||
*/
|
||||
public class ApplicationsBean {
|
||||
|
||||
private List<ApplicationEntry> applications = new LinkedList<ApplicationEntry>();
|
||||
private List<ApplicationEntry> applications = new LinkedList<>();
|
||||
|
||||
public ApplicationsBean(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||
|
||||
Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
|
||||
|
||||
for (ClientModel client : getApplications(session, realm, user)) {
|
||||
Set<RoleModel> availableRoles = new HashSet<>();
|
||||
if (isAdminClient(client) && ! AdminPermissions.realms(session, realm, user).isAdmin()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Construct scope parameter with all optional scopes to see all potentially available roles
|
||||
Set<ClientScopeModel> allClientScopes = new HashSet<>(client.getClientScopes(true, true).values());
|
||||
allClientScopes.addAll(client.getClientScopes(false, true).values());
|
||||
allClientScopes.add(client);
|
||||
|
||||
availableRoles = TokenManager.getAccess(user, client, allClientScopes);
|
||||
Set<RoleModel> availableRoles = TokenManager.getAccess(user, client, allClientScopes);
|
||||
|
||||
// Don't show applications, which user doesn't have access into (any available roles)
|
||||
// unless this is can be changed by approving/revoking consent
|
||||
if (! isAdminClient(client) && availableRoles.isEmpty() && ! client.isConsentRequired()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<RoleModel> realmRolesAvailable = new LinkedList<>();
|
||||
MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable = new MultivaluedHashMap<>();
|
||||
processRoles(availableRoles, realmRolesAvailable, resourceRolesAvailable);
|
||||
|
||||
List<ClientScopeModel> orderedScopes = new ArrayList<>();
|
||||
List<ClientScopeModel> orderedScopes = new LinkedList<>();
|
||||
if (client.isConsentRequired()) {
|
||||
UserConsentModel consent = session.users().getConsentByClient(realm, user.getId(), client.getId());
|
||||
|
||||
if (consent != null) {
|
||||
orderedScopes.addAll(consent.getGrantedClientScopes());
|
||||
orderedScopes.sort(new OrderedModel.OrderedModelComparator<>());
|
||||
}
|
||||
}
|
||||
List<String> clientScopesGranted = orderedScopes.stream()
|
||||
.sorted(OrderedModel.OrderedModelComparator.getInstance())
|
||||
.map(ClientScopeModel::getConsentScreenText)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
@ -89,6 +94,11 @@ public class ApplicationsBean {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean isAdminClient(ClientModel client) {
|
||||
return client.getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)
|
||||
|| client.getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID);
|
||||
}
|
||||
|
||||
private Set<ClientModel> getApplications(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||
Set<ClientModel> clients = new HashSet<>();
|
||||
|
||||
|
@ -98,11 +108,6 @@ public class ApplicationsBean {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (client.getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)
|
||||
|| client.getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) {
|
||||
if (!AdminPermissions.realms(session, realm, user).isAdmin()) continue;
|
||||
}
|
||||
|
||||
clients.add(client);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,14 @@ package org.keycloak.testsuite.updaters;
|
|||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.ClientsResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import java.io.Closeable;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
|
@ -14,29 +18,40 @@ import static org.junit.Assert.assertThat;
|
|||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class ClientAttributeUpdater {
|
||||
public class ClientAttributeUpdater extends ServerResourceUpdater<ClientAttributeUpdater, ClientResource, ClientRepresentation> {
|
||||
|
||||
private final ClientResource clientResource;
|
||||
|
||||
private final ClientRepresentation rep;
|
||||
private final ClientRepresentation origRep;
|
||||
private final RealmResource realmResource;
|
||||
|
||||
public static ClientAttributeUpdater forClient(Keycloak adminClient, String realm, String clientId) {
|
||||
ClientsResource clients = adminClient.realm(realm).clients();
|
||||
RealmResource realmRes = adminClient.realm(realm);
|
||||
ClientsResource clients = realmRes.clients();
|
||||
List<ClientRepresentation> foundClients = clients.findByClientId(clientId);
|
||||
assertThat(foundClients, hasSize(1));
|
||||
ClientResource clientRes = clients.get(foundClients.get(0).getId());
|
||||
|
||||
return new ClientAttributeUpdater(clientRes);
|
||||
return new ClientAttributeUpdater(clientRes, realmRes);
|
||||
}
|
||||
|
||||
public ClientAttributeUpdater(ClientResource clientResource) {
|
||||
this.clientResource = clientResource;
|
||||
this.origRep = clientResource.toRepresentation();
|
||||
this.rep = clientResource.toRepresentation();
|
||||
private ClientAttributeUpdater(ClientResource resource, RealmResource realmResource) {
|
||||
super(resource, resource::toRepresentation, resource::update);
|
||||
if (this.rep.getAttributes() == null) {
|
||||
this.rep.setAttributes(new HashMap<>());
|
||||
}
|
||||
this.realmResource = realmResource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performUpdate(ClientRepresentation from, ClientRepresentation to) {
|
||||
super.performUpdate(from, to);
|
||||
updateViaAddRemove(from.getDefaultClientScopes(), to.getDefaultClientScopes(), this::getConversionForScopeNameToId, resource::addDefaultClientScope, resource::removeDefaultClientScope);
|
||||
updateViaAddRemove(from.getOptionalClientScopes(), to.getOptionalClientScopes(), this::getConversionForScopeNameToId, resource::addOptionalClientScope, resource::removeOptionalClientScope);
|
||||
}
|
||||
|
||||
private Function<String, String> getConversionForScopeNameToId() {
|
||||
Map<String, String> scopeNameToIdMap = realmResource.clientScopes().findAll().stream()
|
||||
.collect(Collectors.toMap(ClientScopeRepresentation::getName, ClientScopeRepresentation::getId));
|
||||
|
||||
return scopeNameToIdMap::get;
|
||||
}
|
||||
|
||||
public ClientAttributeUpdater setClientId(String clientId) {
|
||||
|
@ -64,9 +79,27 @@ public class ClientAttributeUpdater {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Closeable update() {
|
||||
clientResource.update(rep);
|
||||
|
||||
return () -> clientResource.update(origRep);
|
||||
public ClientAttributeUpdater setFullScopeAllowed(Boolean fullScopeAllowed) {
|
||||
rep.setFullScopeAllowed(fullScopeAllowed);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientAttributeUpdater setDefaultClientScopes(List<String> defaultClientScopes) {
|
||||
rep.setDefaultClientScopes(defaultClientScopes);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientAttributeUpdater setOptionalClientScopes(List<String> optionalClientScopes) {
|
||||
rep.setOptionalClientScopes(optionalClientScopes);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RoleScopeUpdater realmRoleScope() {
|
||||
return new RoleScopeUpdater(resource.getScopeMappings().realmLevel());
|
||||
}
|
||||
|
||||
public RoleScopeUpdater clientRoleScope(String clientUUID) {
|
||||
return new RoleScopeUpdater(resource.getScopeMappings().clientLevel(clientUUID));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,35 +2,22 @@ package org.keycloak.testsuite.updaters;
|
|||
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import java.io.Closeable;
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class RealmAttributeUpdater {
|
||||
public class RealmAttributeUpdater extends ServerResourceUpdater<ServerResourceUpdater, RealmResource, RealmRepresentation> {
|
||||
|
||||
private final RealmResource realmResource;
|
||||
|
||||
private final RealmRepresentation rep;
|
||||
private final RealmRepresentation origRep;
|
||||
|
||||
public RealmAttributeUpdater(RealmResource realmResource) {
|
||||
this.realmResource = realmResource;
|
||||
this.origRep = realmResource.toRepresentation();
|
||||
this.rep = realmResource.toRepresentation();
|
||||
public RealmAttributeUpdater(RealmResource resource) {
|
||||
super(resource, resource::toRepresentation, resource::update);
|
||||
if (this.rep.getAttributes() == null) {
|
||||
this.rep.setAttributes(new HashMap<>());
|
||||
}
|
||||
}
|
||||
|
||||
public RealmAttributeUpdater updateWith(Consumer<RealmRepresentation> updater) {
|
||||
updater.accept(this.rep);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RealmAttributeUpdater setAttribute(String name, String value) {
|
||||
this.rep.getAttributes().put(name, value);
|
||||
return this;
|
||||
|
@ -51,9 +38,9 @@ public class RealmAttributeUpdater {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Closeable update() {
|
||||
realmResource.update(rep);
|
||||
|
||||
return () -> realmResource.update(origRep);
|
||||
public RealmAttributeUpdater setDefaultDefaultClientScopes(List<String> defaultClientScopes) {
|
||||
rep.setDefaultDefaultClientScopes(defaultClientScopes);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2018 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.testsuite.updaters;
|
||||
|
||||
import org.keycloak.admin.client.resource.RoleScopeResource;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class RoleScopeUpdater extends ServerResourceUpdater<RoleScopeUpdater, RoleScopeResource, List<RoleRepresentation>> {
|
||||
|
||||
public RoleScopeUpdater(RoleScopeResource resource) {
|
||||
super(resource, resource::listAll, null);
|
||||
this.updater = this::update;
|
||||
}
|
||||
|
||||
public RoleScopeUpdater add(RoleRepresentation representation) {
|
||||
rep.add(representation);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RoleScopeUpdater remove(RoleRepresentation representation) {
|
||||
rep.add(representation);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void update(List<RoleRepresentation> expectedRoles) {
|
||||
List<RoleRepresentation> currentRoles = resource.listAll();
|
||||
|
||||
Set<String> currentRoleIds = currentRoles.stream().map(RoleRepresentation::getId).collect(Collectors.toSet());
|
||||
Set<String> expectedRoleIds = expectedRoles.stream().map(RoleRepresentation::getId).collect(Collectors.toSet());
|
||||
|
||||
List<RoleRepresentation> toAdd = expectedRoles.stream()
|
||||
.filter(role -> ! currentRoleIds.contains(role.getId()))
|
||||
.collect(Collectors.toList());
|
||||
List<RoleRepresentation> toRemove = currentRoles.stream()
|
||||
.filter(role -> ! expectedRoleIds.contains(role.getId()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
resource.add(toAdd);
|
||||
resource.remove(toRemove);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 2018 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.testsuite.updaters;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public abstract class ServerResourceUpdater<T extends ServerResourceUpdater, Res, Rep> implements Closeable {
|
||||
|
||||
protected final Res resource;
|
||||
protected final Rep rep;
|
||||
protected final Rep origRep;
|
||||
protected Consumer<Rep> updater;
|
||||
protected boolean updated = false;
|
||||
|
||||
public ServerResourceUpdater(Res resource, Supplier<Rep> representationGenerator, Consumer<Rep> updater) {
|
||||
this.resource = resource;
|
||||
this.updater = updater;
|
||||
|
||||
// origRep and rep need to be two different instances
|
||||
this.origRep = representationGenerator.get();
|
||||
this.rep = representationGenerator.get();
|
||||
}
|
||||
|
||||
public Res getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public T update() {
|
||||
performUpdate(origRep, rep);
|
||||
this.updated = true;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
protected void performUpdate(Rep from, Rep to) {
|
||||
updater.accept(to);
|
||||
}
|
||||
|
||||
public T updateWith(Consumer<Rep> representationUpdater) {
|
||||
representationUpdater.accept(this.rep);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (! this.updated) {
|
||||
throw new IOException("Attempt to revert changes that were never applied - have you called " + this.getClass().getName() + ".update()?");
|
||||
}
|
||||
performUpdate(rep, origRep);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function performs a set of single {@code add} and {@code remove} operations that represent the changes needed to
|
||||
* get collection {@code from} to the state of collection {@code to}. Since this is intended to work on collections of
|
||||
* names of objects but the {@code add} and {@code remove} functions operate on IDs of those objects, a conversion
|
||||
* is performed.
|
||||
*
|
||||
* @param <T> Type of the objects in the collections (e.g. names)
|
||||
* @param <V> Type of the objects required by add/remove functions (e.g. IDs)
|
||||
* @param from Initial collection
|
||||
* @param to Target collection
|
||||
* @param client2ServerConvertorGenerator Producer of the convertor. If not needed, just use {@code () -> Functions::identity}.
|
||||
* This is intentionally a lazy-evaluated function variable because the conversion map often needs to be obtained from the
|
||||
* server which can be slow operation. This function is called only if the two collections differ.
|
||||
* @param add Function to add
|
||||
* @param remove Function to remove
|
||||
*/
|
||||
public static <T, V> void updateViaAddRemove(Collection<T> from, Collection<T> to, Supplier<Function<T, V>> client2ServerConvertorGenerator, Consumer<V> add, Consumer<V> remove) {
|
||||
if (Objects.equals(from, to)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Function<T, V> client2ServerConvertor = client2ServerConvertorGenerator.get();
|
||||
|
||||
Set<V> current = from == null ? Collections.EMPTY_SET : from.stream().map(client2ServerConvertor).collect(Collectors.toSet());
|
||||
Set<V> expected = to == null ? Collections.EMPTY_SET : to.stream().map(client2ServerConvertor).collect(Collectors.toSet());
|
||||
|
||||
expected.stream()
|
||||
.filter(role -> ! current.contains(role))
|
||||
.forEach(add);
|
||||
current.stream()
|
||||
.filter(role -> ! expected.contains(role))
|
||||
.forEach(remove);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +1,37 @@
|
|||
package org.keycloak.testsuite.updaters;
|
||||
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.ClientsResource;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.admin.client.resource.UsersResource;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import java.io.Closeable;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class UserAttributeUpdater {
|
||||
public class UserAttributeUpdater extends ServerResourceUpdater<UserAttributeUpdater, UserResource, UserRepresentation> {
|
||||
|
||||
private final UserResource userResource;
|
||||
public static UserAttributeUpdater forUserByUsername(Keycloak adminClient, String realm, String userName) {
|
||||
UsersResource users = adminClient.realm(realm).users();
|
||||
List<UserRepresentation> foundUsers = users.search(userName);
|
||||
assertThat(foundUsers, hasSize(1));
|
||||
UserResource userRes = users.get(foundUsers.get(0).getId());
|
||||
|
||||
private final UserRepresentation rep;
|
||||
private final UserRepresentation origRep;
|
||||
return new UserAttributeUpdater(userRes);
|
||||
}
|
||||
|
||||
public UserAttributeUpdater(UserResource userResource) {
|
||||
this.userResource = userResource;
|
||||
this.origRep = userResource.toRepresentation();
|
||||
this.rep = userResource.toRepresentation();
|
||||
public UserAttributeUpdater(UserResource resource) {
|
||||
super(resource, resource::toRepresentation, resource::update);
|
||||
if (this.rep.getAttributes() == null) {
|
||||
this.rep.setAttributes(new HashMap<>());
|
||||
}
|
||||
|
@ -49,12 +57,6 @@ public class UserAttributeUpdater {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Closeable update() {
|
||||
userResource.update(rep);
|
||||
|
||||
return () -> userResource.update(origRep);
|
||||
}
|
||||
|
||||
public UserAttributeUpdater setRequiredActions(UserModel.RequiredAction... requiredAction) {
|
||||
rep.setRequiredActions(Arrays.stream(requiredAction)
|
||||
.map(action -> action.name())
|
||||
|
@ -62,4 +64,12 @@ public class UserAttributeUpdater {
|
|||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RoleScopeUpdater realmRoleScope() {
|
||||
return new RoleScopeUpdater(resource.roles().realmLevel());
|
||||
}
|
||||
|
||||
public RoleScopeUpdater clientRoleScope(String clientUUID) {
|
||||
return new RoleScopeUpdater(resource.roles().clientLevel(clientUUID));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,11 +57,16 @@ import org.keycloak.testsuite.pages.AppPage.RequestType;
|
|||
import org.keycloak.testsuite.pages.ErrorPage;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.pages.RegisterPage;
|
||||
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
|
||||
import org.keycloak.testsuite.updaters.RoleScopeUpdater;
|
||||
import org.keycloak.testsuite.util.IdentityProviderBuilder;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.RealmBuilder;
|
||||
import org.keycloak.testsuite.util.UIUtils;
|
||||
import org.keycloak.testsuite.util.UserBuilder;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
|
@ -86,6 +91,9 @@ import static org.junit.Assert.assertTrue;
|
|||
*/
|
||||
public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
public static final String ROOT_URL_CLIENT = "root-url-client";
|
||||
public static final String REALM_NAME = "test";
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
//UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost");
|
||||
|
@ -1067,7 +1075,50 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
events.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applicationsVisibilityNoScopesNoConsent() throws Exception {
|
||||
try (ClientAttributeUpdater cau = ClientAttributeUpdater.forClient(adminClient, REALM_NAME, ROOT_URL_CLIENT)
|
||||
.setConsentRequired(false)
|
||||
.setFullScopeAllowed(false)
|
||||
.setDefaultClientScopes(Collections.EMPTY_LIST)
|
||||
.setOptionalClientScopes(Collections.EMPTY_LIST)
|
||||
.update();
|
||||
RoleScopeUpdater rsu = cau.realmRoleScope().update()) {
|
||||
applicationsPage.open();
|
||||
loginPage.login("john-doh@localhost", "password");
|
||||
applicationsPage.assertCurrent();
|
||||
|
||||
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
|
||||
Assert.assertThat(apps.keySet(), containsInAnyOrder(
|
||||
/* "root-url-client", */ "Account", "test-app", "test-app-scope", "third-party", "test-app-authz", "My Named Test App", "Test App Named - ${client_account}", "direct-grant"));
|
||||
|
||||
rsu.add(testRealm().roles().get("user").toRepresentation())
|
||||
.update();
|
||||
|
||||
driver.navigate().refresh();
|
||||
apps = applicationsPage.getApplications();
|
||||
Assert.assertThat(apps.keySet(), containsInAnyOrder(
|
||||
"root-url-client", "Account", "test-app", "test-app-scope", "third-party", "test-app-authz", "My Named Test App", "Test App Named - ${client_account}", "direct-grant"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applicationsVisibilityNoScopesAndConsent() throws Exception {
|
||||
try (ClientAttributeUpdater cau = ClientAttributeUpdater.forClient(adminClient, REALM_NAME, ROOT_URL_CLIENT)
|
||||
.setConsentRequired(true)
|
||||
.setFullScopeAllowed(false)
|
||||
.setDefaultClientScopes(Collections.EMPTY_LIST)
|
||||
.setOptionalClientScopes(Collections.EMPTY_LIST)
|
||||
.update()) {
|
||||
applicationsPage.open();
|
||||
loginPage.login("john-doh@localhost", "password");
|
||||
applicationsPage.assertCurrent();
|
||||
|
||||
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
|
||||
Assert.assertThat(apps.keySet(), containsInAnyOrder(
|
||||
"root-url-client", "Account", "test-app", "test-app-scope", "third-party", "test-app-authz", "My Named Test App", "Test App Named - ${client_account}", "direct-grant"));
|
||||
}
|
||||
}
|
||||
|
||||
// More tests (including revoke) are in OAuthGrantTest and OfflineTokenTest
|
||||
@Test
|
||||
|
@ -1076,19 +1127,19 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=applications").assertEvent();
|
||||
Assert.assertTrue(applicationsPage.isCurrent());
|
||||
applicationsPage.assertCurrent();
|
||||
|
||||
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
|
||||
Assert.assertThat(apps.keySet(), containsInAnyOrder("root-url-client", "Account", "Broker", "test-app", "test-app-scope", "third-party", "test-app-authz", "My Named Test App", "Test App Named - ${client_account}", "direct-grant"));
|
||||
|
||||
AccountApplicationsPage.AppEntry accountEntry = apps.get("Account");
|
||||
Assert.assertEquals(4, accountEntry.getRolesAvailable().size());
|
||||
Assert.assertTrue(accountEntry.getRolesAvailable().contains("Manage account links in Account"));
|
||||
Assert.assertTrue(accountEntry.getRolesAvailable().contains("Manage account in Account"));
|
||||
Assert.assertTrue(accountEntry.getRolesAvailable().contains("View profile in Account"));
|
||||
Assert.assertTrue(accountEntry.getRolesAvailable().contains("Offline access"));
|
||||
Assert.assertEquals(1, accountEntry.getClientScopesGranted().size());
|
||||
Assert.assertTrue(accountEntry.getClientScopesGranted().contains("Full Access"));
|
||||
Assert.assertThat(accountEntry.getRolesAvailable(), containsInAnyOrder(
|
||||
"Manage account links in Account",
|
||||
"Manage account in Account",
|
||||
"View profile in Account",
|
||||
"Offline access"
|
||||
));
|
||||
Assert.assertThat(accountEntry.getClientScopesGranted(), containsInAnyOrder("Full Access"));
|
||||
Assert.assertEquals("http://localhost:8180/auth/realms/test/account", accountEntry.getHref());
|
||||
|
||||
AccountApplicationsPage.AppEntry testAppEntry = apps.get("test-app");
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.testsuite.pages.OAuthGrantPage;
|
|||
import org.keycloak.testsuite.util.ClientManager;
|
||||
import org.keycloak.testsuite.utils.io.IOUtil;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.openqa.selenium.By;
|
||||
|
||||
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
|
||||
|
@ -181,8 +182,8 @@ public class OfflineServletsAdapterTest extends AbstractServletsAdapterTest {
|
|||
|
||||
accountAppPage.open();
|
||||
AccountApplicationsPage.AppEntry offlineClient = accountAppPage.getApplications().get("offline-client");
|
||||
Assert.assertTrue(offlineClient.getClientScopesGranted().contains(OAuthGrantPage.OFFLINE_ACCESS_CONSENT_TEXT));
|
||||
Assert.assertTrue(offlineClient.getAdditionalGrants().contains("Offline Token"));
|
||||
Assert.assertThat(offlineClient.getClientScopesGranted(), Matchers.hasItem(OAuthGrantPage.OFFLINE_ACCESS_CONSENT_TEXT));
|
||||
Assert.assertThat(offlineClient.getAdditionalGrants(), Matchers.hasItem("Offline Token"));
|
||||
|
||||
//This was necessary to be introduced, otherwise other testcases will fail
|
||||
offlineTokenPage.logout();
|
||||
|
|
|
@ -818,8 +818,7 @@ public class SAMLServletAdapterTest extends AbstractServletsAdapterTest {
|
|||
|
||||
@Test
|
||||
public void salesPostEncSignedAssertionsAndDocumentTest() throws Exception {
|
||||
ClientRepresentation salesPostEncClient = testRealmResource().clients().findByClientId(SalesPostEncServlet.CLIENT_NAME).get(0);
|
||||
try (Closeable client = new ClientAttributeUpdater(testRealmResource().clients().get(salesPostEncClient.getId()))
|
||||
try (Closeable client = ClientAttributeUpdater.forClient(adminClient, testRealmPage.getAuthRealm(), SalesPostEncServlet.CLIENT_NAME)
|
||||
.setAttribute(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE, "true")
|
||||
.setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "true")
|
||||
.update()) {
|
||||
|
@ -831,8 +830,7 @@ public class SAMLServletAdapterTest extends AbstractServletsAdapterTest {
|
|||
|
||||
@Test
|
||||
public void salesPostEncRejectConsent() throws Exception {
|
||||
ClientRepresentation salesPostEncClient = testRealmResource().clients().findByClientId(SalesPostEncServlet.CLIENT_NAME).get(0);
|
||||
try (Closeable client = new ClientAttributeUpdater(testRealmResource().clients().get(salesPostEncClient.getId()))
|
||||
try (Closeable client = ClientAttributeUpdater.forClient(adminClient, testRealmPage.getAuthRealm(), SalesPostEncServlet.CLIENT_NAME)
|
||||
.setConsentRequired(true)
|
||||
.update()) {
|
||||
new SamlClientBuilder()
|
||||
|
@ -853,8 +851,7 @@ public class SAMLServletAdapterTest extends AbstractServletsAdapterTest {
|
|||
|
||||
@Test
|
||||
public void salesPostRejectConsent() throws Exception {
|
||||
ClientRepresentation salesPostClient = testRealmResource().clients().findByClientId(SalesPostServlet.CLIENT_NAME).get(0);
|
||||
try (Closeable client = new ClientAttributeUpdater(testRealmResource().clients().get(salesPostClient.getId()))
|
||||
try (Closeable client = ClientAttributeUpdater.forClient(adminClient, testRealmPage.getAuthRealm(), SalesPostServlet.CLIENT_NAME)
|
||||
.setConsentRequired(true)
|
||||
.update()) {
|
||||
new SamlClientBuilder()
|
||||
|
|
|
@ -117,14 +117,6 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
|||
}
|
||||
|
||||
public void withSignedEncryptedAssertions(Runnable testBody, boolean signedAssertion, boolean encryptedAssertion) throws Exception {
|
||||
ClientRepresentation client = adminClient.realm(bc.providerRealmName())
|
||||
.clients()
|
||||
.findByClientId(bc.getIDPClientIdInProviderRealm(suiteContext))
|
||||
.get(0);
|
||||
|
||||
final ClientResource clientResource = realmsResouce().realm(bc.providerRealmName()).clients().get(client.getId());
|
||||
Assert.assertThat(clientResource, Matchers.notNullValue());
|
||||
|
||||
String providerCert = KeyUtils.getActiveKey(adminClient.realm(bc.providerRealmName()).keys().getKeyMetadata(), Algorithm.RS256).getCertificate();
|
||||
Assert.assertThat(providerCert, Matchers.notNullValue());
|
||||
|
||||
|
@ -138,7 +130,7 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
|||
.setAttribute(SAMLIdentityProviderConfig.WANT_AUTHN_REQUESTS_SIGNED, "false")
|
||||
.setAttribute(SAMLIdentityProviderConfig.SIGNING_CERTIFICATE_KEY, providerCert)
|
||||
.update();
|
||||
Closeable clientUpdater = new ClientAttributeUpdater(clientResource)
|
||||
Closeable clientUpdater = ClientAttributeUpdater.forClient(adminClient, bc.providerRealmName(), bc.getIDPClientIdInProviderRealm(suiteContext))
|
||||
.setAttribute(SamlConfigAttributes.SAML_ENCRYPT, Boolean.toString(encryptedAssertion))
|
||||
.setAttribute(SamlConfigAttributes.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE, consumerCert)
|
||||
.setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "false") // only sign assertions
|
||||
|
@ -269,14 +261,6 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
|||
|
||||
@Test
|
||||
public void testWithExpiredBrokerCertificate() throws Exception {
|
||||
ClientRepresentation client = adminClient.realm(bc.providerRealmName())
|
||||
.clients()
|
||||
.findByClientId(bc.getIDPClientIdInProviderRealm(suiteContext))
|
||||
.get(0);
|
||||
|
||||
final ClientResource clientResource = realmsResouce().realm(bc.providerRealmName()).clients().get(client.getId());
|
||||
Assert.assertThat(clientResource, Matchers.notNullValue());
|
||||
|
||||
try (Closeable idpUpdater = new IdentityProviderAttributeUpdater(identityProviderResource)
|
||||
.setAttribute(SAMLIdentityProviderConfig.VALIDATE_SIGNATURE, Boolean.toString(true))
|
||||
.setAttribute(SAMLIdentityProviderConfig.WANT_ASSERTIONS_SIGNED, Boolean.toString(true))
|
||||
|
@ -284,7 +268,7 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
|||
.setAttribute(SAMLIdentityProviderConfig.WANT_AUTHN_REQUESTS_SIGNED, "true")
|
||||
.setAttribute(SAMLIdentityProviderConfig.SIGNING_CERTIFICATE_KEY, AbstractSamlTest.SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE)
|
||||
.update();
|
||||
Closeable clientUpdater = new ClientAttributeUpdater(clientResource)
|
||||
Closeable clientUpdater = ClientAttributeUpdater.forClient(adminClient, bc.providerRealmName(), bc.getIDPClientIdInProviderRealm(suiteContext))
|
||||
.setAttribute(SamlConfigAttributes.SAML_ENCRYPT, Boolean.toString(false))
|
||||
.setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "true")
|
||||
.setAttribute(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE, Boolean.toString(true))
|
||||
|
|
|
@ -244,11 +244,8 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest {
|
|||
// KEYCLOAK-5982
|
||||
@Test
|
||||
public void testLogoutWhenAccountClientRenamed() throws IOException {
|
||||
// Rename client "account"
|
||||
ClientResource accountClient = ApiUtil.findClientByClientId(adminClient.realm("test"), Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||
|
||||
// Temporarily rename client "account" . Revert it back after the test
|
||||
try (Closeable accountClientUpdater = new ClientAttributeUpdater(accountClient)
|
||||
try (Closeable accountClientUpdater = ClientAttributeUpdater.forClient(adminClient, "test", Constants.ACCOUNT_MANAGEMENT_CLIENT_ID)
|
||||
.setClientId("account-changed")
|
||||
.update()) {
|
||||
|
||||
|
|
|
@ -1011,10 +1011,8 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest {
|
|||
// KEYCLOAK-5982
|
||||
@Test
|
||||
public void resetPasswordLinkOpenedInNewBrowserAndAccountClientRenamed() throws IOException, MessagingException {
|
||||
ClientResource accountClient = ApiUtil.findClientByClientId(adminClient.realm("test"), Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||
|
||||
// Temporarily rename client "account" . Revert it back after the test
|
||||
try (Closeable accountClientUpdater = new ClientAttributeUpdater(accountClient)
|
||||
try (Closeable accountClientUpdater = ClientAttributeUpdater.forClient(adminClient, "test", Constants.ACCOUNT_MANAGEMENT_CLIENT_ID)
|
||||
.setClientId("account-changed")
|
||||
.update()) {
|
||||
|
||||
|
|
|
@ -59,12 +59,7 @@ public class IncludeOneTimeUseConditionTest extends AbstractSamlTest
|
|||
|
||||
private void testOneTimeUseConditionIncluded(Boolean oneTimeUseConditionShouldBeIncluded) throws IOException
|
||||
{
|
||||
ClientsResource clients = adminClient.realm(REALM_NAME).clients();
|
||||
List<ClientRepresentation> foundClients = clients.findByClientId(SAML_CLIENT_ID_SALES_POST);
|
||||
assertThat(foundClients, hasSize(1));
|
||||
ClientResource clientRes = clients.get(foundClients.get(0).getId());
|
||||
|
||||
try (Closeable c = new ClientAttributeUpdater(clientRes)
|
||||
try (Closeable c = ClientAttributeUpdater.forClient(adminClient, REALM_NAME, SAML_CLIENT_ID_SALES_POST)
|
||||
.setAttribute(SamlConfigAttributes.SAML_ONETIMEUSE_CONDITION, oneTimeUseConditionShouldBeIncluded.toString())
|
||||
.update()) {
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.keycloak.testsuite.saml;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientsResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.broker.saml.SAMLIdentityProviderConfig;
|
||||
import org.keycloak.broker.saml.SAMLIdentityProviderFactory;
|
||||
|
@ -361,10 +360,9 @@ public class LogoutTest extends AbstractSamlTest {
|
|||
@Test
|
||||
public void testLogoutPropagatesToSamlIdentityProvider() throws IOException {
|
||||
final RealmResource realm = adminClient.realm(REALM_NAME);
|
||||
final ClientsResource clients = realm.clients();
|
||||
|
||||
try (
|
||||
Closeable sales = new ClientAttributeUpdater(clients.get(salesRep.getId()))
|
||||
Closeable sales = ClientAttributeUpdater.forClient(adminClient, REALM_NAME, SAML_CLIENT_ID_SALES_POST)
|
||||
.setFrontchannelLogout(true)
|
||||
.removeAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE)
|
||||
.setAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE, "http://url")
|
||||
|
|
Loading…
Reference in a new issue