KEYCLOAK-153
Realm installation page
This commit is contained in:
parent
d20be22ab5
commit
c6f4e21b84
14 changed files with 205 additions and 7 deletions
|
@ -253,7 +253,18 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||||
},
|
},
|
||||||
controller : 'ApplicationScopeMappingCtrl'
|
controller : 'ApplicationScopeMappingCtrl'
|
||||||
})
|
})
|
||||||
|
.when('/realms/:realm/applications/:application/installation', {
|
||||||
|
templateUrl : 'partials/application-installation.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
installation : function(ApplicationInstallationLoader) {
|
||||||
|
return ApplicationInstallationLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'ApplicationInstallationCtrl'
|
||||||
|
})
|
||||||
.when('/create/application/:realm', {
|
.when('/create/application/:realm', {
|
||||||
templateUrl : 'partials/application-detail.html',
|
templateUrl : 'partials/application-detail.html',
|
||||||
resolve : {
|
resolve : {
|
||||||
|
|
|
@ -179,6 +179,12 @@ module.controller('ApplicationListCtrl', function($scope, realm, applications, A
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.controller('ApplicationInstallationCtrl', function($scope, realm, installation, ApplicationInstallation, $routeParams) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
$scope.installation = installation;
|
||||||
|
$scope.download = ApplicationInstallation.url({ realm: $routeParams.realm, application: $routeParams.application });
|
||||||
|
});
|
||||||
|
|
||||||
module.controller('ApplicationDetailCtrl', function($scope, realm, application, Application, $location, Dialog, Notifications) {
|
module.controller('ApplicationDetailCtrl', function($scope, realm, application, Application, $location, Dialog, Notifications) {
|
||||||
console.log('ApplicationDetailCtrl');
|
console.log('ApplicationDetailCtrl');
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,15 @@ module.factory('ApplicationRoleLoader', function(Loader, ApplicationRole, $route
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.factory('ApplicationInstallationLoader', function(Loader, ApplicationInstallation, $route, $q) {
|
||||||
|
return Loader.get(ApplicationInstallation, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
application : $route.current.params.application
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
module.factory('ApplicationRoleListLoader', function(Loader, ApplicationRole, $route, $q) {
|
module.factory('ApplicationRoleListLoader', function(Loader, ApplicationRole, $route, $q) {
|
||||||
return Loader.query(ApplicationRole, function() {
|
return Loader.query(ApplicationRole, function() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -209,6 +209,22 @@ module.factory('Application', function($resource) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.factory('ApplicationInstallation', function($resource) {
|
||||||
|
var url = '/auth-server/rest/saas/admin/realms/:realm/applications/:application/installation';
|
||||||
|
var resource = $resource('/auth-server/rest/saas/admin/realms/:realm/applications/:application/installation', {
|
||||||
|
realm : '@realm',
|
||||||
|
application : '@application'
|
||||||
|
}, {
|
||||||
|
update : {
|
||||||
|
method : 'PUT'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
resource.url = function(parameters) {
|
||||||
|
return url.replace(':realm', parameters.realm).replace(':application', parameters.application);
|
||||||
|
}
|
||||||
|
return resource;
|
||||||
|
});
|
||||||
|
|
||||||
module.factory('ApplicationCredentials', function($resource) {
|
module.factory('ApplicationCredentials', function($resource) {
|
||||||
return $resource('/auth-server/rest/saas/admin/realms/:realm/applications/:application/credentials', {
|
return $resource('/auth-server/rest/saas/admin/realms/:realm/applications/:application/credentials', {
|
||||||
realm : '@realm',
|
realm : '@realm',
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<ul class="rcue-tabs">
|
<ul class="rcue-tabs">
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
||||||
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
||||||
<li><a href="#">Installation</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/installation">Installation</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
||||||
<li><a href="#">Sessions</a></li>
|
<li><a href="#">Sessions</a></li>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<ul class="rcue-tabs">
|
<ul class="rcue-tabs">
|
||||||
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
||||||
<li><a href="#">Installation</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/installation">Installation</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
||||||
<li><a href="#">Sessions</a></li>
|
<li><a href="#">Sessions</a></li>
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<div id="wrapper" class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
|
||||||
|
<div id="content-area" class="col-md-9" role="main">
|
||||||
|
<div class="top-nav" data-ng-show="!create">
|
||||||
|
<ul class="rcue-tabs">
|
||||||
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
||||||
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
||||||
|
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/installation">Installation</a></li>
|
||||||
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
||||||
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
||||||
|
<li><a href="#">Sessions</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="top-nav" data-ng-show="create">
|
||||||
|
<ul class="rcue-tabs">
|
||||||
|
<li></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
<a class="button primary" href="{{download}}" download="keycloak.json" type="submit">Download</a></br>
|
||||||
|
<textarea style="width: 100%;" rows="20" onclick="this.select()">{{installation | json}}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="container-right-bg"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -6,7 +6,7 @@
|
||||||
<ul class="rcue-tabs">
|
<ul class="rcue-tabs">
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
||||||
<li><a href="#">Installation</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/installation">Installation</a></li>
|
||||||
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
||||||
<li><a href="#">Sessions</a></li>
|
<li><a href="#">Sessions</a></li>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<ul class="rcue-tabs">
|
<ul class="rcue-tabs">
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
|
||||||
<li><a href="#">Installation</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/installation">Installation</a></li>
|
||||||
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
|
||||||
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
|
||||||
<li><a href="#">Sessions</a></li>
|
<li><a href="#">Sessions</a></li>
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package org.keycloak.representations.idm;
|
||||||
|
|
||||||
|
import org.codehaus.jackson.annotate.JsonProperty;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
public class ApplicationInstallationRepresentation {
|
||||||
|
protected String realm;
|
||||||
|
protected String resource;
|
||||||
|
@JsonProperty("realm-public-key")
|
||||||
|
protected String realmPublicKey;
|
||||||
|
@JsonProperty("auth-url")
|
||||||
|
protected String authUrl;
|
||||||
|
@JsonProperty("code-url")
|
||||||
|
protected String codeUrl;
|
||||||
|
@JsonProperty("ssl-not-required")
|
||||||
|
protected boolean sslNotRequired;
|
||||||
|
protected Map<String, String> credentials;
|
||||||
|
|
||||||
|
public String getRealm() {
|
||||||
|
return realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRealm(String realm) {
|
||||||
|
this.realm = realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResource() {
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResource(String resource) {
|
||||||
|
this.resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRealmPublicKey() {
|
||||||
|
return realmPublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRealmPublicKey(String realmPublicKey) {
|
||||||
|
this.realmPublicKey = realmPublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthUrl() {
|
||||||
|
return authUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthUrl(String authUrl) {
|
||||||
|
this.authUrl = authUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCodeUrl() {
|
||||||
|
return codeUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCodeUrl(String codeUrl) {
|
||||||
|
this.codeUrl = codeUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSslNotRequired() {
|
||||||
|
return sslNotRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSslNotRequired(boolean sslNotRequired) {
|
||||||
|
this.sslNotRequired = sslNotRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getCredentials() {
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCredentials(Map<String, String> credentials) {
|
||||||
|
this.credentials = credentials;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,15 +8,20 @@ import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.representations.idm.ApplicationRepresentation;
|
import org.keycloak.representations.idm.ApplicationRepresentation;
|
||||||
|
import org.keycloak.representations.idm.ApplicationInstallationRepresentation;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
import org.keycloak.representations.idm.ScopeMappingRepresentation;
|
import org.keycloak.representations.idm.ScopeMappingRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRoleMappingRepresentation;
|
import org.keycloak.representations.idm.UserRoleMappingRepresentation;
|
||||||
|
import org.keycloak.services.resources.flows.Urls;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.HashSet;
|
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;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -159,4 +164,25 @@ public class ApplicationManager {
|
||||||
return rep;
|
return rep;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ApplicationInstallationRepresentation toInstallationRepresentation(RealmModel realmModel, ApplicationModel applicationModel, URI baseUri) {
|
||||||
|
ApplicationInstallationRepresentation rep = new ApplicationInstallationRepresentation();
|
||||||
|
rep.setRealm(realmModel.getId());
|
||||||
|
rep.setRealmPublicKey(realmModel.getPublicKeyPem());
|
||||||
|
rep.setSslNotRequired(realmModel.isSslNotRequired());
|
||||||
|
|
||||||
|
rep.setAuthUrl(Urls.realmLoginPage(baseUri, realmModel.getId()).toString());
|
||||||
|
rep.setCodeUrl(Urls.realmCode(baseUri, realmModel.getId()).toString());
|
||||||
|
|
||||||
|
rep.setResource(applicationModel.getId());
|
||||||
|
|
||||||
|
Map<String, String> creds = new HashMap<String, String>();
|
||||||
|
creds.put(CredentialRepresentation.PASSWORD, "INSERT APPLICATION PASSWORD");
|
||||||
|
if (applicationModel.getApplicationUser().isTotp()) {
|
||||||
|
creds.put(CredentialRepresentation.TOTP, "INSERT APPLICATION TOTP");
|
||||||
|
}
|
||||||
|
rep.setCredentials(creds);
|
||||||
|
|
||||||
|
return rep;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,10 @@ import org.keycloak.models.ModelProvider;
|
||||||
import org.keycloak.services.managers.SocialRequestManager;
|
import org.keycloak.services.managers.SocialRequestManager;
|
||||||
import org.keycloak.services.managers.TokenManager;
|
import org.keycloak.services.managers.TokenManager;
|
||||||
|
|
||||||
import javax.annotation.PreDestroy;
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.logging.Logger;
|
import org.jboss.resteasy.logging.Logger;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
|
import org.keycloak.representations.idm.ApplicationInstallationRepresentation;
|
||||||
import org.keycloak.representations.idm.ApplicationRepresentation;
|
import org.keycloak.representations.idm.ApplicationRepresentation;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.services.managers.ApplicationManager;
|
import org.keycloak.services.managers.ApplicationManager;
|
||||||
|
@ -17,7 +19,10 @@ import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -30,6 +35,8 @@ public class ApplicationResource extends RoleContainerResource {
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
protected ApplicationModel application;
|
protected ApplicationModel application;
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
|
@Context
|
||||||
|
protected UriInfo uriInfo;
|
||||||
|
|
||||||
public ApplicationResource(RealmModel realm, ApplicationModel applicationModel, KeycloakSession session) {
|
public ApplicationResource(RealmModel realm, ApplicationModel applicationModel, KeycloakSession session) {
|
||||||
super(applicationModel);
|
super(applicationModel);
|
||||||
|
@ -54,6 +61,20 @@ public class ApplicationResource extends RoleContainerResource {
|
||||||
return applicationManager.toRepresentation(application);
|
return applicationManager.toRepresentation(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@NoCache
|
||||||
|
@Path("installation")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public String getInstallation() throws IOException {
|
||||||
|
ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
|
||||||
|
ApplicationInstallationRepresentation rep = applicationManager.toInstallationRepresentation(realm, application, uriInfo.getBaseUri());
|
||||||
|
|
||||||
|
// TODO Temporary solution to pretty-print
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep);
|
||||||
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@NoCache
|
@NoCache
|
||||||
public void deleteApplication() {
|
public void deleteApplication() {
|
||||||
|
|
|
@ -120,6 +120,10 @@ public class Urls {
|
||||||
return tokenBase(baseUri).path(TokenService.class, "registerPage").build(realmId);
|
return tokenBase(baseUri).path(TokenService.class, "registerPage").build(realmId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static URI realmCode(URI baseUri, String realmId) {
|
||||||
|
return tokenBase(baseUri).path(TokenService.class, "accessCodeToToken").build(realmId);
|
||||||
|
}
|
||||||
|
|
||||||
private static UriBuilder saasBase(URI baseUri) {
|
private static UriBuilder saasBase(URI baseUri) {
|
||||||
return UriBuilder.fromUri(baseUri).path(SaasService.class);
|
return UriBuilder.fromUri(baseUri).path(SaasService.class);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue