Merge pull request #4320 from patriot1burke/master

KEYCLOAK-5155
This commit is contained in:
Bill Burke 2017-07-13 17:23:53 -04:00 committed by GitHub
commit 286fb688eb
5 changed files with 110 additions and 10 deletions

View file

@ -19,6 +19,7 @@ package org.keycloak.forms.account.freemarker.model;
import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
@ -27,8 +28,10 @@ import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.protocol.oidc.TokenManager; import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.services.managers.UserSessionManager; import org.keycloak.services.managers.UserSessionManager;
import org.keycloak.services.resources.admin.permissions.AdminPermissions;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -51,11 +54,18 @@ public class ApplicationsBean {
continue; continue;
} }
Set<RoleModel> availableRoles = TokenManager.getAccess(null, false, client, user); Set<RoleModel> availableRoles = new HashSet<>();
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;
} else {
availableRoles = TokenManager.getAccess(null, false, client, user);
// Don't show applications, which user doesn't have access into (any available roles) // Don't show applications, which user doesn't have access into (any available roles)
if (availableRoles.isEmpty()) { if (availableRoles.isEmpty()) {
continue; continue;
} }
}
List<RoleModel> realmRolesAvailable = new LinkedList<RoleModel>(); List<RoleModel> realmRolesAvailable = new LinkedList<RoleModel>();
MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable = new MultivaluedHashMap<String, ClientRoleEntry>(); MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable = new MultivaluedHashMap<String, ClientRoleEntry>();
processRoles(availableRoles, realmRolesAvailable, resourceRolesAvailable); processRoles(availableRoles, realmRolesAvailable, resourceRolesAvailable);

View file

@ -46,6 +46,10 @@ public class AdminPermissions {
return new MgmtPermissions(session, auth); return new MgmtPermissions(session, auth);
} }
public static RealmsPermissionEvaluator realms(KeycloakSession session, RealmModel adminsRealm, UserModel admin) {
return new MgmtPermissions(session, adminsRealm, admin);
}
public static AdminPermissionManagement management(KeycloakSession session, RealmModel realm) { public static AdminPermissionManagement management(KeycloakSession session, RealmModel realm) {
return new MgmtPermissions(session, realm); return new MgmtPermissions(session, realm);
} }

View file

@ -107,6 +107,14 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
this.identity = new KeycloakIdentity(auth.getToken(), session); this.identity = new KeycloakIdentity(auth.getToken(), session);
} }
} }
MgmtPermissions(KeycloakSession session, RealmModel adminsRealm, UserModel admin) {
this.session = session;
this.admin = admin;
this.adminsRealm = adminsRealm;
this.identity = new UserModelIdentity(adminsRealm, admin);
}
MgmtPermissions(KeycloakSession session, RealmModel realm, RealmModel adminsRealm, UserModel admin) { MgmtPermissions(KeycloakSession session, RealmModel realm, RealmModel adminsRealm, UserModel admin) {
this(session, realm); this(session, realm);
this.admin = admin; this.admin = admin;

View file

@ -28,6 +28,9 @@ import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.events.Details; import org.keycloak.events.Details;
import org.keycloak.events.Errors; import org.keycloak.events.Errors;
import org.keycloak.events.EventType; import org.keycloak.events.EventType;
import org.keycloak.models.AccountRoles;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.Constants;
import org.keycloak.models.PasswordPolicy; import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
@ -83,6 +86,13 @@ public class AccountTest extends AbstractTestRealmKeycloakTest {
.email("test-user-no-access@localhost") .email("test-user-no-access@localhost")
.password("password") .password("password")
.build(); .build();
UserRepresentation realmAdmin = UserBuilder.create()
.enabled(true)
.username("realm-admin")
.password("password")
.role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN)
.role(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID, AccountRoles.MANAGE_ACCOUNT)
.build();
testRealm.addIdentityProvider(IdentityProviderBuilder.create() testRealm.addIdentityProvider(IdentityProviderBuilder.create()
.providerId("github") .providerId("github")
@ -105,7 +115,8 @@ public class AccountTest extends AbstractTestRealmKeycloakTest {
.build()); .build());
RealmBuilder.edit(testRealm) RealmBuilder.edit(testRealm)
.user(user2); .user(user2)
.user(realmAdmin);
} }
private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8180/auth"); private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8180/auth");
@ -870,6 +881,19 @@ public class AccountTest extends AbstractTestRealmKeycloakTest {
} }
} }
// KEYCLOAK-5155
@Test
public void testConsoleListedInApplications() {
applicationsPage.open();
loginPage.login("realm-admin", "password");
Assert.assertTrue(applicationsPage.isCurrent());
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
Assert.assertThat(apps.keySet(), hasItems("Admin CLI", "Security Admin Console"));
events.clear();
}
// More tests (including revoke) are in OAuthGrantTest and OfflineTokenTest // More tests (including revoke) are in OAuthGrantTest and OfflineTokenTest
@Test @Test
public void applications() { public void applications() {

View file

@ -648,6 +648,60 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
} }
} }
// KEYCLOAK-5152
@Test
public void testMasterRealmWithComposites() throws Exception {
RoleRepresentation composite = new RoleRepresentation();
composite.setName("composite");
composite.setComposite(true);
adminClient.realm(TEST).roles().create(composite);
composite = adminClient.realm(TEST).roles().get("composite").toRepresentation();
RoleRepresentation compositePart = new RoleRepresentation();
compositePart.setName("composite-part");
adminClient.realm(TEST).roles().create(compositePart);
compositePart = adminClient.realm(TEST).roles().get("composite-part").toRepresentation();
List<RoleRepresentation> composites = new LinkedList<>();
composites.add(compositePart);
adminClient.realm(TEST).rolesById().addComposites(composite.getId(), composites);
}
public static void setup5152(KeycloakSession session) {
RealmModel realm = session.realms().getRealmByName(TEST);
ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
RoleModel realmAdminRole = realmAdminClient.getRole(AdminRoles.REALM_ADMIN);
UserModel realmUser = session.users().addUser(realm, "realm-admin");
realmUser.grantRole(realmAdminRole);
realmUser.setEnabled(true);
session.userCredentialManager().updateCredential(realm, realmUser, UserCredentialModel.password("password"));
}
// KEYCLOAK-5152
@Test
public void testRealmWithComposites() throws Exception {
testingClient.server().run(FineGrainAdminUnitTest::setup5152);
Keycloak realmClient = AdminClientUtil.createAdminClient(suiteContext.isAdapterCompatTesting(),
TEST, "realm-admin", "password", Constants.ADMIN_CLI_CLIENT_ID, null);
RoleRepresentation composite = new RoleRepresentation();
composite.setName("composite");
composite.setComposite(true);
realmClient.realm(TEST).roles().create(composite);
composite = adminClient.realm(TEST).roles().get("composite").toRepresentation();
RoleRepresentation compositePart = new RoleRepresentation();
compositePart.setName("composite-part");
realmClient.realm(TEST).roles().create(compositePart);
compositePart = adminClient.realm(TEST).roles().get("composite-part").toRepresentation();
List<RoleRepresentation> composites = new LinkedList<>();
composites.add(compositePart);
realmClient.realm(TEST).rolesById().addComposites(composite.getId(), composites);
}
// testRestEvaluationMasterRealm // testRestEvaluationMasterRealm
// testRestEvaluationMasterAdminTestRealm // testRestEvaluationMasterAdminTestRealm