From 199c786e224dd62f0c315729c85c4cd6c1bd7411 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Mon, 26 May 2014 20:41:33 -0400 Subject: [PATCH] jaxrs-doclet support --- distribution/examples-docs-zip/assembly.xml | 4 + services/pom.xml | 53 ++++-- .../services/resources/AccountService.java | 45 +++++ .../services/resources/JsResource.java | 7 + .../resources/PublicRealmResource.java | 9 +- .../services/resources/QRCodeResource.java | 12 ++ .../services/resources/RealmsResource.java | 2 +- .../services/resources/ThemeResource.java | 10 ++ .../services/resources/TokenService.java | 105 +++++++++++- .../services/resources/WelcomeResource.java | 12 ++ .../resources/admin/AdminConsole.java | 34 +++- .../services/resources/admin/AdminRoot.java | 35 +++- .../resources/admin/ApplicationResource.java | 100 +++++++++++- .../resources/admin/ApplicationsResource.java | 20 +++ .../resources/admin/ClaimResource.java | 12 ++ .../resources/admin/OAuthClientResource.java | 46 +++++- .../resources/admin/OAuthClientsResource.java | 18 ++ .../resources/admin/RealmAdminResource.java | 96 +++++++++++ .../resources/admin/RealmsAdminResource.java | 34 +++- .../resources/admin/RoleByIdResource.java | 49 +++++- .../admin/RoleContainerResource.java | 61 +++++++ .../resources/admin/ScopeMappedResource.java | 64 ++++++++ .../admin/ServerInfoAdminResource.java | 5 + .../resources/admin/UsersResource.java | 154 +++++++++++++++++- 24 files changed, 961 insertions(+), 26 deletions(-) mode change 100644 => 100755 services/src/main/java/org/keycloak/services/resources/JsResource.java mode change 100644 => 100755 services/src/main/java/org/keycloak/services/resources/WelcomeResource.java mode change 100644 => 100755 services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java diff --git a/distribution/examples-docs-zip/assembly.xml b/distribution/examples-docs-zip/assembly.xml index 8efd9dfb2c..9f765f1908 100755 --- a/distribution/examples-docs-zip/assembly.xml +++ b/distribution/examples-docs-zip/assembly.xml @@ -18,6 +18,10 @@ ../../target/site/apidocs docs/javadocs + + ../../services/target/site/apidocs + docs/rest-api + ../../docbook/target/docbook/publish/en-US docs/userguide diff --git a/services/pom.xml b/services/pom.xml index beab13f40e..887f2cab79 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -195,16 +195,34 @@ ${maven.compiler.target} - - - - org.apache.maven.plugins maven-javadoc-plugin - 2.7 - - + 2.9.1 + + + + generate-service-docs + generate-resources com.lunatech.doclets.jax.jaxrs.JAXRSDoclet @@ -214,13 +232,22 @@ 0.10.0 + false + + + ../javadocs + + ${project.basedir}/../target/site/apidocs + + + -disablejavascriptexample - - javadoc - - - + + javadoc + + + - + diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java index b232de5e24..e26a111c80 100755 --- a/services/src/main/java/org/keycloak/services/resources/AccountService.java +++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java @@ -200,12 +200,22 @@ public class AccountService { } } + /** + * CORS preflight + * + * @return + */ @Path("/") @OPTIONS public Response accountPreflight() { return Cors.add(request, Response.ok()).auth().preflight().build(); } + /** + * Get account information. + * + * @return + */ @Path("/") @GET public Response accountPage() { @@ -279,6 +289,18 @@ public class AccountService { return forwardToPage("sessions", AccountPages.SESSIONS); } + /** + * Update account information. + * + * Form params: + * + * firstName + * lastName + * email + * + * @param formData + * @return + */ @Path("/") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @@ -348,6 +370,17 @@ public class AccountService { return Response.seeOther(Urls.accountSessionsPage(uriInfo.getBaseUri(), realm.getName())).build(); } + /** + * Update the TOTP for this account. + * + * form parameters: + * + * totp - otp generated by authenticator + * totpSecret - totp secret to register + * + * @param formData + * @return + */ @Path("totp") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @@ -381,6 +414,18 @@ public class AccountService { return account.setSuccess("successTotp").createResponse(AccountPages.TOTP); } + /** + * Update account password + * + * Form params: + * + * password - old password + * password-new + * pasword-confirm + * + * @param formData + * @return + */ @Path("password") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) diff --git a/services/src/main/java/org/keycloak/services/resources/JsResource.java b/services/src/main/java/org/keycloak/services/resources/JsResource.java old mode 100644 new mode 100755 index c28d8bd88b..62349db86e --- a/services/src/main/java/org/keycloak/services/resources/JsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/JsResource.java @@ -7,11 +7,18 @@ import javax.ws.rs.core.Response; import java.io.InputStream; /** + * Get keycloak.js file for javascript clients + * * @author Stian Thorgersen */ @Path("/js") public class JsResource { + /** + * Get keycloak.js file for javascript clients + * + * @return + */ @GET @Path("/keycloak.js") @Produces("text/javascript") diff --git a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java index f8518e9ff9..097b25a610 100755 --- a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java +++ b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java @@ -13,6 +13,8 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; /** + * Resource class for public realm information + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -28,10 +30,15 @@ public class PublicRealmResource { this.realm = realm; } + /** + * Public information about the realm. + * + * @return + */ @GET @NoCache @Produces("application/json") - public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) { + public PublishedRealmRepresentation getRealm() { return realmRep(realm, uriInfo); } diff --git a/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java b/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java index 3ae4b6756e..6cc66ee424 100755 --- a/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java +++ b/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java @@ -18,11 +18,23 @@ import java.io.IOException; import java.io.OutputStream; /** + * Create a barcode image + * * @author Stian Thorgersen */ @Path("/qrcode") public class QRCodeResource { + /** + * Create a bar code image + * + * @param contents + * @param size + * @return + * @throws ServletException + * @throws IOException + * @throws WriterException + */ @GET @Produces("image/png") public Response createQrCode(@QueryParam("contents") String contents, @QueryParam("size") String size) throws ServletException, IOException, WriterException { diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java index 23359d5e39..0edf915555 100755 --- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java @@ -162,7 +162,7 @@ public class RealmsResource { protected RealmModel locateRealm(String name, RealmManager realmManager) { RealmModel realm = realmManager.getRealmByName(name); if (realm == null) { - throw new NotFoundException("Realm " + name + " not found"); + throw new NotFoundException("Realm " + name + " does not exist"); } return realm; } diff --git a/services/src/main/java/org/keycloak/services/resources/ThemeResource.java b/services/src/main/java/org/keycloak/services/resources/ThemeResource.java index 1d4fe1c499..84413a3ce4 100755 --- a/services/src/main/java/org/keycloak/services/resources/ThemeResource.java +++ b/services/src/main/java/org/keycloak/services/resources/ThemeResource.java @@ -16,6 +16,8 @@ import javax.ws.rs.core.Response; import java.io.InputStream; /** + * Theme resource + * * @author Stian Thorgersen */ @Path("/theme") @@ -28,6 +30,14 @@ public class ThemeResource { @Context private ProviderSession providerSession; + /** + * Get theme content + * + * @param themType + * @param themeName + * @param path + * @return + */ @GET @Path("/{themType}/{themeName}/{path:.*}") public Response getResource(@PathParam("themType") String themType, @PathParam("themeName") String themeName, @PathParam("path") String path) { diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java index 9f018c1591..024bdb73c9 100755 --- a/services/src/main/java/org/keycloak/services/resources/TokenService.java +++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java @@ -74,6 +74,8 @@ import java.util.Map; import java.util.Set; /** + * Resource class for the oauth/openid connect token service + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -198,7 +200,23 @@ public class TokenService { } - + /** + * Direct grant REST invocation. One stop call to obtain an access token. + * + * If the client is a confidential client + * you must include the client-id (application name or oauth client name) and secret in an Basic Auth Authorization header. + * + * If the client is a public client, then you must include a "client_id" form parameter with the app's or oauth client's name. + * + * The realm must be configured to allow these types of auth requests. (Direct Grant API in admin console Settings page) + * + * + * @See http://tools.ietf.org/html/rfc6749#section-4.3 + * + * @param authorizationHeader + * @param form + * @return @see org.keycloak.representations.AccessTokenResponse + */ @Path("grants/access") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @@ -284,6 +302,20 @@ public class TokenService { return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build(); } + /** + * URL for making refresh token requests. + * + * @See http://tools.ietf.org/html/rfc6749#section-6 + * + * If the client is a confidential client + * you must include the client-id (application name or oauth client name) and secret in an Basic Auth Authorization header. + * + * If the client is a public client, then you must include a "client_id" form parameter with the app's or oauth client's name. + * + * @param authorizationHeader + * @param form + * @return + */ @Path("refresh") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @@ -321,6 +353,16 @@ public class TokenService { return Cors.add(request, Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).auth().allowedOrigins(client).allowedMethods("POST").exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS).build(); } + /** + * URL called after login page. YOU SHOULD NEVER INVOKE THIS DIRECTLY! + * + * @param clientId + * @param scopeParam + * @param state + * @param redirect + * @param formData + * @return + */ @Path("auth/request/login") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @@ -422,6 +464,16 @@ public class TokenService { return service; } + /** + * Registration + * + * @param clientId + * @param scopeParam + * @param state + * @param redirect + * @param formData + * @return + */ @Path("registrations") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @@ -530,6 +582,11 @@ public class TokenService { return processLogin(clientId, scopeParam, state, redirect, formData); } + /** + * CORS preflight path for access code to token + * + * @return + */ @Path("access/codes") @OPTIONS @Produces("application/json") @@ -538,6 +595,15 @@ public class TokenService { return Cors.add(request, Response.ok()).auth().preflight().build(); } + /** + * URL invoked by adapter to turn an access code to access token + * + * @See http://tools.ietf.org/html/rfc6749#section-4.1 + * + * @param authorizationHeader + * @param formData + * @return + */ @Path("access/codes") @POST @Produces("application/json") @@ -720,6 +786,20 @@ public class TokenService { return client; } + /** + * Login page. Must be redirected to from the application or oauth client. + * + * @See http://tools.ietf.org/html/rfc6749#section-4.1 + * + * + * @param responseType + * @param redirect + * @param clientId + * @param scopeParam + * @param state + * @param prompt + * @return + */ @Path("login") @GET public Response loginPage(final @QueryParam("response_type") String responseType, @@ -784,6 +864,16 @@ public class TokenService { return Flows.forms(providerSession, realm, uriInfo).createLogin(); } + /** + * Registration page. Must be redirected to from login page. + * + * @param responseType + * @param redirect + * @param clientId + * @param scopeParam + * @param state + * @return + */ @Path("registrations") @GET public Response registerPage(final @QueryParam("response_type") String responseType, @@ -834,6 +924,13 @@ public class TokenService { return Flows.forms(providerSession, realm, uriInfo).createRegistration(); } + /** + * Logout user session. + * + * @param sessionState + * @param redirectUri + * @return + */ @Path("logout") @GET @NoCache @@ -877,6 +974,12 @@ public class TokenService { audit.user(user).session(session).success(); } + /** + * OAuth grant page. You should not invoked this directly! + * + * @param formData + * @return + */ @Path("oauth/grant") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) diff --git a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java old mode 100644 new mode 100755 index 6df21f2bc7..9716ff65b4 --- a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java +++ b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java @@ -20,6 +20,12 @@ public class WelcomeResource { @Context private UriInfo uriInfo; + /** + * Welcome page of Keycloak + * + * @return + * @throws URISyntaxException + */ @GET @Produces("text/html") public Response getWelcomePage() throws URISyntaxException { @@ -31,6 +37,12 @@ public class WelcomeResource { } } + /** + * Resources for welcome page + * + * @param name + * @return + */ @GET @Path("/welcome-content/{name}") @Produces("text/html") diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java index 38bd390e77..090a2dfa52 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java @@ -147,6 +147,11 @@ public class AdminConsole { } } + /** + * Adapter configuration for the admin console for this realm + * + * @return + */ @Path("config") @GET @Produces("application/json") @@ -160,6 +165,12 @@ public class AdminConsole { } + /** + * Permission information + * + * @param headers + * @return + */ @Path("whoami") @GET @Produces("application/json") @@ -231,6 +242,11 @@ public class AdminConsole { } } + /** + * Logout from the admin console + * + * @return + */ @Path("logout") @GET @NoCache @@ -248,6 +264,12 @@ public class AdminConsole { private static FileTypeMap mimeTypes = MimetypesFileTypeMap.getDefaultFileTypeMap(); + /** + * Main page of this realm's admin console + * + * @return + * @throws URISyntaxException + */ @GET public Response getMainPage() throws URISyntaxException { if (!uriInfo.getRequestUri().getPath().endsWith("/")) { @@ -257,6 +279,11 @@ public class AdminConsole { } } + /** + * Javascript used by admin console + * + * @return + */ @GET @Path("js/keycloak.js") @Produces("text/javascript") @@ -270,7 +297,12 @@ public class AdminConsole { } } - + /** + * Theme resources for this realm's admin console. (images, html files, etc..) + * + * @param path + * @return + */ @GET @Path("{path:.+}") public Response getResource(@PathParam("path") String path) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java index 838dacab3c..cf3e49e5f2 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java @@ -35,6 +35,8 @@ import javax.ws.rs.core.UriInfo; import java.io.IOException; /** + * Root resource for admin console and admin REST API + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -72,6 +74,12 @@ public class AdminRoot { + + /** + * Convenience path to master realm admin console + * + * @return + */ @GET public Response masterRealmAdminConsoleRedirect() { RealmModel master = new RealmManager(session).getKeycloakAdminstrationRealm(); @@ -80,7 +88,12 @@ public class AdminRoot { ).build(); } - @Path("index.{hack:html}") + /** + * Convenience path to master realm admin console + * + * @return + */ + @Path("index.{html:html}") // expression is actually "index.html" but this is a hack to get around jax-doclet bug @GET public Response masterRealmAdminConsoleRedirectHtml() { return masterRealmAdminConsoleRedirect(); @@ -103,7 +116,12 @@ public class AdminRoot { return adminBaseUrl(base).path(AdminRoot.class, "getAdminConsole"); } - @Path("{realm}/console") + /** + * path to realm admin console ui + * + * @param name Realm name (not id!) + * @return + */ public AdminConsole getAdminConsole(final @PathParam("realm") String name) { RealmManager realmManager = new RealmManager(session); RealmModel realm = locateRealm(name, realmManager); @@ -152,6 +170,13 @@ public class AdminRoot { return adminBaseUrl(base).path(AdminRoot.class, "getRealmsAdmin"); } + + /** + * Base Path to realm admin REST interface + * + * @param headers + * @return + */ @Path("realms") public RealmsAdminResource getRealmsAdmin(@Context final HttpHeaders headers) { if (request.getHttpMethod().equalsIgnoreCase("OPTIONS")) { @@ -173,6 +198,12 @@ public class AdminRoot { return adminResource; } + /** + * General information about the server + * + * @param headers + * @return + */ @Path("serverinfo") public ServerInfoAdminResource getServerInfo(@Context final HttpHeaders headers) { ServerInfoAdminResource adminResource = new ServerInfoAdminResource(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java index 0e29604c71..9f4527b528 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java @@ -45,6 +45,8 @@ import java.util.Map; import java.util.Set; /** + * Base resource class for managing one particular application of a realm. + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -73,11 +75,21 @@ public class ApplicationResource { auth.init(RealmAuth.Resource.APPLICATION); } + /** + * base path for managing allowed application claims + * + * @return + */ @Path("claims") public ClaimResource getClaimResource() { return new ClaimResource(application, auth); } + /** + * Update the application. + * @param rep + * @return + */ @PUT @Consumes(MediaType.APPLICATION_JSON) public Response update(final ApplicationRepresentation rep) { @@ -93,6 +105,11 @@ public class ApplicationResource { } + /** + * Get representation of the application. + * + * @return + */ @GET @NoCache @Produces(MediaType.APPLICATION_JSON) @@ -104,6 +121,12 @@ public class ApplicationResource { } + /** + * Return keycloak.json file for this application to be used to configure the adapter of that application. + * + * @return + * @throws IOException + */ @GET @NoCache @Path("installation/json") @@ -118,6 +141,12 @@ public class ApplicationResource { return JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep); } + /** + * Return XML that can be included in the JBoss/Wildfly Keycloak subsystem to configure the adapter of that application. + * + * @return + * @throws IOException + */ @GET @NoCache @Path("installation/jboss") @@ -129,6 +158,10 @@ public class ApplicationResource { return applicationManager.toJBossSubsystemConfig(realm, application, getKeycloakApplication().getBaseUri(uriInfo)); } + /** + * Delete this application. + * + */ @DELETE @NoCache public void deleteApplication() { @@ -137,6 +170,12 @@ public class ApplicationResource { realm.removeApplication(application.getId()); } + + /** + * Generates a new secret for this application + * + * @return + */ @Path("client-secret") @POST @Produces("application/json") @@ -150,6 +189,11 @@ public class ApplicationResource { return rep; } + /** + * Get the secret of this application + * + * @return + */ @Path("client-secret") @GET @Produces("application/json") @@ -162,7 +206,11 @@ public class ApplicationResource { return ModelToRepresentation.toRepresentation(model); } - + /** + * Base path for managing the scope mappings for this application + * + * @return + */ @Path("scope-mappings") public ScopeMappedResource getScopeMappedResource() { return new ScopeMappedResource(realm, auth, application, session); @@ -173,6 +221,12 @@ public class ApplicationResource { return new RoleContainerResource(realm, auth, application); } + /** + * Returns set of allowed origin. This is used for CORS requests. Access tokens will have + * their allowedOrigins claim set to this value for tokens created for this application. + * + * @return + */ @Path("allowed-origins") @GET @Produces("application/json") @@ -183,6 +237,12 @@ public class ApplicationResource { return application.getWebOrigins(); } + /** + * Change the set of allowed origins. This is used for CORS requests. Access tokens will have + * their allowedOrigins claim set to this value for tokens created for this application. + * + * @param allowedOrigins + */ @Path("allowed-origins") @PUT @Consumes("application/json") @@ -193,6 +253,12 @@ public class ApplicationResource { application.setWebOrigins(allowedOrigins); } + /** + * Remove set of allowed origins from current allowed origins list. This is used for CORS requests. Access tokens will have + * their allowedOrigins claim set to this value for tokens created for this application. + * + * @param allowedOrigins + */ @Path("allowed-origins") @DELETE @Consumes("application/json") @@ -205,6 +271,10 @@ public class ApplicationResource { } } + /** + * If the application has an admin URL, push the application's revocation policy to it. + * + */ @Path("push-revocation") @POST public void pushRevocation() { @@ -212,6 +282,12 @@ public class ApplicationResource { new ResourceAdminManager().pushApplicationRevocationPolicy(uriInfo.getRequestUri(), realm, application); } + /** + * If the application has an admin URL, query it directly for session stats. + * + * @param users whether to include users logged in. + * @return + */ @Path("session-stats") @GET @NoCache @@ -235,6 +311,15 @@ public class ApplicationResource { return stats; } + /** + * Number of user sessions associated with this application + * + * { + * "count": number + * } + * + * @return + */ @Path("session-count") @GET @NoCache @@ -246,6 +331,11 @@ public class ApplicationResource { return map; } + /** + * Return a list of user sessions associated with this application + * + * @return + */ @Path("user-sessions") @GET @NoCache @@ -260,6 +350,10 @@ public class ApplicationResource { return sessions; } + /** + * If the application has an admin URL, invalidate all sessions associated with that application directly. + * + */ @Path("logout-all") @POST public void logoutAll() { @@ -267,6 +361,10 @@ public class ApplicationResource { new ResourceAdminManager().logoutApplication(uriInfo.getRequestUri(), realm, application, null, null); } + /** + * If the application has an admin URL, invalidate the sessions for a particular user directly. + * + */ @Path("logout-user/{username}") @POST public void logout(final @PathParam("username") String username) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java index 7241a15433..f83bfc79f3 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java @@ -27,6 +27,8 @@ import java.util.ArrayList; import java.util.List; /** + * Base resource class for managing a realm's applications. + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -45,6 +47,11 @@ public class ApplicationsResource { auth.init(RealmAuth.Resource.APPLICATION); } + /** + * List of applications belonging to this realm. + * + * @return + */ @GET @Produces(MediaType.APPLICATION_JSON) @NoCache @@ -68,6 +75,13 @@ public class ApplicationsResource { return rep; } + /** + * Create a new application. Application name must be unique! + * + * @param uriInfo + * @param rep + * @return + */ @POST @Consumes(MediaType.APPLICATION_JSON) public Response createApplication(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) { @@ -82,6 +96,12 @@ public class ApplicationsResource { } } + /** + * Base path for managing a specific application. + * + * @param name + * @return + */ @Path("{app-name}") public ApplicationResource getApplication(final @PathParam("app-name") String name) { ApplicationModel applicationModel = realm.getApplicationByName(name); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java index 4d260e579e..9a9ebaa389 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java @@ -12,6 +12,8 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; /** + * Base resource class for managing allowed claims for an application or oauth client + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -24,6 +26,11 @@ public class ClaimResource { this.auth = auth; } + /** + * Get the claims a client is allowed to ask for + * + * @return + */ @GET @Produces(MediaType.APPLICATION_JSON) public ClaimRepresentation getClaims() { @@ -31,6 +38,11 @@ public class ClaimResource { return ModelToRepresentation.toRepresentation(model); } + /** + * Set the cliams a client is allowed to ask for. + * + * @param rep + */ @PUT @Consumes(MediaType.APPLICATION_JSON) public void updateClaims(ClaimRepresentation rep) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java index 3c4d9a98c4..ac318b6494 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java @@ -30,6 +30,8 @@ import javax.ws.rs.core.UriInfo; import java.io.IOException; /** + * Base resource class for managing oauth clients + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -58,12 +60,22 @@ public class OAuthClientResource { auth.init(RealmAuth.Resource.CLIENT); } + /** + * Base path for managing allowed oauth client claims + * + * @return + */ @Path("claims") public ClaimResource getClaimResource() { return new ClaimResource(oauthClient, auth); } - + /** + * Update the oauth client + * + * @param rep + * @return + */ @PUT @Consumes(MediaType.APPLICATION_JSON) public Response update(final OAuthClientRepresentation rep) { @@ -78,7 +90,11 @@ public class OAuthClientResource { } } - + /** + * Get a representation of the oauth client + * + * @return + */ @GET @NoCache @Produces(MediaType.APPLICATION_JSON) @@ -88,6 +104,12 @@ public class OAuthClientResource { return OAuthClientManager.toRepresentation(oauthClient); } + /** + * Get an example keycloak.json file to use to configure the oauth client + * + * @return + * @throws IOException + */ @GET @NoCache @Path("installation") @@ -102,6 +124,10 @@ public class OAuthClientResource { return JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep); } + /** + * Remove the OAuth Client + * + */ @DELETE @NoCache public void deleteOAuthClient() { @@ -110,6 +136,12 @@ public class OAuthClientResource { realm.removeOAuthClient(oauthClient.getId()); } + + /** + * Generate a new client secret for the oauth client + * + * @return + */ @Path("client-secret") @POST @Produces("application/json") @@ -124,6 +156,11 @@ public class OAuthClientResource { return rep; } + /** + * Get the secret of the oauth client + * + * @return + */ @Path("client-secret") @GET @Produces("application/json") @@ -136,6 +173,11 @@ public class OAuthClientResource { return ModelToRepresentation.toRepresentation(model); } + /** + * Base path for managing the oauth client's scope + * + * @return + */ @Path("scope-mappings") public ScopeMappedResource getScopeMappedResource() { return new ScopeMappedResource(realm, auth, oauthClient, session); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java index 66da95e492..f80a8c95a4 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java @@ -50,6 +50,11 @@ public class OAuthClientsResource { auth.init(RealmAuth.Resource.CLIENT); } + /** + * Get a list of oauth clients in this realm. + * + * @return + */ @GET @Produces(MediaType.APPLICATION_JSON) @NoCache @@ -70,6 +75,13 @@ public class OAuthClientsResource { return rep; } + /** + * Create an oauth client + * + * @param uriInfo + * @param rep + * @return + */ @POST @Consumes(MediaType.APPLICATION_JSON) public Response createOAuthClient(final @Context UriInfo uriInfo, final OAuthClientRepresentation rep) { @@ -84,6 +96,12 @@ public class OAuthClientsResource { } } + /** + * Base path to manage one specific oauth client + * + * @param id oauth client's id (not clientId!) + * @return + */ @Path("{id}") public OAuthClientResource getOAuthClient(final @PathParam("id") String id) { auth.requireView(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java index 1107a3d4ec..cc2903fd4c 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -41,6 +41,8 @@ import java.util.List; import java.util.Map; /** + * Base resource class for the admin REST api of one realm + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -72,6 +74,11 @@ public class RealmAdminResource { auth.init(RealmAuth.Resource.REALM); } + /** + * Base path for managing applications under this realm. + * + * @return + */ @Path("applications") public ApplicationsResource getApplications() { ApplicationsResource applicationsResource = new ApplicationsResource(realm, auth); @@ -80,6 +87,11 @@ public class RealmAdminResource { return applicationsResource; } + /** + * base path for managing oauth clients in this realm + * + * @return + */ @Path("oauth-clients") public OAuthClientsResource getOAuthClients() { OAuthClientsResource oauth = new OAuthClientsResource(realm, auth, session); @@ -88,11 +100,22 @@ public class RealmAdminResource { return oauth; } + /** + * base path for managing realm-level roles of this realm + * + * @return + */ @Path("roles") public RoleContainerResource getRoleContainerResource() { return new RoleContainerResource(realm, auth, realm); } + /** + * Get the top-level representation of the realm. It will not include nested information like User, Application, or OAuth + * Client representations. + * + * @return + */ @GET @NoCache @Produces("application/json") @@ -109,6 +132,13 @@ public class RealmAdminResource { } } + /** + * Update the top-level information of this realm. Any user, roles, application, or oauth client information in the representation + * will be ignored. This will only update top-level attributes of the realm. + * + * @param rep + * @return + */ @PUT @Consumes("application/json") public Response updateRealm(final RealmRepresentation rep) { @@ -123,6 +153,10 @@ public class RealmAdminResource { } } + /** + * Delete this realm. + * + */ @DELETE public void deleteRealm() { auth.requireManage(); @@ -132,6 +166,11 @@ public class RealmAdminResource { } } + /** + * Base path for managing users in this realm. + * + * @return + */ @Path("users") public UsersResource users() { UsersResource users = new UsersResource(providers, realm, auth, tokenManager); @@ -140,6 +179,11 @@ public class RealmAdminResource { return users; } + /** + * Path for managing all realm-level or application-level roles defined in this realm by it's id. + * + * @return + */ @Path("roles-by-id") public RoleByIdResource rolesById() { RoleByIdResource resource = new RoleByIdResource(realm, auth); @@ -148,6 +192,10 @@ public class RealmAdminResource { return resource; } + /** + * Push the realm's revocation policy to any application that has an admin url associated with it. + * + */ @Path("push-revocation") @POST public void pushRevocation() { @@ -155,6 +203,11 @@ public class RealmAdminResource { new ResourceAdminManager().pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm); } + /** + * Removes all user sessions. Any application that has an admin url will also be told to invalidate any sessions + * they have. + * + */ @Path("logout-all") @POST public void logoutAll() { @@ -163,6 +216,12 @@ public class RealmAdminResource { new ResourceAdminManager().logoutAll(uriInfo.getRequestUri(), realm); } + /** + * Remove a specific user session. Any application that has an admin url will also be told to invalidate this + * particular session. + * + * @param sessionId + */ @Path("sessions/{session}") @DELETE public void deleteSession(@PathParam("session") String sessionId) { @@ -172,6 +231,12 @@ public class RealmAdminResource { new ResourceAdminManager().logoutSession(uriInfo.getRequestUri(), realm, session.getId()); } + /** + * Returns a JSON map. The key is the application name, the value is the number of sessions that currently are active + * with that application. Only application's that actually have a session associated with them will be in this map. + * + * @return + */ @Path("application-session-stats") @GET @NoCache @@ -187,6 +252,12 @@ public class RealmAdminResource { return stats; } + /** + * Any application that has an admin URL will be asked directly how many sessions they have active and what users + * are involved with those sessions. + * + * @return + */ @Path("session-stats") @GET @NoCache @@ -203,6 +274,11 @@ public class RealmAdminResource { return stats; } + /** + * View the audit provider and how it is configured. + * + * @return + */ @GET @Path("audit") @Produces("application/json") @@ -212,6 +288,11 @@ public class RealmAdminResource { return ModelToRepresentation.toAuditReprensetation(realm); } + /** + * Change the audit provider and/or it's configuration + * + * @param rep + */ @PUT @Path("audit") @Consumes("application/json") @@ -222,6 +303,17 @@ public class RealmAdminResource { new RealmManager(session).updateRealmAudit(rep, realm); } + /** + * Query audit events. Returns all events, or will query based on URL query parameters listed here + * + * @param client app or oauth client name + * @param event event type + * @param user user id + * @param ipAddress + * @param firstResult + * @param maxResults + * @return + */ @Path("audit/events") @GET @NoCache @@ -255,6 +347,10 @@ public class RealmAdminResource { return query.getResultList(); } + /** + * Delete all audit events. + * + */ @Path("audit/events") @DELETE public void clearAudit() { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java index 65de057e4f..50d5442942 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java @@ -41,6 +41,8 @@ import java.util.List; import java.util.Map; /** + * Top level resource for Admin REST API + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -71,10 +73,16 @@ public class RealmsAdminResource { @Context protected KeycloakApplication keycloak; + + /** + * Returns a list of realms. This list is filtered based on what realms the caller is allowed to view. + * + * @return + */ @GET @NoCache @Produces("application/json") - public List getRealms() { + public List getRealms() { RealmManager realmManager = new RealmManager(session); List reps = new ArrayList(); if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) { @@ -101,6 +109,13 @@ public class RealmsAdminResource { } } + /** + * Import a realm from a full representation of that realm. Realm name must be unique. + * + * @param uriInfo + * @param rep JSON representation + * @return + */ @POST @Consumes("application/json") public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) { @@ -127,6 +142,15 @@ public class RealmsAdminResource { } } + /** + * Upload a realm from a uploaded JSON file. The posted represenation is expected to be a multipart/form-data encapsulation + * of a JSON file. The same format a browser would use when uploading a file. + * + * @param uriInfo + * @param input multipart/form data + * @return + * @throws IOException + */ @POST @Consumes(MediaType.MULTIPART_FORM_DATA) public Response uploadRealm(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException { @@ -178,7 +202,13 @@ public class RealmsAdminResource { } } - + /** + * Base path for the admin REST API for one particular realm. + * + * @param headers + * @param name realm name (not id!) + * @return + */ @Path("{realm}") public RealmAdminResource getRealmAdmin(@Context final HttpHeaders headers, @PathParam("realm") final String name) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java index bb7ff14e5e..f14fc0643f 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java @@ -39,6 +39,12 @@ public class RoleByIdResource extends RoleResource { this.auth = auth; } + /** + * Get a specific role's representation + * + * @param id id of role + * @return + */ @Path("{role-id}") @GET @NoCache @@ -70,6 +76,11 @@ public class RoleByIdResource extends RoleResource { return roleModel; } + /** + * Delete this role + * + * @param id id of role + */ @Path("{role-id}") @DELETE @NoCache @@ -79,6 +90,12 @@ public class RoleByIdResource extends RoleResource { deleteRole(role); } + /** + * Update this role + * + * @param id id of role + * @param rep + */ @Path("{role-id}") @PUT @Consumes("application/json") @@ -88,6 +105,12 @@ public class RoleByIdResource extends RoleResource { updateRole(rep, role); } + /** + * Make this role a composite role by associating some child roles to it. + * + * @param id + * @param roles + */ @Path("{role-id}/composites") @POST @Consumes("application/json") @@ -97,6 +120,12 @@ public class RoleByIdResource extends RoleResource { addComposites(roles, role); } + /** + * If this role is a composite, return a set of its children + * + * @param id + * @return + */ @Path("{role-id}/composites") @GET @NoCache @@ -109,6 +138,12 @@ public class RoleByIdResource extends RoleResource { return getRoleComposites(role); } + /** + * Return a set of realm-level roles that are in the role's composite + * + * @param id + * @return + */ @Path("{role-id}/composites/realm") @GET @NoCache @@ -119,6 +154,13 @@ public class RoleByIdResource extends RoleResource { return getRealmRoleComposites(role); } + /** + * Return a set of application-level roles for a specific app that are in the role's composite + * + * @param id + * @param appName + * @return + */ @Path("{role-id}/composites/applications/{app}") @GET @NoCache @@ -130,7 +172,12 @@ public class RoleByIdResource extends RoleResource { return getApplicationRoleComposites(appName, role); } - + /** + * Remove the listed set of roles from this role's composite + * + * @param id + * @param roles + */ @Path("{role-id}/composites") @DELETE @Consumes("application/json") diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java index e33d74f95c..d1bb14980c 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java @@ -42,6 +42,11 @@ public class RoleContainerResource extends RoleResource { this.roleContainer = roleContainer; } + /** + * List all roles for this realm or application + * + * @return + */ @GET @NoCache @Produces("application/json") @@ -56,6 +61,13 @@ public class RoleContainerResource extends RoleResource { return roles; } + /** + * Create a new role for this realm or application + * + * @param uriInfo + * @param rep + * @return + */ @POST @Consumes("application/json") public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) { @@ -70,6 +82,12 @@ public class RoleContainerResource extends RoleResource { } } + /** + * Get a role by name + * + * @param roleName role's name (not id!) + * @return + */ @Path("{role-name}") @GET @NoCache @@ -84,6 +102,11 @@ public class RoleContainerResource extends RoleResource { return getRole(roleModel); } + /** + * Delete a role by name + * + * @param roleName role's name (not id!) + */ @Path("{role-name}") @DELETE @NoCache @@ -97,6 +120,13 @@ public class RoleContainerResource extends RoleResource { deleteRole(role); } + /** + * Update a role by name + * + * @param roleName role's name (not id!) + * @param rep + * @return + */ @Path("{role-name}") @PUT @Consumes("application/json") @@ -115,6 +145,12 @@ public class RoleContainerResource extends RoleResource { } } + /** + * Add a composite to this role + * + * @param roleName role's name (not id!) + * @param roles + */ @Path("{role-name}/composites") @POST @Consumes("application/json") @@ -128,6 +164,12 @@ public class RoleContainerResource extends RoleResource { addComposites(roles, role); } + /** + * List composites of this role + * + * @param roleName role's name (not id!) + * @return + */ @Path("{role-name}/composites") @GET @NoCache @@ -142,6 +184,12 @@ public class RoleContainerResource extends RoleResource { return getRoleComposites(role); } + /** + * Get realm-level roles of this role's composite + * + * @param roleName role's name (not id!) + * @return + */ @Path("{role-name}/composites/realm") @GET @NoCache @@ -156,6 +204,13 @@ public class RoleContainerResource extends RoleResource { return getRealmRoleComposites(role); } + /** + * An app-level roles for a specific app for this role's composite + * + * @param roleName role's name (not id!) + * @param appName + * @return + */ @Path("{role-name}/composites/application/{app}") @GET @NoCache @@ -172,6 +227,12 @@ public class RoleContainerResource extends RoleResource { } + /** + * Remove roles from this role's composite + * + * @param roleName role's name (not id!) + * @param roles roles to remove + */ @Path("{role-name}/composites") @DELETE @Consumes("application/json") diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java index 38d627635b..200e0ae9ed 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java @@ -28,6 +28,8 @@ import java.util.Map; import java.util.Set; /** + * Base class for managing the scope mappings of a specific client (application or oauth). + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -44,6 +46,11 @@ public class ScopeMappedResource { this.session = session; } + /** + * Get all scope mappings for this client + * + * @return + */ @GET @Produces("application/json") @NoCache @@ -82,6 +89,11 @@ public class ScopeMappedResource { return all; } + /** + * Get list of realm-level roles associated with this client's scope. + * + * @return + */ @Path("realm") @GET @Produces("application/json") @@ -97,6 +109,11 @@ public class ScopeMappedResource { return realmMappingsRep; } + /** + * Get list of realm-level roles that are available to attach to this client's scope. + * + * @return + */ @Path("realm/available") @GET @Produces("application/json") @@ -117,6 +134,13 @@ public class ScopeMappedResource { return available; } + /** + * Get all effective realm-level roles that are associated with this client's scope. What this does is recurse + * any composite roles associated with the client's scope and adds the roles to this lists. The method is really + * to show a comprehensive total view of realm-level roles associated with the client. + * + * @return + */ @Path("realm/composite") @GET @Produces("application/json") @@ -136,6 +160,11 @@ public class ScopeMappedResource { return composite; } + /** + * Add a set of realm-level roles to the client's scope + * + * @param roles + */ @Path("realm") @POST @Consumes("application/json") @@ -153,6 +182,11 @@ public class ScopeMappedResource { } + /** + * Remove a set of realm-level roles from the client's scope + * + * @param roles + */ @Path("realm") @DELETE @Consumes("application/json") @@ -176,6 +210,12 @@ public class ScopeMappedResource { } } + /** + * Get the roles associated with a client's scope for a specific application. + * + * @param appName roles associated with client's scope for a specific application + * @return + */ @Path("applications/{app}") @GET @Produces("application/json") @@ -197,6 +237,12 @@ public class ScopeMappedResource { return mapRep; } + /** + * The available application-level roles that can be associated with the client's scope + * + * @param appName available roles for a specific application + * @return + */ @Path("applications/{app}/available") @GET @Produces("application/json") @@ -214,6 +260,12 @@ public class ScopeMappedResource { return getAvailable(roles); } + /** + * Get effective application roles that are associated with the client's scope for a specific application. + * + * @param appName effective roles for a specific app + * @return + */ @Path("applications/{app}/composite") @GET @Produces("application/json") @@ -231,6 +283,12 @@ public class ScopeMappedResource { return getComposite(roles); } + /** + * Add application-level roles to the client's scope + * + * @param appName + * @param roles + */ @Path("applications/{app}") @POST @Consumes("application/json") @@ -253,6 +311,12 @@ public class ScopeMappedResource { } + /** + * Remove application-level roles from the client's scope. + * + * @param appName + * @param roles + */ @Path("applications/{app}") @DELETE @Consumes("application/json") diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java old mode 100644 new mode 100755 index 028f198a31..86a1acc310 --- a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java @@ -26,6 +26,11 @@ public class ServerInfoAdminResource { @Context private ProviderSession providers; + /** + * Returns a list of themes, social providers, auth providers, and audit listeners available on this server + * + * @return + */ @GET public ServerInfoRepresentation getInfo() { ServerInfoRepresentation info = new ServerInfoRepresentation(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index e4cc8c1ab8..8297e7fcb2 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -58,6 +58,8 @@ import java.util.Set; import java.util.concurrent.TimeUnit; /** + * Base resource for managing users + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -91,6 +93,13 @@ public class UsersResource { protected KeycloakSession session; + /** + * Update the user + * + * @param username user name (not id!) + * @param rep + * @return + */ @Path("{username}") @PUT @Consumes("application/json") @@ -110,6 +119,13 @@ public class UsersResource { } } + /** + * Create a new user. Must be a unique username! + * + * @param uriInfo + * @param rep + * @return + */ @POST @Consumes("application/json") public Response createUser(final @Context UriInfo uriInfo, final UserRepresentation rep) { @@ -153,6 +169,12 @@ public class UsersResource { } } + /** + * Get represenation of the user + * + * @param username username (not id!) + * @return + */ @Path("{username}") @GET @NoCache @@ -167,6 +189,15 @@ public class UsersResource { return ModelToRepresentation.toRepresentation(user); } + /** + * For each application with an admin URL, query them for the set of users logged in. This not as reliable + * as getSessions(). + * + * @See getSessions + * + * @param username + * @return + */ @Path("{username}/session-stats") @GET @NoCache @@ -188,6 +219,12 @@ public class UsersResource { return stats; } + /** + * List set of sessions associated with this user. + * + * @param username + * @return + */ @Path("{username}/sessions") @GET @NoCache @@ -208,6 +245,12 @@ public class UsersResource { return reps; } + /** + * List set of social logins associated with this user. + * + * @param username + * @return + */ @Path("{username}/social-links") @GET @NoCache @@ -227,6 +270,12 @@ public class UsersResource { return result; } + /** + * Remove all user sessions associated with this user. And, for all applications that have an admin URL, tell + * them to invalidate the sessions for this particular user. + * + * @param username username (not id!) + */ @Path("{username}/logout") @POST public void logout(final @PathParam("username") String username) { @@ -241,7 +290,11 @@ public class UsersResource { new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), null); } - + /** + * delete this user + * + * @param username username (not id!) + */ @Path("{username}") @DELETE @NoCache @@ -251,6 +304,16 @@ public class UsersResource { realm.removeUser(username); } + /** + * Query list of users. May pass in query criteria + * + * @param search string contained in username, first or last name, or email + * @param last + * @param first + * @param email + * @param username + * @return + */ @GET @NoCache @Produces("application/json") @@ -294,6 +357,12 @@ public class UsersResource { return results; } + /** + * Get role mappings for this user + * + * @param username username (not id!) + * @return + */ @Path("{username}/role-mappings") @GET @Produces("application/json") @@ -339,6 +408,12 @@ public class UsersResource { return all; } + /** + * Get realm-level role mappings for this user + * + * @param username username (not id!) + * @return + */ @Path("{username}/role-mappings/realm") @GET @Produces("application/json") @@ -359,6 +434,12 @@ public class UsersResource { return realmMappingsRep; } + /** + * Effective realm-level role mappings for this user. Will recurse all composite roles to get this list. + * + * @param username username (not id!) + * @return + */ @Path("{username}/role-mappings/realm/composite") @GET @Produces("application/json") @@ -381,6 +462,12 @@ public class UsersResource { return realmMappingsRep; } + /** + * Realm-level roles that can be mapped to this user + * + * @param username username (not id!) + * @return + */ @Path("{username}/role-mappings/realm/available") @GET @Produces("application/json") @@ -397,6 +484,12 @@ public class UsersResource { return getAvailableRoles(user, available); } + /** + * Add realm-level role mappings + * + * @param username username (not id!) + * @param roles + */ @Path("{username}/role-mappings/realm") @POST @Consumes("application/json") @@ -420,6 +513,12 @@ public class UsersResource { } + /** + * Delete realm-level role mappings + * + * @param username username (not id!) + * @param roles + */ @Path("{username}/role-mappings/realm") @DELETE @Consumes("application/json") @@ -449,6 +548,13 @@ public class UsersResource { } } + /** + * Get application-level role mappings for this user for a specific app + * + * @param username username (not id!) + * @param appName app name (not id!) + * @return + */ @Path("{username}/role-mappings/applications/{app}") @GET @Produces("application/json") @@ -478,6 +584,13 @@ public class UsersResource { return mapRep; } + /** + * Get effective application-level role mappings. This recurses any composite roles + * + * @param username username (not id!) + * @param appName app name (not id!) + * @return + */ @Path("{username}/role-mappings/applications/{app}/composite") @GET @Produces("application/json") @@ -507,6 +620,13 @@ public class UsersResource { return mapRep; } + /** + * Get available application-level roles that can be mapped to the user + * + * @param username username (not id!) + * @param appName app name (not id!) + * @return + */ @Path("{username}/role-mappings/applications/{app}/available") @GET @Produces("application/json") @@ -544,6 +664,13 @@ public class UsersResource { return mappings; } + /** + * Add applicaiton-level roles to the user role mapping. + * + * @param username username (not id!) + * @param appName app name (not id!) + * @param roles + */ @Path("{username}/role-mappings/applications/{app}") @POST @Consumes("application/json") @@ -572,6 +699,13 @@ public class UsersResource { } + /** + * Delete application-level roles from user role mapping. + * + * @param username username (not id!) + * @param appName app name (not id!) + * @param roles + */ @Path("{username}/role-mappings/applications/{app}") @DELETE @Consumes("application/json") @@ -610,6 +744,13 @@ public class UsersResource { } } + /** + * Set up a temporary password for this user. User will have to reset this temporary password when they log + * in next. + * + * @param username username (not id!) + * @param pass temporary password + */ @Path("{username}/reset-password") @PUT @Consumes("application/json") @@ -629,6 +770,11 @@ public class UsersResource { user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD); } + /** + * + * + * @param username username (not id!) + */ @Path("{username}/remove-totp") @PUT @Consumes("application/json") @@ -643,6 +789,12 @@ public class UsersResource { user.setTotp(false); } + /** + * Send an email to the user with a link they can click to reset their password + * + * @param username username (not id!) + * @return + */ @Path("{username}/reset-password-email") @PUT @Consumes("application/json")