Merge pull request #375 from patriot1burke/master
per-realm admin console
This commit is contained in:
commit
a4cb268703
18 changed files with 217 additions and 77 deletions
|
@ -57,6 +57,7 @@ public class RealmRepresentation {
|
|||
protected List<AuthenticationProviderRepresentation> authenticationProviders;
|
||||
protected String loginTheme;
|
||||
protected String accountTheme;
|
||||
protected String adminTheme;
|
||||
protected boolean auditEnabled;
|
||||
protected long auditExpiration;
|
||||
protected List<String> auditListeners;
|
||||
|
@ -377,6 +378,14 @@ public class RealmRepresentation {
|
|||
this.accountTheme = accountTheme;
|
||||
}
|
||||
|
||||
public String getAdminTheme() {
|
||||
return adminTheme;
|
||||
}
|
||||
|
||||
public void setAdminTheme(String adminTheme) {
|
||||
this.adminTheme = adminTheme;
|
||||
}
|
||||
|
||||
public Integer getNotBefore() {
|
||||
return notBefore;
|
||||
}
|
||||
|
|
2
export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java
Normal file → Executable file
2
export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java
Normal file → Executable file
|
@ -73,7 +73,7 @@ public class ModelExporter {
|
|||
this.propertiesManager.setBasicPropertiesFromModel(realmModel, entity);
|
||||
|
||||
// Export 'advanced' properties
|
||||
ApplicationModel realmAdminApp = realmModel.getAdminApp();
|
||||
ApplicationModel realmAdminApp = realmModel.getMasterAdminApp();
|
||||
if (realmAdminApp != null) {
|
||||
entity.setAdminAppId(realmAdminApp.getId());
|
||||
}
|
||||
|
|
2
export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java
Normal file → Executable file
2
export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java
Normal file → Executable file
|
@ -182,7 +182,7 @@ public class ModelImporter {
|
|||
// admin app
|
||||
String adminAppId = realmEntity.getAdminAppId();
|
||||
if (adminAppId != null) {
|
||||
realm.setAdminApp(adminRealm.getApplicationById(adminAppId));
|
||||
realm.setMasterAdminApp(adminRealm.getApplicationById(adminAppId));
|
||||
}
|
||||
|
||||
// Default roles
|
||||
|
|
|
@ -99,6 +99,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="adminTheme">Admin Console Theme</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="select-kc">
|
||||
<select id="adminTheme"
|
||||
ng-model="realm.adminTheme"
|
||||
ng-options="o as o for o in serverInfo.themes.admin">
|
||||
<option value="" disabled selected>Select one...</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="pull-right form-actions" data-ng-show="createRealm && access.manageRealm">
|
||||
|
|
3
model/api/src/main/java/org/keycloak/models/AdminRoles.java
Normal file → Executable file
3
model/api/src/main/java/org/keycloak/models/AdminRoles.java
Normal file → Executable file
|
@ -9,6 +9,9 @@ public class AdminRoles {
|
|||
|
||||
public static String ADMIN = "admin";
|
||||
|
||||
// for admin application local to each realm
|
||||
public static String REALM_ADMIN = "realm-admin";
|
||||
|
||||
public static String CREATE_REALM = "create-realm";
|
||||
|
||||
public static String VIEW_REALM = "view-realm";
|
||||
|
|
|
@ -220,6 +220,10 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
|
|||
|
||||
void setAccountTheme(String name);
|
||||
|
||||
String getAdminTheme();
|
||||
|
||||
void setAdminTheme(String name);
|
||||
|
||||
boolean hasScope(ClientModel client, RoleModel role);
|
||||
|
||||
/**
|
||||
|
@ -245,9 +249,9 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
|
|||
|
||||
void setAuditListeners(Set<String> listeners);
|
||||
|
||||
ApplicationModel getAdminApp();
|
||||
ApplicationModel getMasterAdminApp();
|
||||
|
||||
void setAdminApp(ApplicationModel app);
|
||||
void setMasterAdminApp(ApplicationModel app);
|
||||
|
||||
UserSessionModel createUserSession(UserModel user, String ipAddress);
|
||||
|
||||
|
|
9
model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
Normal file → Executable file
9
model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
Normal file → Executable file
|
@ -42,6 +42,7 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
|||
|
||||
private String loginTheme;
|
||||
private String accountTheme;
|
||||
private String adminTheme;
|
||||
|
||||
// We are using names of defaultRoles (not ids)
|
||||
private List<String> defaultRoles = new ArrayList<String>();
|
||||
|
@ -275,6 +276,14 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
|||
this.accountTheme = accountTheme;
|
||||
}
|
||||
|
||||
public String getAdminTheme() {
|
||||
return adminTheme;
|
||||
}
|
||||
|
||||
public void setAdminTheme(String adminTheme) {
|
||||
this.adminTheme = adminTheme;
|
||||
}
|
||||
|
||||
public List<String> getDefaultRoles() {
|
||||
return defaultRoles;
|
||||
}
|
||||
|
|
|
@ -1328,6 +1328,17 @@ public class RealmAdapter implements RealmModel {
|
|||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdminTheme() {
|
||||
return realm.getAdminTheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdminTheme(String name) {
|
||||
realm.setAdminTheme(name);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuditEnabled() {
|
||||
return realm.isAuditEnabled();
|
||||
|
@ -1362,13 +1373,13 @@ public class RealmAdapter implements RealmModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ApplicationModel getAdminApp() {
|
||||
return new ApplicationAdapter(this, em, realm.getAdminApp());
|
||||
public ApplicationModel getMasterAdminApp() {
|
||||
return new ApplicationAdapter(this, em, realm.getMasterAdminApp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdminApp(ApplicationModel app) {
|
||||
realm.setAdminApp(((ApplicationAdapter) app).getJpaEntity());
|
||||
public void setMasterAdminApp(ApplicationModel app) {
|
||||
realm.setMasterAdminApp(((ApplicationAdapter) app).getJpaEntity());
|
||||
em.flush();
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ public class RealmEntity {
|
|||
|
||||
protected String loginTheme;
|
||||
protected String accountTheme;
|
||||
protected String adminTheme;
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
@JoinTable(name="User_RequiredCreds")
|
||||
|
@ -109,16 +110,16 @@ public class RealmEntity {
|
|||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
@JoinTable(name="RealmDefaultRoles")
|
||||
Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
|
||||
protected Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
|
||||
|
||||
private boolean auditEnabled;
|
||||
private long auditExpiration;
|
||||
protected boolean auditEnabled;
|
||||
protected long auditExpiration;
|
||||
|
||||
@ElementCollection
|
||||
private Set<String> auditListeners= new HashSet<String>();
|
||||
protected Set<String> auditListeners= new HashSet<String>();
|
||||
|
||||
@OneToOne
|
||||
private ApplicationEntity adminApp;
|
||||
protected ApplicationEntity masterAdminApp;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
@ -351,6 +352,14 @@ public class RealmEntity {
|
|||
this.accountTheme = theme;
|
||||
}
|
||||
|
||||
public String getAdminTheme() {
|
||||
return adminTheme;
|
||||
}
|
||||
|
||||
public void setAdminTheme(String adminTheme) {
|
||||
this.adminTheme = adminTheme;
|
||||
}
|
||||
|
||||
public int getNotBefore() {
|
||||
return notBefore;
|
||||
}
|
||||
|
@ -439,12 +448,12 @@ public class RealmEntity {
|
|||
this.auditListeners = auditListeners;
|
||||
}
|
||||
|
||||
public ApplicationEntity getAdminApp() {
|
||||
return adminApp;
|
||||
public ApplicationEntity getMasterAdminApp() {
|
||||
return masterAdminApp;
|
||||
}
|
||||
|
||||
public void setAdminApp(ApplicationEntity adminApp) {
|
||||
this.adminApp = adminApp;
|
||||
public void setMasterAdminApp(ApplicationEntity masterAdminApp) {
|
||||
this.masterAdminApp = masterAdminApp;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -409,6 +409,17 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdminTheme() {
|
||||
return realm.getAdminTheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdminTheme(String name) {
|
||||
realm.setAdminTheme(name);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAdapter getUser(String name) {
|
||||
DBObject query = new QueryBuilder()
|
||||
|
@ -1322,13 +1333,13 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
}
|
||||
|
||||
@Override
|
||||
public ApplicationModel getAdminApp() {
|
||||
public ApplicationModel getMasterAdminApp() {
|
||||
MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, realm.getAdminAppId(), invocationContext);
|
||||
return appData != null ? new ApplicationAdapter(this, appData, invocationContext) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdminApp(ApplicationModel app) {
|
||||
public void setMasterAdminApp(ApplicationModel app) {
|
||||
realm.setAdminAppId(app.getId());
|
||||
updateRealm();
|
||||
}
|
||||
|
|
|
@ -77,7 +77,10 @@ public class ImportTest extends AbstractModelTest {
|
|||
Assert.assertEquals(0, realm.getSocialLinks(user).size());
|
||||
|
||||
List<ApplicationModel> resources = realm.getApplications();
|
||||
Assert.assertEquals(3, resources.size());
|
||||
for (ApplicationModel app : resources) {
|
||||
System.out.println("app: " + app.getName());
|
||||
}
|
||||
Assert.assertEquals(5, resources.size());
|
||||
|
||||
// Test applications imported
|
||||
ApplicationModel application = realm.getApplicationByName("Application");
|
||||
|
@ -88,7 +91,7 @@ public class ImportTest extends AbstractModelTest {
|
|||
Assert.assertNotNull(otherApp);
|
||||
Assert.assertNull(nonExisting);
|
||||
Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
|
||||
Assert.assertEquals(3, apps.size());
|
||||
Assert.assertEquals(5, apps.size());
|
||||
Assert.assertTrue(apps.values().contains(application));
|
||||
Assert.assertTrue(apps.values().contains(otherApp));
|
||||
Assert.assertTrue(apps.values().contains(accountApp));
|
||||
|
|
|
@ -49,6 +49,7 @@ public class ApplianceBootstrap {
|
|||
logger.info("Initializing " + adminRealmName + " realm");
|
||||
|
||||
RealmManager manager = new RealmManager(session);
|
||||
manager.setContextPath(contextPath);
|
||||
RealmModel realm = manager.createRealm(adminRealmName, adminRealmName);
|
||||
realm.setName(adminRealmName);
|
||||
realm.setEnabled(true);
|
||||
|
@ -63,18 +64,8 @@ public class ApplianceBootstrap {
|
|||
manager.generateRealmKeys(realm);
|
||||
realm.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
|
||||
|
||||
ApplicationModel adminConsole = new ApplicationManager(manager).createApplication(realm, Constants.ADMIN_CONSOLE_APPLICATION);
|
||||
adminConsole.setBaseUrl(contextPath + "/admin/index.html");
|
||||
adminConsole.setEnabled(true);
|
||||
adminConsole.setPublicClient(true);
|
||||
adminConsole.addRedirectUri(contextPath + "/admin/" + realm.getName() + "/console/*");
|
||||
|
||||
realm.setAuditListeners(Collections.singleton("jboss-logging"));
|
||||
|
||||
RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
|
||||
|
||||
realm.addScopeMapping(adminConsole, adminRole);
|
||||
|
||||
UserModel adminUser = realm.addUser("admin");
|
||||
adminUser.setEnabled(true);
|
||||
UserCredentialModel password = new UserCredentialModel();
|
||||
|
@ -83,6 +74,7 @@ public class ApplianceBootstrap {
|
|||
realm.updateCredential(adminUser, password);
|
||||
adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||
|
||||
RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
|
||||
realm.grantRole(adminUser, adminRole);
|
||||
|
||||
ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
|
||||
|
|
|
@ -99,6 +99,7 @@ public class ModelToRepresentation {
|
|||
rep.setLdapServer(realm.getLdapServerConfig());
|
||||
rep.setAccountTheme(realm.getAccountTheme());
|
||||
rep.setLoginTheme(realm.getLoginTheme());
|
||||
rep.setAdminTheme(realm.getAdminTheme());
|
||||
if (realm.getPasswordPolicy() != null) {
|
||||
rep.setPasswordPolicy(realm.getPasswordPolicy().toString());
|
||||
}
|
||||
|
|
|
@ -54,6 +54,15 @@ public class RealmManager {
|
|||
protected static final Logger logger = Logger.getLogger(RealmManager.class);
|
||||
|
||||
protected KeycloakSession identitySession;
|
||||
protected String contextPath = "";
|
||||
|
||||
public String getContextPath() {
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
public void setContextPath(String contextPath) {
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
public RealmManager(KeycloakSession identitySession) {
|
||||
this.identitySession = identitySession;
|
||||
|
@ -83,14 +92,39 @@ public class RealmManager {
|
|||
// setup defaults
|
||||
setupRealmDefaults(realm);
|
||||
|
||||
setupAdminManagement(realm);
|
||||
setupMasterAdminManagement(realm);
|
||||
setupRealmAdminManagement(realm);
|
||||
setupAccountManagement(realm);
|
||||
setupAdminConsole(realm);
|
||||
|
||||
realm.setAuditListeners(Collections.singleton("jboss-logging"));
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
protected void setupAdminConsole(RealmModel realm) {
|
||||
ApplicationModel adminConsole = new ApplicationManager(this).createApplication(realm, Constants.ADMIN_CONSOLE_APPLICATION);
|
||||
String baseUrl = contextPath + "/admin/" + realm.getName() + "/console";
|
||||
adminConsole.setBaseUrl(baseUrl + "/index.html");
|
||||
adminConsole.setEnabled(true);
|
||||
adminConsole.setPublicClient(true);
|
||||
adminConsole.addRedirectUri(baseUrl + "/*");
|
||||
|
||||
RoleModel adminRole;
|
||||
if (realm.getName().equals(Config.getAdminRealm())) {
|
||||
adminRole = realm.getRole(AdminRoles.ADMIN);
|
||||
} else {
|
||||
ApplicationModel realmApp = realm.getApplicationByName(getRealmAdminApplicationName(realm));
|
||||
adminRole = realmApp.getRole(AdminRoles.REALM_ADMIN);
|
||||
|
||||
}
|
||||
realm.addScopeMapping(adminConsole, adminRole);
|
||||
}
|
||||
|
||||
public String getRealmAdminApplicationName(RealmModel realm) {
|
||||
return realm.getName() + "-realm";
|
||||
}
|
||||
|
||||
protected void setupRealmDefaults(RealmModel realm) {
|
||||
// brute force
|
||||
realm.setBruteForceProtected(false); // default settings off for now todo set it on
|
||||
|
@ -105,7 +139,7 @@ public class RealmManager {
|
|||
public boolean removeRealm(RealmModel realm) {
|
||||
boolean removed = identitySession.removeRealm(realm.getId());
|
||||
if (removed) {
|
||||
getKeycloakAdminstrationRealm().removeApplication(realm.getAdminApp().getId());
|
||||
getKeycloakAdminstrationRealm().removeApplication(realm.getMasterAdminApp().getId());
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
@ -153,6 +187,7 @@ public class RealmManager {
|
|||
}
|
||||
if (rep.getLoginTheme() != null) realm.setLoginTheme(rep.getLoginTheme());
|
||||
if (rep.getAccountTheme() != null) realm.setAccountTheme(rep.getAccountTheme());
|
||||
if (rep.getAdminTheme() != null) realm.setAdminTheme(rep.getAdminTheme());
|
||||
|
||||
if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
|
||||
|
||||
|
@ -189,7 +224,7 @@ public class RealmManager {
|
|||
}
|
||||
}
|
||||
|
||||
private void setupAdminManagement(RealmModel realm) {
|
||||
private void setupMasterAdminManagement(RealmModel realm) {
|
||||
RealmModel adminRealm;
|
||||
RoleModel adminRole;
|
||||
|
||||
|
@ -207,9 +242,9 @@ public class RealmManager {
|
|||
|
||||
ApplicationManager applicationManager = new ApplicationManager(new RealmManager(identitySession));
|
||||
|
||||
ApplicationModel realmAdminApp = applicationManager.createApplication(adminRealm, realm.getName() + "-realm");
|
||||
ApplicationModel realmAdminApp = applicationManager.createApplication(adminRealm, getRealmAdminApplicationName(realm));
|
||||
realmAdminApp.setBearerOnly(true);
|
||||
realm.setAdminApp(realmAdminApp);
|
||||
realm.setMasterAdminApp(realmAdminApp);
|
||||
|
||||
for (String r : AdminRoles.ALL_REALM_ROLES) {
|
||||
RoleModel role = realmAdminApp.addRole(r);
|
||||
|
@ -217,6 +252,22 @@ public class RealmManager {
|
|||
}
|
||||
}
|
||||
|
||||
private void setupRealmAdminManagement(RealmModel realm) {
|
||||
if (realm.getName().equals(Config.getAdminRealm())) { return; } // don't need to do this for master realm
|
||||
|
||||
ApplicationManager applicationManager = new ApplicationManager(new RealmManager(identitySession));
|
||||
|
||||
ApplicationModel realmAdminApp = applicationManager.createApplication(realm, getRealmAdminApplicationName(realm));
|
||||
RoleModel adminRole = realmAdminApp.addRole(AdminRoles.REALM_ADMIN);
|
||||
realmAdminApp.setBearerOnly(true);
|
||||
|
||||
for (String r : AdminRoles.ALL_REALM_ROLES) {
|
||||
RoleModel role = realmAdminApp.addRole(r);
|
||||
adminRole.addCompositeRole(role);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setupAccountManagement(RealmModel realm) {
|
||||
ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
|
||||
if (application == null) {
|
||||
|
@ -283,6 +334,7 @@ public class RealmManager {
|
|||
}
|
||||
if (rep.getLoginTheme() != null) newRealm.setLoginTheme(rep.getLoginTheme());
|
||||
if (rep.getAccountTheme() != null) newRealm.setAccountTheme(rep.getAccountTheme());
|
||||
if (rep.getAdminTheme() != null) newRealm.setAdminTheme(rep.getAccountTheme());
|
||||
|
||||
Map<String, UserModel> userMap = new HashMap<String, UserModel>();
|
||||
|
||||
|
|
|
@ -219,6 +219,7 @@ public class KeycloakApplication extends Application {
|
|||
try {
|
||||
session.getTransaction().begin();
|
||||
RealmManager manager = new RealmManager(session);
|
||||
manager.setContextPath(getContextPath());
|
||||
|
||||
if (rep.getId() != null && manager.getRealm(rep.getId()) != null) {
|
||||
log.info("Not importing realm " + rep.getRealm() + " from " + from + ". It already exists.");
|
||||
|
|
|
@ -6,12 +6,8 @@ import org.jboss.resteasy.annotations.cache.NoCache;
|
|||
import org.jboss.resteasy.spi.HttpRequest;
|
||||
import org.jboss.resteasy.spi.HttpResponse;
|
||||
import org.jboss.resteasy.spi.NotFoundException;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.jboss.resteasy.spi.UnauthorizedException;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.freemarker.Theme;
|
||||
import org.keycloak.freemarker.ThemeLoader;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.models.AdminRoles;
|
||||
import org.keycloak.models.ApplicationModel;
|
||||
import org.keycloak.models.Config;
|
||||
|
@ -21,17 +17,12 @@ import org.keycloak.models.RealmModel;
|
|||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.ProviderSession;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.services.ForbiddenException;
|
||||
import org.keycloak.services.managers.AppAuthManager;
|
||||
import org.keycloak.services.managers.ApplicationManager;
|
||||
import org.keycloak.services.managers.Auth;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.managers.TokenManager;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.services.resources.TokenService;
|
||||
import org.keycloak.services.resources.flows.Flows;
|
||||
import org.keycloak.services.resources.flows.OAuthRedirect;
|
||||
|
||||
import javax.activation.FileTypeMap;
|
||||
import javax.activation.MimetypesFileTypeMap;
|
||||
|
@ -39,19 +30,17 @@ import javax.ws.rs.GET;
|
|||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import javax.ws.rs.ext.Providers;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -182,7 +171,7 @@ public class AdminConsole {
|
|||
return Response.status(401).build();
|
||||
}
|
||||
String displayName;
|
||||
if (user.getFirstName() != null || user.getLastName() != null) {
|
||||
if ((user.getFirstName() != null && !user.getFirstName().trim().equals("")) || (user.getLastName() != null && !user.getLastName().trim().equals(""))) {
|
||||
displayName = user.getFirstName();
|
||||
if (user.getLastName() != null) {
|
||||
displayName = displayName != null ? displayName + " " + user.getLastName() : user.getLastName();
|
||||
|
@ -192,41 +181,55 @@ public class AdminConsole {
|
|||
}
|
||||
|
||||
RealmModel masterRealm = getAdminstrationRealm(realmManager);
|
||||
Map<String, Set<String>> realmAccess = new HashMap<String, Set<String>>();
|
||||
if (masterRealm == null)
|
||||
throw new NotFoundException("No realm found");
|
||||
boolean createRealm = false;
|
||||
if (realm.equals(masterRealm)) {
|
||||
logger.info("setting up realm access for a master realm user");
|
||||
createRealm = masterRealm.hasRole(user, masterRealm.getRole(AdminRoles.CREATE_REALM));
|
||||
addMasterRealmAccess(realm, user, realmAccess);
|
||||
} else {
|
||||
logger.info("setting up realm access for a realm user");
|
||||
addRealmAccess(realm, user, realmAccess);
|
||||
}
|
||||
if (realmAccess.size() == 0) {
|
||||
return Response.status(401).build();
|
||||
}
|
||||
|
||||
Map<String, Set<String>> realmAccess = new HashMap<String, Set<String>>();
|
||||
addRealmAdminAccess(realmAccess, realm.getRoleMappings(user));
|
||||
|
||||
return Response.ok(new WhoAmI(user.getId(), realm.getName(), displayName, createRealm, realmAccess)).build();
|
||||
}
|
||||
|
||||
private void addRealmAdminAccess(Map<String, Set<String>> realmAdminAccess, Set<RoleModel> roles) {
|
||||
for (RoleModel r : roles) {
|
||||
if (r.getContainer() instanceof ApplicationModel) {
|
||||
ApplicationModel app = (ApplicationModel) r.getContainer();
|
||||
if (app.getName().endsWith(AdminRoles.APP_SUFFIX)) {
|
||||
String realm = app.getName().substring(0, app.getName().length() - AdminRoles.APP_SUFFIX.length());
|
||||
if (!realmAdminAccess.containsKey(realm)) {
|
||||
realmAdminAccess.put(realm, new HashSet<String>());
|
||||
}
|
||||
realmAdminAccess.get(realm).add(r.getName());
|
||||
}
|
||||
private void addRealmAccess(RealmModel realm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
ApplicationModel realmAdminApp = realm.getApplicationByName(realmManager.getRealmAdminApplicationName(realm));
|
||||
Set<RoleModel> roles = realmAdminApp.getRoles();
|
||||
for (RoleModel role : roles) {
|
||||
if (!realm.hasRole(user, role)) continue;
|
||||
if (!realmAdminAccess.containsKey(realm.getName())) {
|
||||
realmAdminAccess.put(realm.getName(), new HashSet<String>());
|
||||
}
|
||||
realmAdminAccess.get(realm.getName()).add(role.getName());
|
||||
}
|
||||
|
||||
if (r.isComposite()) {
|
||||
addRealmAdminAccess(realmAdminAccess, r.getComposites());
|
||||
}
|
||||
|
||||
private void addMasterRealmAccess(RealmModel masterRealm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
|
||||
List<RealmModel> realms = session.getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
ApplicationModel realmAdminApp = realm.getMasterAdminApp();
|
||||
Set<RoleModel> roles = realmAdminApp.getRoles();
|
||||
for (RoleModel role : roles) {
|
||||
if (!masterRealm.hasRole(user, role)) continue;
|
||||
if (!realmAdminAccess.containsKey(realm.getName())) {
|
||||
realmAdminAccess.put(realm.getName(), new HashSet<String>());
|
||||
}
|
||||
realmAdminAccess.get(realm.getName()).add(role.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Path("logout")
|
||||
@GET
|
||||
@NoCache
|
||||
|
@ -268,7 +271,12 @@ public class AdminConsole {
|
|||
@Path("{path:.+}")
|
||||
public Response getResource(@PathParam("path") String path) {
|
||||
try {
|
||||
Theme theme = ThemeLoader.createTheme(Config.getThemeAdmin(), Theme.Type.ADMIN);
|
||||
String themeName = realm.getAdminTheme();
|
||||
if (themeName == null || themeName.trim().equals("")) {
|
||||
themeName = Config.getThemeAdmin();
|
||||
}
|
||||
|
||||
Theme theme = ThemeLoader.createTheme(themeName, Theme.Type.ADMIN);
|
||||
InputStream resource = theme.getResourceAsStream(path);
|
||||
if (resource != null) {
|
||||
String contentType = mimeTypes.getContentType(path);
|
||||
|
|
|
@ -145,6 +145,9 @@ public class AdminRoot {
|
|||
@Path("realms")
|
||||
public RealmsAdminResource getRealmsAdmin(@Context final HttpHeaders headers) {
|
||||
Auth auth = authenticateRealmAdminRequest(headers);
|
||||
if (auth != null) {
|
||||
logger.info("authenticated admin access for: " + auth.getUser().getLoginName());
|
||||
}
|
||||
RealmsAdminResource adminResource = new RealmsAdminResource(auth, tokenManager);
|
||||
ResteasyProviderFactory.getInstance().injectProperties(adminResource);
|
||||
//resourceContext.initResource(adminResource);
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.keycloak.services.managers.Auth;
|
|||
import org.keycloak.services.managers.ModelToRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.managers.TokenManager;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.services.resources.flows.Flows;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
|
@ -32,7 +33,6 @@ import javax.ws.rs.core.Context;
|
|||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -68,6 +68,9 @@ public class RealmsAdminResource {
|
|||
@Context
|
||||
protected KeycloakSession session;
|
||||
|
||||
@Context
|
||||
protected KeycloakApplication keycloak;
|
||||
|
||||
@GET
|
||||
@NoCache
|
||||
@Produces("application/json")
|
||||
|
@ -77,19 +80,20 @@ public class RealmsAdminResource {
|
|||
if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
|
||||
List<RealmModel> realms = session.getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
addRealmRep(reps, realm);
|
||||
addRealmRep(reps, realm, realm.getMasterAdminApp());
|
||||
}
|
||||
} else {
|
||||
addRealmRep(reps, auth.getRealm());
|
||||
ApplicationModel adminApp = auth.getRealm().getApplicationByName(realmManager.getRealmAdminApplicationName(auth.getRealm()));
|
||||
addRealmRep(reps, auth.getRealm(), adminApp);
|
||||
}
|
||||
logger.debug(("getRealms()"));
|
||||
return reps;
|
||||
}
|
||||
|
||||
protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm) {
|
||||
if (auth.hasAppRole(realm.getAdminApp(), AdminRoles.MANAGE_REALM)) {
|
||||
protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ApplicationModel realmManagementApplication) {
|
||||
if (auth.hasAppRole(realmManagementApplication, AdminRoles.MANAGE_REALM)) {
|
||||
reps.add(ModelToRepresentation.toRepresentation(realm));
|
||||
} else if (auth.hasOneOfAppRole(realm.getAdminApp(), AdminRoles.ALL_REALM_ROLES)) {
|
||||
} else if (auth.hasOneOfAppRole(realmManagementApplication, AdminRoles.ALL_REALM_ROLES)) {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm(realm.getName());
|
||||
reps.add(rep);
|
||||
|
@ -100,6 +104,7 @@ public class RealmsAdminResource {
|
|||
@Consumes("application/json")
|
||||
public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
realmManager.setContextPath(keycloak.getContextPath());
|
||||
if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
@ -125,6 +130,7 @@ public class RealmsAdminResource {
|
|||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||
public Response uploadRealm(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
realmManager.setContextPath(keycloak.getContextPath());
|
||||
if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
@ -164,7 +170,7 @@ public class RealmsAdminResource {
|
|||
}
|
||||
|
||||
RealmModel adminRealm = new RealmManager(session).getKeycloakAdminstrationRealm();
|
||||
ApplicationModel realmAdminApp = realm.getAdminApp();
|
||||
ApplicationModel realmAdminApp = realm.getMasterAdminApp();
|
||||
for (String r : AdminRoles.ALL_REALM_ROLES) {
|
||||
RoleModel role = realmAdminApp.getRole(r);
|
||||
adminRealm.grantRole(auth.getUser(), role);
|
||||
|
@ -183,7 +189,13 @@ public class RealmsAdminResource {
|
|||
&& !auth.getRealm().equals(realm)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
RealmAuth realmAuth = new RealmAuth(auth, realm.getAdminApp());
|
||||
RealmAuth realmAuth;
|
||||
|
||||
if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
|
||||
realmAuth = new RealmAuth(auth, realm.getMasterAdminApp());
|
||||
} else {
|
||||
realmAuth = new RealmAuth(auth, realm.getApplicationByName(realmManager.getRealmAdminApplicationName(auth.getRealm())));
|
||||
}
|
||||
|
||||
RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager);
|
||||
ResteasyProviderFactory.getInstance().injectProperties(adminResource);
|
||||
|
|
Loading…
Reference in a new issue