From 31f1fd3d665b882586322a9a56dbef30401b6201 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Mon, 14 Mar 2022 08:45:30 +0200 Subject: [PATCH 1/2] Add first version of Keycloak admin client based on Reactive REST Client This is pretty much a straight copy of the existing Keycloak code that removes various things that are not supported by Quarkus. Furthermore, the base package was changed because there are cases where the upstream Keycloak client still needs to be used (for example in a QuarkusTestResourceLifecycleManager which runs before the Quarkus application and therefore cannot use any Quarkus infrastructure) Fixes: #20505 --- bom/application/pom.xml | 10 + devtools/bom-descriptor-json/pom.xml | 13 + docs/pom.xml | 13 + .../deployment/pom.xml | 54 ++++ .../keycloak-admin-client-reactive/pom.xml | 20 ++ .../runtime/pom.xml | 47 +++ .../admin/client/reactive/Config.java | 119 +++++++ .../admin/client/reactive/Keycloak.java | 157 +++++++++ .../client/reactive/KeycloakBuilder.java | 155 +++++++++ .../resource/AggregatePoliciesResource.java | 48 +++ .../resource/AggregatePolicyResource.java | 64 ++++ .../resource/AttackDetectionResource.java | 47 +++ .../AuthenticationManagementResource.java | 204 ++++++++++++ .../resource/AuthorizationResource.java | 64 ++++ .../reactive/resource/BasicAuthFilter.java | 48 +++ .../reactive/resource/BearerAuthFilter.java | 77 +++++ .../ClientAttributeCertificateResource.java | 105 ++++++ .../resource/ClientInitialAccessResource.java | 52 +++ .../ClientPoliciesPoliciesResource.java | 23 ++ .../ClientPoliciesProfilesResource.java | 30 ++ .../resource/ClientPoliciesResource.java | 48 +++ .../resource/ClientPolicyResource.java | 64 ++++ .../ClientRegistrationPolicyResource.java | 38 +++ .../reactive/resource/ClientResource.java | 210 ++++++++++++ .../resource/ClientScopePoliciesResource.java | 44 +++ .../resource/ClientScopeResource.java | 52 +++ .../resource/ClientScopesResource.java | 49 +++ .../reactive/resource/ClientsResource.java | 70 ++++ .../reactive/resource/ComponentResource.java | 58 ++++ .../reactive/resource/ComponentsResource.java | 63 ++++ .../resource/GroupPoliciesResource.java | 48 +++ .../resource/GroupPolicyResource.java | 64 ++++ .../reactive/resource/GroupResource.java | 150 +++++++++ .../reactive/resource/GroupsResource.java | 144 +++++++++ .../resource/IdentityProviderResource.java | 87 +++++ .../resource/IdentityProvidersResource.java | 68 ++++ .../reactive/resource/JSPoliciesResource.java | 48 +++ .../reactive/resource/JSPolicyResource.java | 64 ++++ .../client/reactive/resource/KeyResource.java | 35 ++ .../resource/PermissionsResource.java | 31 ++ .../reactive/resource/PoliciesResource.java | 108 +++++++ .../reactive/resource/PolicyResource.java | 73 +++++ .../resource/ProtocolMappersResource.java | 72 +++++ .../resource/RealmLocalizationResource.java | 66 ++++ .../reactive/resource/RealmResource.java | 295 +++++++++++++++++ .../reactive/resource/RealmsResource.java | 49 +++ .../resource/RegexPoliciesResource.java | 37 +++ .../resource/ResourcePermissionResource.java | 64 ++++ .../resource/ResourcePermissionsResource.java | 48 +++ .../reactive/resource/ResourceResource.java | 52 +++ .../resource/ResourceScopeResource.java | 52 +++ .../resource/ResourceScopesResource.java | 54 ++++ .../reactive/resource/ResourcesResource.java | 67 ++++ .../reactive/resource/RoleByIdResource.java | 92 ++++++ .../resource/RoleMappingResource.java | 45 +++ .../resource/RolePoliciesResource.java | 48 +++ .../reactive/resource/RolePolicyResource.java | 64 ++++ .../reactive/resource/RoleResource.java | 158 +++++++++ .../reactive/resource/RoleScopeResource.java | 63 ++++ .../reactive/resource/RolesResource.java | 132 ++++++++ .../resource/ScopePermissionResource.java | 69 ++++ .../resource/ScopePermissionsResource.java | 48 +++ .../reactive/resource/ServerInfoResource.java | 37 +++ .../resource/TimePoliciesResource.java | 48 +++ .../reactive/resource/TimePolicyResource.java | 64 ++++ .../resource/UserPoliciesResource.java | 48 +++ .../reactive/resource/UserPolicyResource.java | 64 ++++ .../resource/UserProfileResource.java | 40 +++ .../reactive/resource/UserResource.java | 300 ++++++++++++++++++ .../resource/UserStorageProviderResource.java | 90 ++++++ .../reactive/resource/UsersResource.java | 271 ++++++++++++++++ .../client/reactive/token/TokenManager.java | 141 ++++++++ .../client/reactive/token/TokenService.java | 45 +++ .../src/main/resources/META-INF/beans.xml | 0 .../resources/META-INF/quarkus-extension.yaml | 12 + extensions/pom.xml | 1 + 76 files changed, 5702 insertions(+) create mode 100644 extensions/keycloak-admin-client-reactive/deployment/pom.xml create mode 100644 extensions/keycloak-admin-client-reactive/pom.xml create mode 100644 extensions/keycloak-admin-client-reactive/runtime/pom.xml create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/Config.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/Keycloak.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/KeycloakBuilder.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AggregatePoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AggregatePolicyResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AttackDetectionResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AuthenticationManagementResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AuthorizationResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/BasicAuthFilter.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/BearerAuthFilter.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientAttributeCertificateResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientInitialAccessResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesPoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesProfilesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPolicyResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientRegistrationPolicyResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopePoliciesResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopeResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopesResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientsResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ComponentResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ComponentsResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupPoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupPolicyResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupsResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/IdentityProviderResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/IdentityProvidersResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/JSPoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/JSPolicyResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/KeyResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PermissionsResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PolicyResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ProtocolMappersResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmLocalizationResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmsResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RegexPoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcePermissionResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcePermissionsResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceScopeResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceScopesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcesResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleByIdResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleMappingResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolePoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolePolicyResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleScopeResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ScopePermissionResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ScopePermissionsResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ServerInfoResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/TimePoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/TimePolicyResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserPoliciesResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserPolicyResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserProfileResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserStorageProviderResource.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UsersResource.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/token/TokenManager.java create mode 100755 extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/token/TokenService.java create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/resources/META-INF/beans.xml create mode 100644 extensions/keycloak-admin-client-reactive/runtime/src/main/resources/META-INF/quarkus-extension.yaml diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 1d3e049a1d274..f1ef876d666bd 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -840,6 +840,16 @@ quarkus-keycloak-admin-client-deployment ${project.version} + + io.quarkus + quarkus-keycloak-admin-client-reactive + ${project.version} + + + io.quarkus + quarkus-keycloak-admin-client-reactive-deployment + ${project.version} + io.quarkus quarkus-flyway diff --git a/devtools/bom-descriptor-json/pom.xml b/devtools/bom-descriptor-json/pom.xml index fd19d18d966bb..07142834099b2 100644 --- a/devtools/bom-descriptor-json/pom.xml +++ b/devtools/bom-descriptor-json/pom.xml @@ -1072,6 +1072,19 @@ + + io.quarkus + quarkus-keycloak-admin-client-reactive + ${project.version} + pom + test + + + * + * + + + io.quarkus quarkus-keycloak-authorization diff --git a/docs/pom.xml b/docs/pom.xml index a2f3d883cb01a..005bf919f383a 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -1032,6 +1032,19 @@ + + io.quarkus + quarkus-keycloak-admin-client-reactive-deployment + ${project.version} + pom + test + + + * + * + + + io.quarkus quarkus-keycloak-authorization-deployment diff --git a/extensions/keycloak-admin-client-reactive/deployment/pom.xml b/extensions/keycloak-admin-client-reactive/deployment/pom.xml new file mode 100644 index 0000000000000..d87e0b707e7e3 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/deployment/pom.xml @@ -0,0 +1,54 @@ + + + + quarkus-keycloak-admin-client-reactive-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + + quarkus-keycloak-admin-client-reactive-deployment + Quarkus - Keycloak Admin Client - Reactive - Deployment + + + + io.quarkus + quarkus-keycloak-admin-client-reactive + + + io.quarkus + quarkus-rest-client-reactive-jackson-deployment + + + + io.quarkus + quarkus-junit5-internal + test + + + io.rest-assured + rest-assured + test + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${project.version} + + + + + + + + diff --git a/extensions/keycloak-admin-client-reactive/pom.xml b/extensions/keycloak-admin-client-reactive/pom.xml new file mode 100644 index 0000000000000..7398fed5bf64f --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/pom.xml @@ -0,0 +1,20 @@ + + + + quarkus-extensions-parent + io.quarkus + 999-SNAPSHOT + ../pom.xml + + 4.0.0 + + quarkus-keycloak-admin-client-reactive-parent + Quarkus - Keycloak Admin Client - Reactive + pom + + deployment + runtime + + diff --git a/extensions/keycloak-admin-client-reactive/runtime/pom.xml b/extensions/keycloak-admin-client-reactive/runtime/pom.xml new file mode 100644 index 0000000000000..ff00406772cfa --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/pom.xml @@ -0,0 +1,47 @@ + + + + quarkus-keycloak-admin-client-reactive-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + + quarkus-keycloak-admin-client-reactive + Quarkus - Keycloak Admin Client - Reactive - Runtime + Administer a Keycloak Instance + + + + io.quarkus + quarkus-rest-client-reactive-jackson + + + org.keycloak + keycloak-core + + + + + + + io.quarkus + quarkus-bootstrap-maven-plugin + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${project.version} + + + + + + + diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/Config.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/Config.java new file mode 100644 index 0000000000000..b8342ccc9fafe --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/Config.java @@ -0,0 +1,119 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive; + +import static org.keycloak.OAuth2Constants.CLIENT_CREDENTIALS; +import static org.keycloak.OAuth2Constants.PASSWORD; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public class Config { + + private String serverUrl; + private String realm; + private String username; + private String password; + private String clientId; + private String clientSecret; + private String grantType; + + public Config(String serverUrl, String realm, String username, String password, String clientId, String clientSecret) { + this(serverUrl, realm, username, password, clientId, clientSecret, PASSWORD); + } + + public Config(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, + String grantType) { + this.serverUrl = serverUrl; + this.realm = realm; + this.username = username; + this.password = password; + this.clientId = clientId; + this.clientSecret = clientSecret; + this.grantType = grantType; + checkGrantType(grantType); + } + + public String getServerUrl() { + return serverUrl; + } + + public void setServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + } + + public String getRealm() { + return realm; + } + + public void setRealm(String realm) { + this.realm = realm; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public boolean isPublicClient() { + return clientSecret == null; + } + + public String getGrantType() { + return grantType; + } + + public void setGrantType(String grantType) { + this.grantType = grantType; + checkGrantType(grantType); + } + + public static void checkGrantType(String grantType) { + if (grantType != null && !PASSWORD.equals(grantType) && !CLIENT_CREDENTIALS.equals(grantType)) { + throw new IllegalArgumentException("Unsupported grantType: " + grantType + + " (only " + PASSWORD + " and " + CLIENT_CREDENTIALS + " are supported)"); + } + } +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/Keycloak.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/Keycloak.java new file mode 100755 index 0000000000000..3a47c85fada86 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/Keycloak.java @@ -0,0 +1,157 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive; + +import java.net.URI; + +import javax.ws.rs.client.Client; + +import org.jboss.resteasy.reactive.client.impl.ClientBuilderImpl; +import org.jboss.resteasy.reactive.client.impl.WebTargetImpl; +import org.jboss.resteasy.reactive.server.jackson.JacksonBasicMessageBodyReader; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.ArcContainer; +import io.quarkus.arc.InstanceHandle; +import io.quarkus.keycloak.admin.client.reactive.resource.BearerAuthFilter; +import io.quarkus.keycloak.admin.client.reactive.resource.RealmResource; +import io.quarkus.keycloak.admin.client.reactive.resource.RealmsResource; +import io.quarkus.keycloak.admin.client.reactive.resource.ServerInfoResource; +import io.quarkus.keycloak.admin.client.reactive.token.TokenManager; +import io.quarkus.rest.client.reactive.jackson.runtime.serialisers.ClientJacksonMessageBodyWriter; + +/** + * Provides a Keycloak client. + * To customize the underling client, use a {@link KeycloakBuilder} to create a Keycloak client. + * + * @author rodrigo.sasaki@icarros.com.br + * @see KeycloakBuilder + */ +public class Keycloak implements AutoCloseable { + private final TokenManager tokenManager; + private final String authToken; + private final WebTargetImpl target; + private final Client client; + private volatile boolean closed = false; + + Keycloak(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, + String grantType, String authtoken) { + Config config = new Config(serverUrl, realm, username, password, clientId, clientSecret, grantType); + ClientBuilderImpl clientBuilder = new ClientBuilderImpl(); + clientBuilder = registerJacksonProviders(clientBuilder); + client = clientBuilder.build(); + authToken = authtoken; + tokenManager = authtoken == null ? new TokenManager(config, client) : null; + + target = (WebTargetImpl) client.target(config.getServerUrl()); + target.register(newAuthFilter()); + } + + // this code is much more complicated than expected because it needs to handle various permutations + // where beans may or may not exist + private ClientBuilderImpl registerJacksonProviders(ClientBuilderImpl clientBuilder) { + ArcContainer arcContainer = Arc.container(); + if (arcContainer == null) { + ObjectMapper objectMapper = new ObjectMapper(); + clientBuilder = clientBuilder + .register(new JacksonBasicMessageBodyReader(objectMapper)) + .register(new ClientJacksonMessageBodyWriter(objectMapper)); + } else { + InstanceHandle objectMapperInstance = arcContainer.instance(ObjectMapper.class); + ObjectMapper objectMapper = null; + + InstanceHandle readerInstance = arcContainer + .instance(JacksonBasicMessageBodyReader.class); + if (readerInstance.isAvailable()) { + clientBuilder = clientBuilder.register(readerInstance.get()); + } else { + objectMapper = getObjectMapper(objectMapper, objectMapperInstance); + clientBuilder = clientBuilder.register(new JacksonBasicMessageBodyReader(objectMapper)); + } + + InstanceHandle writerInstance = arcContainer + .instance(ClientJacksonMessageBodyWriter.class); + if (writerInstance.isAvailable()) { + clientBuilder = clientBuilder.register(writerInstance.get()); + } else { + objectMapper = getObjectMapper(objectMapper, objectMapperInstance); + clientBuilder = clientBuilder.register(new ClientJacksonMessageBodyWriter(objectMapper)); + } + } + return clientBuilder; + } + + // the whole idea here is to reuse the ObjectMapper instance + private ObjectMapper getObjectMapper(ObjectMapper value, + InstanceHandle objectMapperInstance) { + if (value == null) { + return objectMapperInstance.isAvailable() ? objectMapperInstance.get() : new ObjectMapper(); + } + return value; + } + + private BearerAuthFilter newAuthFilter() { + return authToken != null ? new BearerAuthFilter(authToken) : new BearerAuthFilter(tokenManager); + } + + public RealmsResource realms() { + return target.proxy(RealmsResource.class); + } + + public RealmResource realm(String realmName) { + return realms().realm(realmName); + } + + public ServerInfoResource serverInfo() { + return target.proxy(ServerInfoResource.class); + } + + public TokenManager tokenManager() { + return tokenManager; + } + + /** + * Create a secure proxy based on an absolute URI. + * All set up with appropriate token + * + * @param proxyClass + * @param absoluteURI + * @param + * @return + */ + public T proxy(Class proxyClass, URI absoluteURI) { + return ((WebTargetImpl) client.target(absoluteURI)).register(newAuthFilter()).proxy(proxyClass); + } + + /** + * Closes the underlying client. After calling this method, this Keycloak instance cannot be reused. + */ + @Override + public void close() { + closed = true; + client.close(); + } + + /** + * @return true if the underlying client is closed. + */ + public boolean isClosed() { + return closed; + } +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/KeycloakBuilder.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/KeycloakBuilder.java new file mode 100644 index 0000000000000..56331dc37ae10 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/KeycloakBuilder.java @@ -0,0 +1,155 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive; + +import static org.keycloak.OAuth2Constants.CLIENT_CREDENTIALS; +import static org.keycloak.OAuth2Constants.PASSWORD; + +/** + * Provides a {@link Keycloak} client builder with the ability to customize the underlying + * REST Client used to communicate with the Keycloak server. + *

+ *

+ * Example usage with a connection pool size of 20: + *

+ * + *
+ * Keycloak keycloak = KeycloakBuilder.builder()
+ *         .serverUrl("https://sso.example.com/auth")
+ *         .realm("realm")
+ *         .username("user")
+ *         .password("pass")
+ *         .clientId("client")
+ *         .clientSecret("secret")
+ *         .resteasyClient(new ResteasyClientBuilder().connectionPoolSize(20).build())
+ *         .build();
+ * 
+ *

+ * Example usage with grant_type=client_credentials + *

+ * + *
+ * Keycloak keycloak = KeycloakBuilder.builder()
+ *         .serverUrl("https://sso.example.com/auth")
+ *         .realm("example")
+ *         .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
+ *         .clientId("client")
+ *         .clientSecret("secret")
+ *         .build();
+ * 
+ * + * @author Scott Rossillo + */ +public class KeycloakBuilder { + private String serverUrl; + private String realm; + private String username; + private String password; + private String clientId; + private String clientSecret; + private String grantType; + private String authorization; + + public KeycloakBuilder serverUrl(String serverUrl) { + this.serverUrl = serverUrl; + return this; + } + + public KeycloakBuilder realm(String realm) { + this.realm = realm; + return this; + } + + public KeycloakBuilder grantType(String grantType) { + Config.checkGrantType(grantType); + this.grantType = grantType; + return this; + } + + public KeycloakBuilder username(String username) { + this.username = username; + return this; + } + + public KeycloakBuilder password(String password) { + this.password = password; + return this; + } + + public KeycloakBuilder clientId(String clientId) { + this.clientId = clientId; + return this; + } + + public KeycloakBuilder clientSecret(String clientSecret) { + this.clientSecret = clientSecret; + return this; + } + + public KeycloakBuilder authorization(String auth) { + this.authorization = auth; + return this; + } + + /** + * Builds a new Keycloak client from this builder. + */ + public Keycloak build() { + if (serverUrl == null) { + throw new IllegalStateException("serverUrl required"); + } + + if (realm == null) { + throw new IllegalStateException("realm required"); + } + + if (authorization == null && grantType == null) { + grantType = PASSWORD; + } + + if (PASSWORD.equals(grantType)) { + if (username == null) { + throw new IllegalStateException("username required"); + } + + if (password == null) { + throw new IllegalStateException("password required"); + } + } else if (CLIENT_CREDENTIALS.equals(grantType)) { + if (clientSecret == null) { + throw new IllegalStateException("clientSecret required with grant_type=client_credentials"); + } + } + + if (authorization == null && clientId == null) { + throw new IllegalStateException("clientId required"); + } + + return new Keycloak(serverUrl, realm, username, password, clientId, clientSecret, grantType, authorization); + } + + private KeycloakBuilder() { + } + + /** + * Returns a new Keycloak builder. + */ + public static KeycloakBuilder builder() { + return new KeycloakBuilder(); + } +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AggregatePoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AggregatePoliciesResource.java new file mode 100644 index 0000000000000..3bd6c0548bfcc --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AggregatePoliciesResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface AggregatePoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(AggregatePolicyRepresentation representation); + + @Path("{id}") + AggregatePolicyResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + AggregatePolicyRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AggregatePolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AggregatePolicyResource.java new file mode 100644 index 0000000000000..58f268811066e --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AggregatePolicyResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation; +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; + +/** + * @author Pedro Igor + */ +public interface AggregatePolicyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + AggregatePolicyRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(AggregatePolicyRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AttackDetectionResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AttackDetectionResource.java new file mode 100644 index 0000000000000..79a2bc6a773d7 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AttackDetectionResource.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.Map; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +/** + * @author Stian Thorgersen + */ +public interface AttackDetectionResource { + + @GET + @Path("brute-force/users/{userId}") + @Produces(MediaType.APPLICATION_JSON) + Map bruteForceUserStatus(@PathParam("userId") String userId); + + @Path("brute-force/users/{userId}") + @DELETE + void clearBruteForceForUser(@PathParam("userId") String userId); + + @Path("brute-force/users") + @DELETE + void clearAllBruteForce(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AuthenticationManagementResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AuthenticationManagementResource.java new file mode 100644 index 0000000000000..d356aeda7d19c --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AuthenticationManagementResource.java @@ -0,0 +1,204 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; +import org.keycloak.representations.idm.AuthenticationExecutionRepresentation; +import org.keycloak.representations.idm.AuthenticationFlowRepresentation; +import org.keycloak.representations.idm.AuthenticatorConfigInfoRepresentation; +import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; +import org.keycloak.representations.idm.ConfigPropertyRepresentation; +import org.keycloak.representations.idm.RequiredActionProviderRepresentation; +import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation; + +/** + * @author Marko Strukelj + */ +public interface AuthenticationManagementResource { + + @GET + @Path("/form-providers") + @Produces(MediaType.APPLICATION_JSON) + List> getFormProviders(); + + @Path("/authenticator-providers") + @GET + @Produces(MediaType.APPLICATION_JSON) + List> getAuthenticatorProviders(); + + @Path("/client-authenticator-providers") + @GET + @Produces(MediaType.APPLICATION_JSON) + List> getClientAuthenticatorProviders(); + + @Path("/form-action-providers") + @GET + @Produces(MediaType.APPLICATION_JSON) + List> getFormActionProviders(); + + @Path("/flows") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getFlows(); + + @Path("/flows") + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response createFlow(AuthenticationFlowRepresentation model); + + @Path("/flows/{id}") + @GET + @Produces(MediaType.APPLICATION_JSON) + AuthenticationFlowRepresentation getFlow(@PathParam("id") String id); + + @Path("/flows/{id}") + @DELETE + void deleteFlow(@PathParam("id") String id); + + @Path("/flows/{flowAlias}/copy") + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response copy(@PathParam("flowAlias") String flowAlias, Map data); + + @Path("/flows/{id}") + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updateFlow(@PathParam("id") String id, AuthenticationFlowRepresentation flow); + + @Path("/flows/{flowAlias}/executions/flow") + @POST + @Consumes(MediaType.APPLICATION_JSON) + void addExecutionFlow(@PathParam("flowAlias") String flowAlias, Map data); + + @Path("/flows/{flowAlias}/executions/execution") + @POST + @Consumes(MediaType.APPLICATION_JSON) + void addExecution(@PathParam("flowAlias") String flowAlias, Map data); + + @Path("/flows/{flowAlias}/executions") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getExecutions(@PathParam("flowAlias") String flowAlias); + + @Path("/flows/{flowAlias}/executions") + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updateExecutions(@PathParam("flowAlias") String flowAlias, AuthenticationExecutionInfoRepresentation rep); + + @Path("/executions") + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response addExecution(AuthenticationExecutionRepresentation model); + + @Path("/executions/{executionId}") + @GET + @Produces(MediaType.APPLICATION_JSON) + AuthenticationExecutionRepresentation getExecution(final @PathParam("executionId") String executionId); + + @Path("/executions/{executionId}/raise-priority") + @POST + void raisePriority(@PathParam("executionId") String execution); + + @Path("/executions/{executionId}/lower-priority") + @POST + void lowerPriority(@PathParam("executionId") String execution); + + @Path("/executions/{executionId}") + @DELETE + void removeExecution(@PathParam("executionId") String execution); + + @Path("/executions/{executionId}/config") + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response newExecutionConfig(@PathParam("executionId") String executionId, AuthenticatorConfigRepresentation config); + + @Path("unregistered-required-actions") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getUnregisteredRequiredActions(); + + @Path("register-required-action") + @POST + @Consumes(MediaType.APPLICATION_JSON) + void registerRequiredAction(RequiredActionProviderSimpleRepresentation action); + + @Path("required-actions") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getRequiredActions(); + + @Path("required-actions/{alias}") + @GET + @Produces(MediaType.APPLICATION_JSON) + RequiredActionProviderRepresentation getRequiredAction(@PathParam("alias") String alias); + + @Path("required-actions/{alias}") + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updateRequiredAction(@PathParam("alias") String alias, RequiredActionProviderRepresentation rep); + + @Path("required-actions/{alias}") + @DELETE + void removeRequiredAction(@PathParam("alias") String alias); + + @Path("required-actions/{alias}/raise-priority") + @POST + void raiseRequiredActionPriority(@PathParam("alias") String alias); + + @Path("required-actions/{alias}/lower-priority") + @POST + void lowerRequiredActionPriority(@PathParam("alias") String alias); + + @Path("config-description/{providerId}") + @GET + @Produces(MediaType.APPLICATION_JSON) + AuthenticatorConfigInfoRepresentation getAuthenticatorConfigDescription(@PathParam("providerId") String providerId); + + @Path("per-client-config-description") + @GET + @Produces(MediaType.APPLICATION_JSON) + Map> getPerClientConfigDescription(); + + @Path("config/{id}") + @GET + @Produces(MediaType.APPLICATION_JSON) + AuthenticatorConfigRepresentation getAuthenticatorConfig(@PathParam("id") String id); + + @Path("config/{id}") + @DELETE + void removeAuthenticatorConfig(@PathParam("id") String id); + + @Path("config/{id}") + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updateAuthenticatorConfig(@PathParam("id") String id, AuthenticatorConfigRepresentation config); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AuthorizationResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AuthorizationResource.java new file mode 100644 index 0000000000000..af003489e82fc --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/AuthorizationResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; + +/** + * @author Pedro Igor + */ +public interface AuthorizationResource { + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + void update(ResourceServerRepresentation server); + + @GET + @Produces(MediaType.APPLICATION_JSON) + ResourceServerRepresentation getSettings(); + + @Path("/import") + @POST + @Consumes(MediaType.APPLICATION_JSON) + void importSettings(ResourceServerRepresentation server); + + @Path("/settings") + @GET + @Produces(MediaType.APPLICATION_JSON) + ResourceServerRepresentation exportSettings(); + + @Path("/resource") + ResourcesResource resources(); + + @Path("/scope") + ResourceScopesResource scopes(); + + @Path("/policy") + PoliciesResource policies(); + + @Path("/permission") + PermissionsResource permissions(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/BasicAuthFilter.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/BasicAuthFilter.java new file mode 100644 index 0000000000000..16873fba46f97 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/BasicAuthFilter.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.io.IOException; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientRequestFilter; +import javax.ws.rs.core.HttpHeaders; + +import org.keycloak.common.util.Base64; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public class BasicAuthFilter implements ClientRequestFilter { + + private final String username; + private final String password; + + public BasicAuthFilter(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + String pair = username + ":" + password; + String authHeader = "Basic " + Base64.encodeBytes(pair.getBytes()); + requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader); + } + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/BearerAuthFilter.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/BearerAuthFilter.java new file mode 100644 index 0000000000000..266ce8927d574 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/BearerAuthFilter.java @@ -0,0 +1,77 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.io.IOException; +import java.util.List; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientRequestFilter; +import javax.ws.rs.client.ClientResponseContext; +import javax.ws.rs.client.ClientResponseFilter; +import javax.ws.rs.core.HttpHeaders; + +import io.quarkus.keycloak.admin.client.reactive.token.TokenManager; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public class BearerAuthFilter implements ClientRequestFilter, ClientResponseFilter { + + public static final String AUTH_HEADER_PREFIX = "Bearer "; + private final String tokenString; + private final TokenManager tokenManager; + + public BearerAuthFilter(String tokenString) { + this.tokenString = tokenString; + this.tokenManager = null; + } + + public BearerAuthFilter(TokenManager tokenManager) { + this.tokenManager = tokenManager; + this.tokenString = null; + } + + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + String authHeader = (tokenManager != null ? tokenManager.getAccessTokenString() : tokenString); + if (!authHeader.startsWith(AUTH_HEADER_PREFIX)) { + authHeader = AUTH_HEADER_PREFIX + authHeader; + } + requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader); + } + + @Override + public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { + if (responseContext.getStatus() == 401 && tokenManager != null) { + List authHeaders = requestContext.getHeaders().get(HttpHeaders.AUTHORIZATION); + if (authHeaders == null) { + return; + } + for (Object authHeader : authHeaders) { + if (authHeader instanceof String) { + String headerValue = (String) authHeader; + if (headerValue.startsWith(AUTH_HEADER_PREFIX)) { + String token = headerValue.substring(AUTH_HEADER_PREFIX.length()); + tokenManager.invalidate(token); + } + } + } + } + } +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientAttributeCertificateResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientAttributeCertificateResource.java new file mode 100644 index 0000000000000..1c3e738ccb58b --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientAttributeCertificateResource.java @@ -0,0 +1,105 @@ +/* + * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.KeyStoreConfig; +import org.keycloak.representations.idm.CertificateRepresentation; + +/** + * + * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. + */ +public interface ClientAttributeCertificateResource { + + /** + * Get key info + * + * @return + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + CertificateRepresentation getKeyInfo(); + + /** + * Generate a new certificate with new key pair + * + * @return + */ + @POST + @Path("generate") + @Produces(MediaType.APPLICATION_JSON) + CertificateRepresentation generate(); + + /** + * Upload certificate and eventually private key + * + * @param output + * @return + */ + // @POST + // @Path("upload") + // @Consumes(MediaType.MULTIPART_FORM_DATA) + // @Produces(MediaType.APPLICATION_JSON) + // CertificateRepresentation uploadJks(MultipartFormDataOutput output); + + /** + * Upload only certificate, not private key + * + * @param output + * @return + */ + // @POST + // @Path("upload-certificate") + // @Consumes(MediaType.MULTIPART_FORM_DATA) + // @Produces(MediaType.APPLICATION_JSON) + // CertificateRepresentation uploadJksCertificate(MultipartFormDataOutput output); + + /** + * Get a keystore file for the client, containing private key and public certificate + * + * @param config Keystore configuration as JSON + * @return + */ + @POST + @Path("/download") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Consumes(MediaType.APPLICATION_JSON) + byte[] getKeystore(final KeyStoreConfig config); + + /** + * Generate a new keypair and certificate, and get the private key file + * + * Generates a keypair and certificate and serves the private key in a specified keystore format. + * Only generated public certificate is saved in Keycloak DB - the private key is not. + * + * @param config Keystore configuration as JSON + * @return + */ + @POST + @Path("/generate-and-download") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Consumes(MediaType.APPLICATION_JSON) + byte[] generateAndGetKeystore(final KeyStoreConfig config); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientInitialAccessResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientInitialAccessResource.java new file mode 100644 index 0000000000000..c4b579a3f933a --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientInitialAccessResource.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; +import org.keycloak.representations.idm.ClientInitialAccessPresentation; + +/** + * @author Stian Thorgersen + */ +public interface ClientInitialAccessResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + ClientInitialAccessPresentation create(ClientInitialAccessCreatePresentation rep); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(); + + @DELETE + @Path("{id}") + void delete(final @PathParam("id") String id); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesPoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesPoliciesResource.java new file mode 100644 index 0000000000000..2a988cadf3728 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesPoliciesResource.java @@ -0,0 +1,23 @@ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.ClientPoliciesRepresentation; + +/** + * @author Takashi Norimatsu + */ +public interface ClientPoliciesPoliciesResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + ClientPoliciesRepresentation getPolicies(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updatePolicies(final ClientPoliciesRepresentation clientPolicies); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesProfilesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesProfilesResource.java new file mode 100644 index 0000000000000..f33ed18537d04 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesProfilesResource.java @@ -0,0 +1,30 @@ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.ClientProfilesRepresentation; + +/** + * @author Takashi Norimatsu + */ +public interface ClientPoliciesProfilesResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + ClientProfilesRepresentation getProfiles(@QueryParam("include-global-profiles") Boolean includeGlobalProfiles); + + /** + * Update client profiles in the realm. The "globalProfiles" field of clientProfiles is ignored as it is not possible to + * update global profiles + * + * @param clientProfiles + */ + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updateProfiles(final ClientProfilesRepresentation clientProfiles); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesResource.java new file mode 100644 index 0000000000000..ceb162e2156ca --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPoliciesResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface ClientPoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(ClientPolicyRepresentation representation); + + @Path("{id}") + ClientPolicyResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + ClientPolicyRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPolicyResource.java new file mode 100644 index 0000000000000..08917abc1294d --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientPolicyResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation; +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; + +/** + * @author Pedro Igor + */ +public interface ClientPolicyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + ClientPolicyRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(ClientPolicyRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientRegistrationPolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientRegistrationPolicyResource.java new file mode 100644 index 0000000000000..03a4a8f16c1b5 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientRegistrationPolicyResource.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.ComponentTypeRepresentation; + +/** + * @author Marek Posolda + */ +public interface ClientRegistrationPolicyResource { + + @Path("providers") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getProviders(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientResource.java new file mode 100755 index 0000000000000..c96dcc4cfba3e --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientResource.java @@ -0,0 +1,210 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.MediaType; + +import org.keycloak.representations.adapters.action.GlobalRequestResult; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ClientScopeRepresentation; +import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.representations.idm.ManagementPermissionReference; +import org.keycloak.representations.idm.ManagementPermissionRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.representations.idm.UserSessionRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public interface ClientResource { + + /** + * Enables or disables the fine grain permissions feature. + * Returns the updated status of the server in the + * {@link ManagementPermissionReference}. + * + * @param status status request to apply + * @return permission reference indicating the updated status + */ + @PUT + @Path("/management/permissions") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + ManagementPermissionReference setPermissions(ManagementPermissionRepresentation status); + + /** + * Returns indicator if the fine grain permissions are enabled or not. + * + * @return current representation of the permissions feature + */ + @GET + @Path("/management/permissions") + @Produces(MediaType.APPLICATION_JSON) + ManagementPermissionReference getPermissions(); + + @Path("protocol-mappers") + ProtocolMappersResource getProtocolMappers(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + ClientRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(ClientRepresentation clientRepresentation); + + @DELETE + void remove(); + + @POST + @Path("client-secret") + @Produces(MediaType.APPLICATION_JSON) + CredentialRepresentation generateNewSecret(); + + @GET + @Path("client-secret") + @Produces(MediaType.APPLICATION_JSON) + CredentialRepresentation getSecret(); + + /** + * Generate a new registration access token for the client + * + * @return + */ + @Path("registration-access-token") + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + ClientRepresentation regenerateRegistrationAccessToken(); + + /** + * Get representation of certificate resource + * + * @param attributePrefix + * @return + */ + @Path("certificates/{attr}") + ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix); + + @GET + @Path("installation/providers/{providerId}") + String getInstallationProvider(@PathParam("providerId") String providerId); + + @Path("session-count") + @GET + @Produces(MediaType.APPLICATION_JSON) + Map getApplicationSessionCount(); + + @Path("user-sessions") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getUserSessions(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @Path("offline-session-count") + @GET + @Produces(MediaType.APPLICATION_JSON) + Map getOfflineSessionCount(); + + @Path("offline-sessions") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getOfflineUserSessions(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @POST + @Path("push-revocation") + @Produces(MediaType.APPLICATION_JSON) + void pushRevocation(); + + @Path("/scope-mappings") + RoleMappingResource getScopeMappings(); + + @Path("/roles") + RolesResource roles(); + + /** + * Get default client scopes. Only name and ids are returned. + * + * @return default client scopes + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("default-client-scopes") + List getDefaultClientScopes(); + + @PUT + @Path("default-client-scopes/{clientScopeId}") + void addDefaultClientScope(@PathParam("clientScopeId") String clientScopeId); + + @DELETE + @Path("default-client-scopes/{clientScopeId}") + void removeDefaultClientScope(@PathParam("clientScopeId") String clientScopeId); + + /** + * Get optional client scopes. Only name and ids are returned. + * + * @return optional client scopes + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("optional-client-scopes") + List getOptionalClientScopes(); + + @PUT + @Path("optional-client-scopes/{clientScopeId}") + void addOptionalClientScope(@PathParam("clientScopeId") String clientScopeId); + + @DELETE + @Path("optional-client-scopes/{clientScopeId}") + void removeOptionalClientScope(@PathParam("clientScopeId") String clientScopeId); + + @Path("/service-account-user") + @GET + @Produces(MediaType.APPLICATION_JSON) + UserRepresentation getServiceAccountUser(); + + @Path("nodes") + @POST + @Consumes(MediaType.APPLICATION_JSON) + void registerNode(Map formParams); + + @Path("nodes/{node}") + @DELETE + void unregisterNode(final @PathParam("node") String node); + + @Path("test-nodes-available") + @GET + @Produces(MediaType.APPLICATION_JSON) + GlobalRequestResult testNodesAvailable(); + + @Path("/authz/resource-server") + AuthorizationResource authorization(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopePoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopePoliciesResource.java new file mode 100644 index 0000000000000..0f061d5e4ab4d --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopePoliciesResource.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.ClientScopePolicyRepresentation; + +/** + * @author Yoshiyuki Tabata + */ +public interface ClientScopePoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(ClientScopePolicyRepresentation representation); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + ClientScopePolicyRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopeResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopeResource.java new file mode 100755 index 0000000000000..ad972244a3763 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopeResource.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.ClientScopeRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public interface ClientScopeResource { + + @Path("protocol-mappers") + ProtocolMappersResource getProtocolMappers(); + + @Path("/scope-mappings") + RoleMappingResource getScopeMappings(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + ClientScopeRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(ClientScopeRepresentation rep); + + @DELETE + void remove(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopesResource.java new file mode 100755 index 0000000000000..dc30e330f23e8 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientScopesResource.java @@ -0,0 +1,49 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.ClientScopeRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public interface ClientScopesResource { + + @Path("{id}") + ClientScopeResource get(@PathParam("id") String id); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response create(ClientScopeRepresentation clientScopeRepresentation); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List findAll(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientsResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientsResource.java new file mode 100755 index 0000000000000..5a7fe94738856 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ClientsResource.java @@ -0,0 +1,70 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.ClientRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public interface ClientsResource { + + @Path("{id}") + ClientResource get(@PathParam("id") String id); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response create(ClientRepresentation clientRepresentation); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List findAll(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List findAll(@QueryParam("viewableOnly") boolean viewableOnly); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List findAll(@QueryParam("clientId") String clientId, + @QueryParam("viewableOnly") Boolean viewableOnly, + @QueryParam("search") Boolean search, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List findByClientId(@QueryParam("clientId") String clientId); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List query(@QueryParam("q") String searchQuery); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ComponentResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ComponentResource.java new file mode 100644 index 0000000000000..92520743118d8 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ComponentResource.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.ComponentRepresentation; +import org.keycloak.representations.idm.ComponentTypeRepresentation; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public interface ComponentResource { + @GET + ComponentRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(ComponentRepresentation rep); + + @DELETE + void remove(); + + /** + * List of subcomponent types that are available to configure for a particular parent component. + * + * @param subtype fully qualified name of the java class of the provider, which is subtype of this component + * @return + */ + @GET + @Path("sub-component-types") + @Produces(MediaType.APPLICATION_JSON) + List getSubcomponentConfig(@QueryParam("type") String subtype); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ComponentsResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ComponentsResource.java new file mode 100644 index 0000000000000..ef27a8c897822 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ComponentsResource.java @@ -0,0 +1,63 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.ComponentRepresentation; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public interface ComponentsResource { + @GET + @Produces(MediaType.APPLICATION_JSON) + List query(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List query(@QueryParam("parent") String parent); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List query(@QueryParam("parent") String parent, @QueryParam("type") String type); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List query(@QueryParam("parent") String parent, + @QueryParam("type") String type, + @QueryParam("name") String name); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response add(ComponentRepresentation rep); + + @Path("{id}") + ComponentResource component(@PathParam("id") String id); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupPoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupPoliciesResource.java new file mode 100644 index 0000000000000..055d76a0abecc --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupPoliciesResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2017 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface GroupPoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(GroupPolicyRepresentation representation); + + @Path("{id}") + GroupPolicyResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + GroupPolicyRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupPolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupPolicyResource.java new file mode 100644 index 0000000000000..d4723bf085d71 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupPolicyResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation; +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; + +/** + * @author Pedro Igor + */ +public interface GroupPolicyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + GroupPolicyRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(GroupPolicyRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupResource.java new file mode 100755 index 0000000000000..fc9f915fa3d4c --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupResource.java @@ -0,0 +1,150 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.GroupRepresentation; +import org.keycloak.representations.idm.ManagementPermissionReference; +import org.keycloak.representations.idm.ManagementPermissionRepresentation; +import org.keycloak.representations.idm.UserRepresentation; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public interface GroupResource { + + /** + * Enables or disables the fine grain permissions feature. + * Returns the updated status of the server in the + * {@link ManagementPermissionReference}. + * + * @param status status request to apply + * @return permission reference indicating the updated status + */ + @PUT + @Path("/management/permissions") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + ManagementPermissionReference setPermissions(ManagementPermissionRepresentation status); + + /** + * Returns indicator if the fine grain permissions are enabled or not. + * + * @return current representation of the permissions feature + */ + @GET + @Path("/management/permissions") + @Produces(MediaType.APPLICATION_JSON) + ManagementPermissionReference getPermissions(); + + /** + * Does not expand hierarchy. Subgroups will not be set. + * + * @return + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + GroupRepresentation toRepresentation(); + + /** + * Update group + * + * @param rep + */ + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(GroupRepresentation rep); + + @DELETE + void remove(); + + /** + * Set or create child. This will just set the parent if it exists. Create it and set the parent + * if the group doesn't exist. + * + * @param rep + */ + @POST + @Path("children") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + Response subGroup(GroupRepresentation rep); + + @Path("role-mappings") + RoleMappingResource roles(); + + /** + * Get users + *

+ * Returns a list of all users in group. + * + * @return Returns a max size of 100 users + */ + @GET + @Path("/members") + @Produces(MediaType.APPLICATION_JSON) + List members(); + + /** + * Get users + *

+ * Returns a list of users, filtered according to query parameters + * + * @param firstResult Pagination offset + * @param maxResults Pagination size + * @return + */ + @GET + @Path("/members") + @Produces(MediaType.APPLICATION_JSON) + List members(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + /** + * Get users + *

+ * Returns a list of users, filtered according to query parameters + * + * @param firstResult Pagination offset + * @param maxResults Pagination size + * @param briefRepresentation Only return basic information (only guaranteed to return id, username, created, first and last + * name, + * email, enabled state, email verification state, federation link, and access. + * Note that it means that namely user attributes, required actions, and not before are not returned.) + * @return + */ + @GET + @Path("/members") + @Produces(MediaType.APPLICATION_JSON) + List members(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("briefRepresentation") Boolean briefRepresentation); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupsResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupsResource.java new file mode 100755 index 0000000000000..eec4eaf4063ba --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/GroupsResource.java @@ -0,0 +1,144 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.GroupRepresentation; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public interface GroupsResource { + + /** + * Get all groups. + * + * @return A list containing all groups. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List groups(); + + /** + * Get groups by pagination params. + * + * @param first index of the first element + * @param max max number of occurrences + * @return A list containing the slice of all groups. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + List groups(@QueryParam("first") Integer first, @QueryParam("max") Integer max); + + /** + * Get groups by pagination params. + * + * @param search max number of occurrences + * @param first index of the first element + * @param max max number of occurrences + * @return A list containing the slice of all groups. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + List groups(@QueryParam("search") String search, + @QueryParam("first") Integer first, + @QueryParam("max") Integer max); + + /** + * Get groups by pagination params. + * + * @param search max number of occurrences + * @param first index of the first element + * @param max max number of occurrences + * @param briefRepresentation if false, return groups with their attributes + * @return A list containing the slice of all groups. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + List groups(@QueryParam("search") String search, + @QueryParam("first") Integer first, + @QueryParam("max") Integer max, + @QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation); + + /** + * Counts all groups. + * + * @return A map containing key "count" with number of groups as value. + */ + @GET + @Path("count") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + Map count(); + + /** + * Counts groups by name search. + * + * @param search max number of occurrences + * @return A map containing key "count" with number of groups as value which matching with search. + */ + @GET + @Path("count") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + Map count(@QueryParam("search") String search); + + /** + * Counts groups by name search. + * + * @param onlyTopGroups true or false for filter only top level groups count + * @return A map containing key "count" with number of top level groups. + */ + @GET + @Path("count") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + Map count(@QueryParam("top") @DefaultValue("true") boolean onlyTopGroups); + + /** + * create or add a top level realm groupSet or create child. This will update the group and set the parent if it exists. + * Create it and set the parent + * if the group doesn't exist. + * + * @param rep + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response add(GroupRepresentation rep); + + @Path("{id}") + GroupResource group(@PathParam("id") String id); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/IdentityProviderResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/IdentityProviderResource.java new file mode 100755 index 0000000000000..1145ba47e74f1 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/IdentityProviderResource.java @@ -0,0 +1,87 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.IdentityProviderMapperRepresentation; +import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation; +import org.keycloak.representations.idm.IdentityProviderRepresentation; + +/** + * @author pedroigor + */ +public interface IdentityProviderResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + IdentityProviderRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(IdentityProviderRepresentation identityProviderRepresentation); + + @DELETE + void remove(); + + @GET + @Path("export") + Response export(@QueryParam("format") String format); + + @GET + @Path("mapper-types") + @Produces(MediaType.APPLICATION_JSON) + Map getMapperTypes(); + + @GET + @Path("mappers") + @Produces(MediaType.APPLICATION_JSON) + List getMappers(); + + @POST + @Path("mappers") + @Consumes(MediaType.APPLICATION_JSON) + Response addMapper(IdentityProviderMapperRepresentation mapper); + + @GET + @Path("mappers/{id}") + @Produces(MediaType.APPLICATION_JSON) + IdentityProviderMapperRepresentation getMapperById(@PathParam("id") String id); + + @PUT + @Path("mappers/{id}") + @Consumes(MediaType.APPLICATION_JSON) + void update(@PathParam("id") String id, IdentityProviderMapperRepresentation rep); + + @DELETE + @Path("mappers/{id}") + void delete(@PathParam("id") String id); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/IdentityProvidersResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/IdentityProvidersResource.java new file mode 100755 index 0000000000000..94ff5220339ca --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/IdentityProvidersResource.java @@ -0,0 +1,68 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.IdentityProviderRepresentation; + +/** + * @author pedroigor + */ +public interface IdentityProvidersResource { + + @Path("instances/{alias}") + IdentityProviderResource get(@PathParam("alias") String alias); + + @GET + @Path("instances") + @Produces(MediaType.APPLICATION_JSON) + List findAll(); + + @POST + @Path("instances") + @Consumes(MediaType.APPLICATION_JSON) + Response create(IdentityProviderRepresentation identityProvider); + + @GET + @Path("/providers/{provider_id}") + @Produces(MediaType.APPLICATION_JSON) + Response getIdentityProviders(@PathParam("provider_id") String providerId); + + // @POST + // @Path("import-config") + // @Consumes(MediaType.MULTIPART_FORM_DATA) + // @Produces(MediaType.APPLICATION_JSON) + // Map importFrom(MultipartFormDataOutput data); + + @POST + @Path("import-config") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Map importFrom(Map data); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/JSPoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/JSPoliciesResource.java new file mode 100644 index 0000000000000..e9e3802639225 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/JSPoliciesResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.JSPolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface JSPoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(JSPolicyRepresentation representation); + + @Path("{id}") + JSPolicyResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + JSPolicyRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/JSPolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/JSPolicyResource.java new file mode 100644 index 0000000000000..a9a66b5da0ba4 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/JSPolicyResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.JSPolicyRepresentation; +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; + +/** + * @author Pedro Igor + */ +public interface JSPolicyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + JSPolicyRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(JSPolicyRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/KeyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/KeyResource.java new file mode 100644 index 0000000000000..88bfd8b5e6f27 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/KeyResource.java @@ -0,0 +1,35 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.KeysMetadataRepresentation; + +/** + * @author Stian Thorgersen + */ +public interface KeyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + KeysMetadataRepresentation getKeyMetadata(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PermissionsResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PermissionsResource.java new file mode 100644 index 0000000000000..c2163cf5a7154 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PermissionsResource.java @@ -0,0 +1,31 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Path; + +/** + * @author Pedro Igor + */ +public interface PermissionsResource { + + @Path("resource") + ResourcePermissionsResource resource(); + + @Path("scope") + ScopePermissionsResource scope(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PoliciesResource.java new file mode 100644 index 0000000000000..36b9e61e6f399 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PoliciesResource.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.PolicyEvaluationRequest; +import org.keycloak.representations.idm.authorization.PolicyEvaluationResponse; +import org.keycloak.representations.idm.authorization.PolicyProviderRepresentation; +import org.keycloak.representations.idm.authorization.PolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface PoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(PolicyRepresentation representation); + + @Path("{id}") + PolicyResource policy(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + PolicyRepresentation findByName(@QueryParam("name") String name); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List policies(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List policies(@QueryParam("policyId") String id, + @QueryParam("name") String name, + @QueryParam("type") String type, + @QueryParam("resource") String resource, + @QueryParam("scope") String scope, + @QueryParam("permission") Boolean permission, + @QueryParam("owner") String owner, + @QueryParam("fields") String fields, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResult); + + @Path("providers") + @GET + @Produces(MediaType.APPLICATION_JSON) + List policyProviders(); + + @POST + @Consumes("application/json") + @Produces("application/json") + @Path("evaluate") + PolicyEvaluationResponse evaluate(PolicyEvaluationRequest evaluationRequest); + + @Path("role") + RolePoliciesResource role(); + + @Path("user") + UserPoliciesResource user(); + + @Path("js") + JSPoliciesResource js(); + + @Path("time") + TimePoliciesResource time(); + + @Path("aggregate") + AggregatePoliciesResource aggregate(); + + @Path("client") + ClientPoliciesResource client(); + + @Path("group") + GroupPoliciesResource group(); + + @Path("client-scope") + ClientScopePoliciesResource clientScope(); + + @Path("regex") + RegexPoliciesResource regex(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PolicyResource.java new file mode 100644 index 0000000000000..7a0a0f4c92623 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/PolicyResource.java @@ -0,0 +1,73 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.representations.idm.authorization.ScopeRepresentation; + +/** + * @author Pedro Igor + */ +public interface PolicyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + PolicyRepresentation toRepresentation(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + PolicyRepresentation toRepresentation(@QueryParam("fields") String fields); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(PolicyRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/scopes") + @GET + @Produces("application/json") + List scopes(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ProtocolMappersResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ProtocolMappersResource.java new file mode 100644 index 0000000000000..cc327986a7f03 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ProtocolMappersResource.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.ProtocolMapperRepresentation; + +/** + * @author Marek Posolda + */ +public interface ProtocolMappersResource { + + @GET + @Path("protocol/{protocol}") + @Produces("application/json") + List getMappersPerProtocol(@PathParam("protocol") String protocol); + + @Path("models") + @POST + @Consumes("application/json") + Response createMapper(ProtocolMapperRepresentation rep); + + @Path("add-models") + @POST + @Consumes("application/json") + void createMapper(List reps); + + @GET + @Path("models") + @Produces("application/json") + List getMappers(); + + @GET + @Path("models/{id}") + @Produces("application/json") + ProtocolMapperRepresentation getMapperById(@PathParam("id") String id); + + @PUT + @Path("models/{id}") + @Consumes("application/json") + void update(@PathParam("id") String id, ProtocolMapperRepresentation rep); + + @DELETE + @Path("models/{id}") + void delete(@PathParam("id") String id); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmLocalizationResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmLocalizationResource.java new file mode 100755 index 0000000000000..7b619d38ff820 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmLocalizationResource.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +public interface RealmLocalizationResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + List getRealmSpecificLocales(); + + @Path("{locale}") + @GET + @Produces(MediaType.APPLICATION_JSON) + Map getRealmLocalizationTexts(final @PathParam("locale") String locale); + + @Path("{locale}/{key}") + @GET + @Produces(MediaType.TEXT_PLAIN) + String getRealmLocalizationText(final @PathParam("locale") String locale, final @PathParam("key") String key); + + @Path("{locale}") + @DELETE + void deleteRealmLocalizationTexts(@PathParam("locale") String locale); + + @Path("{locale}/{key}") + @DELETE + void deleteRealmLocalizationText(@PathParam("locale") String locale, @PathParam("key") String key); + + @Path("{locale}/{key}") + @PUT + @Consumes(MediaType.TEXT_PLAIN) + void saveRealmLocalizationText(@PathParam("locale") String locale, @PathParam("key") String key, String text); + + @Path("{locale}") + @POST + @Consumes("application/json") + void createOrUpdateRealmLocalizationTexts(@PathParam("locale") String locale, Map localizationTexts); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmResource.java new file mode 100644 index 0000000000000..4cc5e9aa2f4eb --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmResource.java @@ -0,0 +1,295 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.adapters.action.GlobalRequestResult; +import org.keycloak.representations.idm.AdminEventRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ClientScopeRepresentation; +import org.keycloak.representations.idm.EventRepresentation; +import org.keycloak.representations.idm.GroupRepresentation; +import org.keycloak.representations.idm.LDAPCapabilityRepresentation; +import org.keycloak.representations.idm.PartialImportRepresentation; +import org.keycloak.representations.idm.RealmEventsConfigRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.TestLdapConnectionRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public interface RealmResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + RealmRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(RealmRepresentation realmRepresentation); + + @Path("clients") + ClientsResource clients(); + + @Path("client-scopes") + ClientScopesResource clientScopes(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("default-default-client-scopes") + List getDefaultDefaultClientScopes(); + + @PUT + @Path("default-default-client-scopes/{clientScopeId}") + void addDefaultDefaultClientScope(@PathParam("clientScopeId") String clientScopeId); + + @DELETE + @Path("default-default-client-scopes/{clientScopeId}") + void removeDefaultDefaultClientScope(@PathParam("clientScopeId") String clientScopeId); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("default-optional-client-scopes") + List getDefaultOptionalClientScopes(); + + @PUT + @Path("default-optional-client-scopes/{clientScopeId}") + void addDefaultOptionalClientScope(@PathParam("clientScopeId") String clientScopeId); + + @DELETE + @Path("default-optional-client-scopes/{clientScopeId}") + void removeDefaultOptionalClientScope(@PathParam("clientScopeId") String clientScopeId); + + @Path("client-description-converter") + @POST + // @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN }) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + ClientRepresentation convertClientDescription(String description); + + @Path("users") + UsersResource users(); + + @Path("roles") + RolesResource roles(); + + @Path("roles-by-id") + RoleByIdResource rolesById(); + + @Path("groups") + GroupsResource groups(); + + @DELETE + @Path("events") + void clearEvents(); + + @GET + @Path("events") + @Produces(MediaType.APPLICATION_JSON) + List getEvents(); + + @Path("events") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getEvents(@QueryParam("type") List types, @QueryParam("client") String client, + @QueryParam("user") String user, @QueryParam("dateFrom") String dateFrom, @QueryParam("dateTo") String dateTo, + @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @DELETE + @Path("admin-events") + void clearAdminEvents(); + + @GET + @Path("admin-events") + @Produces(MediaType.APPLICATION_JSON) + List getAdminEvents(); + + @GET + @Path("admin-events") + @Produces(MediaType.APPLICATION_JSON) + List getAdminEvents(@QueryParam("operationTypes") List operationTypes, + @QueryParam("authRealm") String authRealm, @QueryParam("authClient") String authClient, + @QueryParam("authUser") String authUser, @QueryParam("authIpAddress") String authIpAddress, + @QueryParam("resourcePath") String resourcePath, @QueryParam("dateFrom") String dateFrom, + @QueryParam("dateTo") String dateTo, @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @GET + @Path("admin-events") + @Produces(MediaType.APPLICATION_JSON) + List getAdminEvents(@QueryParam("operationTypes") List operationTypes, + @QueryParam("authRealm") String authRealm, @QueryParam("authClient") String authClient, + @QueryParam("authUser") String authUser, @QueryParam("authIpAddress") String authIpAddress, + @QueryParam("resourcePath") String resourcePath, @QueryParam("resourceTypes") List resourceTypes, + @QueryParam("dateFrom") String dateFrom, + @QueryParam("dateTo") String dateTo, @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @GET + @Path("events/config") + @Produces(MediaType.APPLICATION_JSON) + RealmEventsConfigRepresentation getRealmEventsConfig(); + + @PUT + @Path("events/config") + @Consumes(MediaType.APPLICATION_JSON) + void updateRealmEventsConfig(RealmEventsConfigRepresentation rep); + + @GET + @Path("group-by-path/{path: .*}") + @Produces(MediaType.APPLICATION_JSON) + GroupRepresentation getGroupByPath(@PathParam("path") String path); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("default-groups") + List getDefaultGroups(); + + @PUT + @Path("default-groups/{groupId}") + void addDefaultGroup(@PathParam("groupId") String groupId); + + @DELETE + @Path("default-groups/{groupId}") + void removeDefaultGroup(@PathParam("groupId") String groupId); + + @Path("identity-provider") + IdentityProvidersResource identityProviders(); + + @DELETE + void remove(); + + @Path("client-session-stats") + @GET + List> getClientSessionStats(); + + @Path("clients-initial-access") + ClientInitialAccessResource clientInitialAccess(); + + @Path("client-registration-policy") + ClientRegistrationPolicyResource clientRegistrationPolicy(); + + @Path("partialImport") + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response partialImport(PartialImportRepresentation rep); + + @Path("partial-export") + @POST + @Produces(MediaType.APPLICATION_JSON) + RealmRepresentation partialExport(@QueryParam("exportGroupsAndRoles") Boolean exportGroupsAndRoles, + @QueryParam("exportClients") Boolean exportClients); + + @Path("authentication") + @Consumes(MediaType.APPLICATION_JSON) + AuthenticationManagementResource flows(); + + @Path("attack-detection") + AttackDetectionResource attackDetection(); + + // @Path("testLDAPConnection") + // @POST + // @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + // @Deprecated + // Response testLDAPConnection(@FormParam("action") String action, @FormParam("connectionUrl") String connectionUrl, + // @FormParam("bindDn") String bindDn, @FormParam("bindCredential") String bindCredential, + // @FormParam("useTruststoreSpi") String useTruststoreSpi, @FormParam("connectionTimeout") String connectionTimeout); + + @Path("testLDAPConnection") + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response testLDAPConnection(TestLdapConnectionRepresentation config); + + @POST + @Path("ldap-server-capabilities") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + List ldapServerCapabilities(TestLdapConnectionRepresentation config); + + @Path("testSMTPConnection") + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Deprecated + Response testSMTPConnection(@FormParam("config") String config); + + @Path("testSMTPConnection") + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response testSMTPConnection(Map config); + + @Path("clear-realm-cache") + @POST + void clearRealmCache(); + + @Path("clear-user-cache") + @POST + void clearUserCache(); + + @Path("clear-keys-cache") + @POST + void clearKeysCache(); + + @Path("push-revocation") + @POST + @Produces(MediaType.APPLICATION_JSON) + GlobalRequestResult pushRevocation(); + + @Path("logout-all") + @POST + @Produces(MediaType.APPLICATION_JSON) + GlobalRequestResult logoutAll(); + + @Path("sessions/{session}") + @DELETE + void deleteSession(@PathParam("session") String sessionId); + + @Path("components") + ComponentsResource components(); + + @Path("user-storage") + UserStorageProviderResource userStorage(); + + @Path("keys") + KeyResource keys(); + + @Path("localization") + RealmLocalizationResource localization(); + + @Path("client-policies/policies") + ClientPoliciesPoliciesResource clientPoliciesPoliciesResource(); + + @Path("client-policies/profiles") + ClientPoliciesProfilesResource clientPoliciesProfilesResource(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmsResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmsResource.java new file mode 100644 index 0000000000000..3db7bf63d6396 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RealmsResource.java @@ -0,0 +1,49 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.RealmRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +@Path("/admin/realms") +public interface RealmsResource { + + @Path("/{realm}") + RealmResource realm(@PathParam("realm") String realm); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + void create(RealmRepresentation realmRepresentation); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List findAll(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RegexPoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RegexPoliciesResource.java new file mode 100644 index 0000000000000..1a860e21a0037 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RegexPoliciesResource.java @@ -0,0 +1,37 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.RegexPolicyRepresentation; + +/** + * @author Yoshiyuki Tabata + */ +public interface RegexPoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(RegexPolicyRepresentation representation); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcePermissionResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcePermissionResource.java new file mode 100644 index 0000000000000..3b064f0bee01e --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcePermissionResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; + +/** + * @author Pedro Igor + */ +public interface ResourcePermissionResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + ResourcePermissionRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(ResourcePermissionRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcePermissionsResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcePermissionsResource.java new file mode 100644 index 0000000000000..d2a0d13c31a02 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcePermissionsResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation; + +/** + * @author Pedro Igor + */ +public interface ResourcePermissionsResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(ResourcePermissionRepresentation representation); + + @Path("{id}") + ResourcePermissionResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + ResourcePermissionRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceResource.java new file mode 100644 index 0000000000000..0a6f25190000c --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceResource.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; + +/** + * @author Pedro Igor + */ +public interface ResourceResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + ResourceRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(ResourceRepresentation resource); + + @DELETE + void remove(); + + @Path("permissions") + @GET + @Produces(MediaType.APPLICATION_JSON) + List permissions(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceScopeResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceScopeResource.java new file mode 100644 index 0000000000000..27c754dcd1acc --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceScopeResource.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ScopeRepresentation; + +/** + * @author Pedro Igor + */ +public interface ResourceScopeResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + ScopeRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(ScopeRepresentation scope); + + @DELETE + void remove(); + + @Path("/permissions") + @GET + @Produces(MediaType.APPLICATION_JSON) + List permissions(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceScopesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceScopesResource.java new file mode 100644 index 0000000000000..0ae634b01485c --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourceScopesResource.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.ScopeRepresentation; + +/** + * @author Pedro Igor + */ +public interface ResourceScopesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(ScopeRepresentation scope); + + @Path("{id}") + ResourceScopeResource scope(@PathParam("id") String id); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List scopes(); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + ScopeRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcesResource.java new file mode 100644 index 0000000000000..fbdf9c8a348b4 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ResourcesResource.java @@ -0,0 +1,67 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.ResourceRepresentation; + +/** + * @author Pedro Igor + */ +public interface ResourcesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(ResourceRepresentation resource); + + @Path("{id}") + ResourceResource resource(@PathParam("id") String id); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List find(@QueryParam("name") String name, + @QueryParam("uri") String uri, + @QueryParam("owner") String owner, + @QueryParam("type") String type, + @QueryParam("scope") String scope, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResult); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List findByName(@QueryParam("name") String name); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List findByName(@QueryParam("name") String name, @QueryParam("owner") String owner); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List resources(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleByIdResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleByIdResource.java new file mode 100755 index 0000000000000..0c7f53f28abc4 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleByIdResource.java @@ -0,0 +1,92 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.MediaType; + +import org.keycloak.representations.idm.RoleRepresentation; + +/** + * Sometimes its easier to just interact with roles by their ID instead of container/role-name + * + * @author Bill Burke + * @version $Revision: 1 $ + */ +public interface RoleByIdResource { + + @Path("{role-id}") + @GET + @Produces(MediaType.APPLICATION_JSON) + RoleRepresentation getRole(final @PathParam("role-id") String id); + + @Path("{role-id}") + @DELETE + void deleteRole(final @PathParam("role-id") String id); + + @Path("{role-id}") + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updateRole(final @PathParam("role-id") String id, RoleRepresentation rep); + + @Path("{role-id}/composites") + @POST + @Consumes(MediaType.APPLICATION_JSON) + void addComposites(final @PathParam("role-id") String id, List roles); + + @Path("{role-id}/composites") + @GET + @Produces(MediaType.APPLICATION_JSON) + Set getRoleComposites(@PathParam("role-id") String id); + + @Path("{role-id}/composites") + @GET + @Produces(MediaType.APPLICATION_JSON) + Set searchRoleComposites(@PathParam("role-id") String id, + @QueryParam("search") String search, + @QueryParam("first") Integer first, + @QueryParam("max") Integer max); + + @Path("{role-id}/composites/realm") + @GET + @Produces(MediaType.APPLICATION_JSON) + Set getRealmRoleComposites(@PathParam("role-id") String id); + + @Path("{role-id}/composites/clients/{clientUuid}") + @GET + @Produces(MediaType.APPLICATION_JSON) + Set getClientRoleComposites(@PathParam("role-id") String id, + @PathParam("clientUuid") String clientUuid); + + @Path("{role-id}/composites") + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + void deleteComposites(final @PathParam("role-id") String id, List roles); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleMappingResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleMappingResource.java new file mode 100755 index 0000000000000..1e4759bfffe1c --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleMappingResource.java @@ -0,0 +1,45 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.MappingsRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface RoleMappingResource { + + @GET + MappingsRepresentation getAll(); + + @Path("realm") + RoleScopeResource realmLevel(); + + @Path("clients/{clientUUID}") + RoleScopeResource clientLevel(@PathParam("clientUUID") String clientUUID); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolePoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolePoliciesResource.java new file mode 100644 index 0000000000000..12b338ac21923 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolePoliciesResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.RolePolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface RolePoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(RolePolicyRepresentation representation); + + @Path("{id}") + RolePolicyResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + RolePolicyRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolePolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolePolicyResource.java new file mode 100644 index 0000000000000..aadfe40b0ca88 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolePolicyResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.representations.idm.authorization.RolePolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface RolePolicyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + RolePolicyRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(RolePolicyRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleResource.java new file mode 100755 index 0000000000000..d59783a89f584 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleResource.java @@ -0,0 +1,158 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.MediaType; + +import org.keycloak.representations.idm.GroupRepresentation; +import org.keycloak.representations.idm.ManagementPermissionReference; +import org.keycloak.representations.idm.ManagementPermissionRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public interface RoleResource { + + /** + * Enables or disables the fine grain permissions feature. + * Returns the updated status of the server in the + * {@link ManagementPermissionReference}. + * + * @param status status request to apply + * @return permission reference indicating the updated status + */ + @PUT + @Path("/management/permissions") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + ManagementPermissionReference setPermissions(ManagementPermissionRepresentation status); + + /** + * Returns indicator if the fine grain permissions are enabled or not. + * + * @return current representation of the permissions feature + */ + @GET + @Path("/management/permissions") + @Produces(MediaType.APPLICATION_JSON) + ManagementPermissionReference getPermissions(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + RoleRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(RoleRepresentation roleRepresentation); + + @DELETE + void remove(); + + @GET + @Path("composites") + @Produces(MediaType.APPLICATION_JSON) + Set getRoleComposites(); + + @GET + @Path("composites/realm") + @Produces(MediaType.APPLICATION_JSON) + Set getRealmRoleComposites(); + + @GET + @Path("composites/clients/{clientUuid}") + @Produces(MediaType.APPLICATION_JSON) + Set getClientRoleComposites(@PathParam("clientUuid") String clientUuid); + + @POST + @Path("composites") + @Consumes(MediaType.APPLICATION_JSON) + void addComposites(List rolesToAdd); + + @DELETE + @Path("composites") + @Consumes(MediaType.APPLICATION_JSON) + void deleteComposites(List rolesToRemove); + + /** + * Get role members + *

+ * Returns users that have the given role + * + * @return a list of users with the given role + */ + @GET + @Path("users") + @Produces(MediaType.APPLICATION_JSON) + Set getRoleUserMembers(); + + /** + * Get role members + *

+ * Returns users that have the given role, paginated according to the query parameters + * + * @param firstResult Pagination offset + * @param maxResults Pagination size + * @return a list of users with the given role + */ + @GET + @Path("users") + @Produces(MediaType.APPLICATION_JSON) + Set getRoleUserMembers(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + /** + * Get role groups + *

+ * Returns groups that have the given role + * + * @return a list of groups with the given role + */ + @GET + @Path("groups") + @Produces(MediaType.APPLICATION_JSON) + Set getRoleGroupMembers(); + + /** + * Get role groups + *

+ * Returns groups that have the given role, paginated according to the query parameters + * + * @param firstResult Pagination offset + * @param maxResults Pagination size + * @return a list of groups with the given role + */ + @GET + @Path("groups") + @Produces(MediaType.APPLICATION_JSON) + Set getRoleGroupMembers(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleScopeResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleScopeResource.java new file mode 100755 index 0000000000000..cf90672882f71 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RoleScopeResource.java @@ -0,0 +1,63 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.RoleRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface RoleScopeResource { + + @GET + List listAll(); + + @GET + @Path("available") + List listAvailable(); + + @GET + @Path("composite") + List listEffective(); + + @GET + @Path("composite") + List listEffective( + @QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation); + + @POST + void add(List rolesToAdd); + + @DELETE + void remove(List rolesToRemove); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolesResource.java new file mode 100755 index 0000000000000..5ba80078f3fe3 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/RolesResource.java @@ -0,0 +1,132 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; + +import org.keycloak.representations.idm.RoleRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public interface RolesResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(); + + /** + * @param briefRepresentation if false, return roles with their attributes + * @return A list containing all roles. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(@QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation); + + /** + * Get roles by pagination params. + * + * @param search max number of occurrences + * @param first index of the first element + * @param max max number of occurrences + * @return A list containing the slice of all roles. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + /** + * Get roles by pagination params. + * + * @param first index of the first element + * @param max max number of occurrences + * @param briefRepresentation if false, return roles with their attributes + * @return A list containing the slice of all roles. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation); + + /** + * Get roles by pagination params. + * + * @param search max number of occurrences + * @param briefRepresentation if false, return roles with their attributes + * @return A list containing the slice of all roles. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(@QueryParam("search") @DefaultValue("") String search, + @QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation); + + /** + * Get roles by pagination params. + * + * @param search max number of occurrences + * @param first index of the first element + * @param max max number of occurrences + * @return A list containing the slice of all roles. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(@QueryParam("search") @DefaultValue("") String search, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + /** + * Get roles by pagination params. + * + * @param search max number of occurrences + * @param first index of the first element + * @param max max number of occurrences + * @param briefRepresentation if false, return roles with their attributes + * @return A list containing the slice of all roles. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(@QueryParam("search") @DefaultValue("") String search, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + void create(RoleRepresentation roleRepresentation); + + @Path("{roleName}") + RoleResource get(@PathParam("roleName") String roleName); + + @Path("{role-name}") + @DELETE + void deleteRole(final @PathParam("role-name") String roleName); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ScopePermissionResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ScopePermissionResource.java new file mode 100644 index 0000000000000..30011d24bccbf --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ScopePermissionResource.java @@ -0,0 +1,69 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation; +import org.keycloak.representations.idm.authorization.ScopeRepresentation; + +/** + * @author Pedro Igor + */ +public interface ScopePermissionResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + ScopePermissionRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(ScopePermissionRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + + @Path("/scopes") + @GET + @Produces("application/json") + List scopes(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ScopePermissionsResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ScopePermissionsResource.java new file mode 100644 index 0000000000000..68919df56271e --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ScopePermissionsResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation; + +/** + * @author Pedro Igor + */ +public interface ScopePermissionsResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(ScopePermissionRepresentation representation); + + @Path("{id}") + ScopePermissionResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + ScopePermissionRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ServerInfoResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ServerInfoResource.java new file mode 100644 index 0000000000000..0aefaaa6a7ff9 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/ServerInfoResource.java @@ -0,0 +1,37 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.info.ServerInfoRepresentation; + +/** + * @author Stian Thorgersen + */ +@Path("/admin/serverinfo") +public interface ServerInfoResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + ServerInfoRepresentation getInfo(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/TimePoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/TimePoliciesResource.java new file mode 100644 index 0000000000000..ad87decb44a12 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/TimePoliciesResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.TimePolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface TimePoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(TimePolicyRepresentation representation); + + @Path("{id}") + TimePolicyResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + TimePolicyRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/TimePolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/TimePolicyResource.java new file mode 100644 index 0000000000000..78afc65cf9988 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/TimePolicyResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.representations.idm.authorization.TimePolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface TimePolicyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + TimePolicyRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(TimePolicyRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserPoliciesResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserPoliciesResource.java new file mode 100644 index 0000000000000..70109f6e6f4cd --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserPoliciesResource.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.authorization.UserPolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface UserPoliciesResource { + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Response create(UserPolicyRepresentation representation); + + @Path("{id}") + UserPolicyResource findById(@PathParam("id") String id); + + @Path("/search") + @GET + @Produces(MediaType.APPLICATION_JSON) + UserPolicyRepresentation findByName(@QueryParam("name") String name); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserPolicyResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserPolicyResource.java new file mode 100644 index 0000000000000..5added5231744 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserPolicyResource.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.representations.idm.authorization.UserPolicyRepresentation; + +/** + * @author Pedro Igor + */ +public interface UserPolicyResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + UserPolicyRepresentation toRepresentation(); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void update(UserPolicyRepresentation representation); + + @DELETE + void remove(); + + @Path("/associatedPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List associatedPolicies(); + + @Path("/dependentPolicies") + @GET + @Produces(MediaType.APPLICATION_JSON) + List dependentPolicies(); + + @Path("/resources") + @GET + @Produces("application/json") + List resources(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserProfileResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserProfileResource.java new file mode 100644 index 0000000000000..a3177e451c74f --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserProfileResource.java @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * @author Vlastimil Elias + */ +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface UserProfileResource { + + @GET + @Consumes(MediaType.APPLICATION_JSON) + String getConfiguration(); + + @PUT + @Produces(MediaType.APPLICATION_JSON) + Response update(String text); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserResource.java new file mode 100755 index 0000000000000..72438bdf334d4 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserResource.java @@ -0,0 +1,300 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.representations.idm.FederatedIdentityRepresentation; +import org.keycloak.representations.idm.GroupRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.representations.idm.UserSessionRepresentation; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface UserResource { + + @GET + UserRepresentation toRepresentation(); + + @PUT + void update(UserRepresentation userRepresentation); + + @DELETE + void remove(); + + @Path("groups") + @GET + List groups(); + + @Path("groups") + @GET + List groups(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @Path("groups") + @GET + List groups(@QueryParam("search") String search, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @Path("groups") + @GET + List groups(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation); + + @Path("groups") + @GET + List groups(@QueryParam("search") String search, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation); + + @Path("groups/count") + @GET + Map groupsCount(@QueryParam("search") String search); + + @Path("groups/{groupId}") + @PUT + void joinGroup(@PathParam("groupId") String groupId); + + @Path("groups/{groupId}") + @DELETE + void leaveGroup(@PathParam("groupId") String groupId); + + @POST + @Path("logout") + void logout(); + + @GET + @Path("credentials") + @Produces(MediaType.APPLICATION_JSON) + List credentials(); + + /** + * Return credential types, which are provided by the user storage where user is stored. Returned values can contain for + * example "password", "otp" etc. + * This will always return empty list for "local" users, which are not backed by any user storage + * + * @return + */ + @GET + @Path("configured-user-storage-credential-types") + @Produces(MediaType.APPLICATION_JSON) + List getConfiguredUserStorageCredentialTypes(); + + /** + * Remove a credential for a user + * + */ + @DELETE + @Path("credentials/{credentialId}") + void removeCredential(@PathParam("credentialId") String credentialId); + + /** + * Update a credential label for a user + */ + @PUT + @Consumes(MediaType.TEXT_PLAIN) + @Path("credentials/{credentialId}/userLabel") + void setCredentialUserLabel(final @PathParam("credentialId") String credentialId, String userLabel); + + /** + * Move a credential to a first position in the credentials list of the user + * + * @param credentialId The credential to move + */ + @Path("credentials/{credentialId}/moveToFirst") + @POST + void moveCredentialToFirst(final @PathParam("credentialId") String credentialId); + + /** + * Move a credential to a position behind another credential + * + * @param credentialId The credential to move + * @param newPreviousCredentialId The credential that will be the previous element in the list. If set to null, the moved + * credential will be the first element in the list. + */ + @Path("credentials/{credentialId}/moveAfter/{newPreviousCredentialId}") + @POST + void moveCredentialAfter(final @PathParam("credentialId") String credentialId, + final @PathParam("newPreviousCredentialId") String newPreviousCredentialId); + + /** + * Disables or deletes all credentials for specific types. + * Type examples "otp", "password" + * + * This is typically supported just for the users backed by user storage providers. See + * {@link UserRepresentation#getDisableableCredentialTypes()} + * to see what credential types can be disabled for the particular user + * + * @param credentialTypes + */ + @Path("disable-credential-types") + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void disableCredentialType(List credentialTypes); + + @PUT + @Path("reset-password") + void resetPassword(CredentialRepresentation credentialRepresentation); + + /** + * Use executeActionsEmail and pass in the UPDATE_PASSWORD required action + * + */ + @PUT + @Path("reset-password-email") + @Deprecated + void resetPasswordEmail(); + + /** + * Use executeActionsEmail and pass in the UPDATE_PASSWORD required action + * + */ + @PUT + @Path("reset-password-email") + @Deprecated + void resetPasswordEmail(@QueryParam("client_id") String clientId); + + /** + * Sends an email to the user with a link within it. If they click on the link they will be asked to perform some actions + * i.e. {@code VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD, TERMS_AND_CONDITIONS}, etc. + * + * @param actions a {@link List} of string representation of {@link org.keycloak.models.UserModel.RequiredAction} + */ + @PUT + @Path("execute-actions-email") + void executeActionsEmail(List actions); + + /** + * Sends an email to the user with a link within it. If they click on the link they will be asked to perform some actions + * i.e. {@code VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD, TERMS_AND_CONDITIONS}, etc. + * + * The lifespan decides the number of seconds after which the generated token in the email link expires. The default + * value is 12 hours. + * + * @param actions a {@link List} of string representation of {@link org.keycloak.models.UserModel.RequiredAction} + * @param lifespan + */ + @PUT + @Path("execute-actions-email") + void executeActionsEmail(List actions, @QueryParam("lifespan") Integer lifespan); + + /** + * Sends an email to the user with a link within it. If they click on the link they will be asked to perform some actions + * i.e. {@code VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD, TERMS_AND_CONDITIONS}, etc. + * + * If redirectUri is not null, then you must specify a client id. This will set the URI you want the flow to link + * to after the email link is clicked and actions completed. If both parameters are null, then no page is linked to + * at the end of the flow. + * + * The lifespan decides the number of seconds after which the generated token in the email link expires. The default + * value is 12 hours. + * + * @param clientId + * @param redirectUri + * @param lifespan + * @param actions a {@link List} of string representation of {@link org.keycloak.models.UserModel.RequiredAction} + */ + @PUT + @Path("execute-actions-email") + void executeActionsEmail(@QueryParam("client_id") String clientId, + @QueryParam("redirect_uri") String redirectUri, + @QueryParam("lifespan") Integer lifespan, + List actions); + + /** + * Sends an email to the user with a link within it. If they click on the link they will be asked to perform some actions + * i.e. {@code VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD, TERMS_AND_CONDITIONS}, etc. + * + * If redirectUri is not null, then you must specify a client id. This will set the URI you want the flow to link + * to after the email link is clicked and actions completed. If both parameters are null, then no page is linked to + * at the end of the flow. + * + * @param clientId + * @param redirectUri + * @param actions a {@link List} of string representation of {@link org.keycloak.models.UserModel.RequiredAction} + */ + @PUT + @Path("execute-actions-email") + void executeActionsEmail(@QueryParam("client_id") String clientId, @QueryParam("redirect_uri") String redirectUri, + List actions); + + @PUT + @Path("send-verify-email") + void sendVerifyEmail(); + + @PUT + @Path("send-verify-email") + void sendVerifyEmail(@QueryParam("client_id") String clientId); + + @GET + @Path("sessions") + List getUserSessions(); + + @GET + @Path("offline-sessions/{clientId}") + List getOfflineSessions(@PathParam("clientId") String clientId); + + @GET + @Path("federated-identity") + List getFederatedIdentity(); + + @POST + @Path("federated-identity/{provider}") + Response addFederatedIdentity(@PathParam("provider") String provider, FederatedIdentityRepresentation rep); + + @Path("federated-identity/{provider}") + @DELETE + void removeFederatedIdentity(final @PathParam("provider") String provider); + + @Path("role-mappings") + RoleMappingResource roles(); + + @GET + @Path("consents") + List> getConsents(); + + @DELETE + @Path("consents/{client}") + void revokeConsent(@PathParam("client") String clientId); + + @POST + @Path("impersonation") + @Produces(MediaType.APPLICATION_JSON) + Map impersonate(); +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserStorageProviderResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserStorageProviderResource.java new file mode 100644 index 0000000000000..2838261219fca --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UserStorageProviderResource.java @@ -0,0 +1,90 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.quarkus.keycloak.admin.client.reactive.resource; + +import javax.ws.rs.POST; +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.MediaType; + +import org.keycloak.representations.idm.SynchronizationResultRepresentation; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public interface UserStorageProviderResource { + /** + * If the provider supports synchronization, this will invoke it. + * + * Action can be "triggerFullSync" or "triggerChangedUsersSync" + * + * + * @param componentId + * @param action + * @return + */ + @POST + @Path("{componentId}/sync") + @Produces(MediaType.APPLICATION_JSON) + SynchronizationResultRepresentation syncUsers(@PathParam("componentId") String componentId, + @QueryParam("action") String action); + + /** + * Remove imported users + * + * + * @param componentId + * @return + */ + @POST + @Path("{componentId}/remove-imported-users") + @Produces(MediaType.APPLICATION_JSON) + void removeImportedUsers(@PathParam("componentId") String componentId); + + /** + * Unlink imported users from a storage provider + * + * @param componentId + * @return + */ + @POST + @Path("{componentId}/unlink-users") + @Produces(MediaType.APPLICATION_JSON) + void unlink(@PathParam("componentId") String componentId); + + /** + * REST invocation for initiating sync for an ldap mapper. This method may be moved in the future. Right now + * don't have a good place for it. + * + * direction is "fedToKeycloak" or "keycloakToFed" + * + * + * @param componentId + * @param mapperId + * @param direction + * @return + */ + @POST + @Path("{componentId}/mappers/{mapperId}/sync") + @Produces(MediaType.APPLICATION_JSON) + SynchronizationResultRepresentation syncMapperData(@PathParam("componentId") String componentId, + @PathParam("mapperId") String mapperId, @QueryParam("direction") String direction); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UsersResource.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UsersResource.java new file mode 100755 index 0000000000000..06792871f2f3c --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/resource/UsersResource.java @@ -0,0 +1,271 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.resource; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import javax.ws.rs.core.Response; + +import org.keycloak.representations.idm.UserRepresentation; + +public interface UsersResource { + + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("username") String username, + @QueryParam("firstName") String firstName, + @QueryParam("lastName") String lastName, + @QueryParam("email") String email, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("username") String username, + @QueryParam("firstName") String firstName, + @QueryParam("lastName") String lastName, + @QueryParam("email") String email, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("enabled") Boolean enabled, + @QueryParam("briefRepresentation") Boolean briefRepresentation); + + /** + * Search for users based on the given filters. + * + * @param username a value contained in username + * @param firstName a value contained in first name + * @param lastName a value contained in last name + * @param email a value contained in email + * @param emailVerified whether the email has been verified + * @param idpAlias the alias of the Identity Provider + * @param idpUserId the userId at the Identity Provider + * @param firstResult the position of the first result to retrieve + * @param maxResults the maximum number of results to retrieve + * @param enabled only return enabled or disabled users + * @param briefRepresentation Only return basic information (only guaranteed to return id, username, created, first + * and last name, email, enabled state, email verification state, federation link, and access. + * Note that it means that namely user attributes, required actions, and not before are not returned.) + * @return a list of {@link UserRepresentation} + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("username") String username, + @QueryParam("firstName") String firstName, + @QueryParam("lastName") String lastName, + @QueryParam("email") String email, + @QueryParam("emailVerified") Boolean emailVerified, + @QueryParam("idpAlias") String idpAlias, + @QueryParam("idpUserId") String idpUserId, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("enabled") Boolean enabled, + @QueryParam("briefRepresentation") Boolean briefRepresentation); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("username") String username, + @QueryParam("firstName") String firstName, + @QueryParam("lastName") String lastName, + @QueryParam("email") String email, + @QueryParam("emailVerified") Boolean emailVerified, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("enabled") Boolean enabled, + @QueryParam("briefRepresentation") Boolean briefRepresentation); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("emailVerified") Boolean emailVerified, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("enabled") Boolean enabled, + @QueryParam("briefRepresentation") Boolean briefRepresentation); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("username") String username); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + List searchByAttributes(@QueryParam("q") String searchQuery); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + List searchByAttributes(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("enabled") Boolean enabled, + @QueryParam("briefRepresentation") Boolean briefRepresentation, + @QueryParam("q") String searchQuery); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("username") String username, @QueryParam("exact") Boolean exact); + + /** + * Search for users whose username or email matches the value provided by {@code search}. The {@code search} + * argument also allows finding users by specific attributes as follows: + * + *

    + *
  • id: - Find users by identifier. For instance, id:aa497859-bbf5-44ac-bf1a-74dbffcaf197
  • + *
+ * + * @param search the value to search. It can be the username, email or any of the supported options to query based on user + * attributes + * @param firstResult the position of the first result to retrieve + * @param maxResults the maximum number of results to retreive + * @return a list of {@link UserRepresentation} + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("search") String search, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + /** + * Search for users whose username or email matches the value provided by {@code search}. The {@code search} + * argument also allows finding users by specific attributes as follows: + * + *
    + *
  • id: - Find users by identifier. For instance, id:aa497859-bbf5-44ac-bf1a-74dbffcaf197
  • + *
+ * + * @param search the value to search. It can be the username, email or any of the supported options to query based on user + * attributes + * @param firstResult the position of the first result to retrieve + * @param maxResults the maximum number of results to retreive + * @param briefRepresentation Only return basic information (only guaranteed to return id, username, created, first and last + * name, + * email, enabled state, email verification state, federation link, and access. + * Note that it means that namely user attributes, required actions, and not before are not returned.) + * @return a list of {@link UserRepresentation} + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List search(@QueryParam("search") String search, + @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults, + @QueryParam("briefRepresentation") Boolean briefRepresentation); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + + @GET + @Produces(MediaType.APPLICATION_JSON) + List list(); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + Response create(UserRepresentation userRepresentation); + + /** + * Returns the number of users that can be viewed. + * + * @return number of users + */ + @Path("count") + @GET + @Produces(MediaType.APPLICATION_JSON) + Integer count(); + + /** + * Returns the number of users that can be viewed and match the given search criteria. + * If none is specified this is equivalent to {{@link #count()}}. + * + * @param search criteria to search for + * @return number of users matching the search criteria + */ + @Path("count") + @GET + @Produces(MediaType.APPLICATION_JSON) + Integer count(@QueryParam("search") String search); + + /** + * Returns the number of users that can be viewed and match the given filters. + * If none of the filters is specified this is equivalent to {{@link #count()}}. + * + * @param last last name field of a user + * @param first first name field of a user + * @param email email field of a user + * @param username username field of a user + * @return number of users matching the given filters + */ + @Path("count") + @GET + @Produces(MediaType.APPLICATION_JSON) + Integer count(@QueryParam("lastName") String last, + @QueryParam("firstName") String first, + @QueryParam("email") String email, + @QueryParam("username") String username); + + /** + * Returns the number of users that can be viewed and match the given filters. + * If none of the filters is specified this is equivalent to {{@link #count()}}. + * + * @param last last name field of a user + * @param first first name field of a user + * @param email email field of a user + * @param emailVerified emailVerified field of a user + * @param username username field of a user + * @return number of users matching the given filters + */ + @Path("count") + @GET + @Produces(MediaType.APPLICATION_JSON) + Integer count(@QueryParam("lastName") String last, + @QueryParam("firstName") String first, + @QueryParam("email") String email, + @QueryParam("emailVerified") Boolean emailVerified, + @QueryParam("username") String username); + + /** + * Returns the number of users with the given status for emailVerified. + * If none of the filters is specified this is equivalent to {{@link #count()}}. + * + * @param emailVerified emailVerified field of a user + * @return number of users matching the given filters + */ + @Path("count") + @GET + @Produces(MediaType.APPLICATION_JSON) + Integer countEmailVerified(@QueryParam("emailVerified") Boolean emailVerified); + + @Path("{id}") + UserResource get(@PathParam("id") String id); + + @Path("{id}") + @DELETE + Response delete(@PathParam("id") String id); + + @Path("profile") + UserProfileResource userProfile(); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/token/TokenManager.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/token/TokenManager.java new file mode 100644 index 0000000000000..ffec53e895be2 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/token/TokenManager.java @@ -0,0 +1,141 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.token; + +import static org.keycloak.OAuth2Constants.CLIENT_CREDENTIALS; +import static org.keycloak.OAuth2Constants.CLIENT_ID; +import static org.keycloak.OAuth2Constants.GRANT_TYPE; +import static org.keycloak.OAuth2Constants.PASSWORD; +import static org.keycloak.OAuth2Constants.REFRESH_TOKEN; + +import javax.ws.rs.BadRequestException; +import javax.ws.rs.client.Client; +import javax.ws.rs.core.Form; + +import org.jboss.resteasy.reactive.client.impl.WebTargetImpl; +import org.keycloak.common.util.Time; +import org.keycloak.representations.AccessTokenResponse; + +import io.quarkus.keycloak.admin.client.reactive.Config; +import io.quarkus.keycloak.admin.client.reactive.resource.BasicAuthFilter; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +public class TokenManager { + private static final long DEFAULT_MIN_VALIDITY = 30; + + private AccessTokenResponse currentToken; + private long expirationTime; + private long minTokenValidity = DEFAULT_MIN_VALIDITY; + private final Config config; + private final TokenService tokenService; + private final String accessTokenGrantType; + + public TokenManager(Config config, Client client) { + this.config = config; + WebTargetImpl target = (WebTargetImpl) client.target(config.getServerUrl()); + if (!config.isPublicClient()) { + target.register(new BasicAuthFilter(config.getClientId(), config.getClientSecret())); + } + this.tokenService = target.proxy(TokenService.class); + this.accessTokenGrantType = config.getGrantType(); + + if (CLIENT_CREDENTIALS.equals(accessTokenGrantType) && config.isPublicClient()) { + throw new IllegalArgumentException("Can't use " + GRANT_TYPE + "=" + CLIENT_CREDENTIALS + " with public client"); + } + } + + public String getAccessTokenString() { + return getAccessToken().getToken(); + } + + public synchronized AccessTokenResponse getAccessToken() { + if (currentToken == null) { + grantToken(); + } else if (tokenExpired()) { + refreshToken(); + } + return currentToken; + } + + public AccessTokenResponse grantToken() { + Form form = new Form().param(GRANT_TYPE, accessTokenGrantType); + if (PASSWORD.equals(accessTokenGrantType)) { + form.param("username", config.getUsername()) + .param("password", config.getPassword()); + } + + if (config.isPublicClient()) { + form.param(CLIENT_ID, config.getClientId()); + } + + int requestTime = Time.currentTime(); + synchronized (this) { + currentToken = tokenService.grantToken(config.getRealm(), form.asMap()); + expirationTime = requestTime + currentToken.getExpiresIn(); + } + return currentToken; + } + + public synchronized AccessTokenResponse refreshToken() { + if (currentToken.getRefreshToken() == null) { + return grantToken(); + } + + Form form = new Form().param(GRANT_TYPE, REFRESH_TOKEN) + .param(REFRESH_TOKEN, currentToken.getRefreshToken()); + + if (config.isPublicClient()) { + form.param(CLIENT_ID, config.getClientId()); + } + + try { + int requestTime = Time.currentTime(); + + currentToken = tokenService.refreshToken(config.getRealm(), form.asMap()); + expirationTime = requestTime + currentToken.getExpiresIn(); + return currentToken; + } catch (BadRequestException e) { + return grantToken(); + } + } + + public synchronized void setMinTokenValidity(long minTokenValidity) { + this.minTokenValidity = minTokenValidity; + } + + private synchronized boolean tokenExpired() { + return (Time.currentTime() + minTokenValidity) >= expirationTime; + } + + /** + * Invalidates the current token, but only when it is equal to the token passed as an argument. + * + * @param token the token to invalidate (cannot be null). + */ + public synchronized void invalidate(String token) { + if (currentToken == null) { + return; // There's nothing to invalidate. + } + if (token.equals(currentToken.getToken())) { + // When used next, this cause a refresh attempt, that in turn will cause a grant attempt if refreshing fails. + expirationTime = -1; + } + } +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/token/TokenService.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/token/TokenService.java new file mode 100755 index 0000000000000..14841b73d3d1f --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/token/TokenService.java @@ -0,0 +1,45 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.quarkus.keycloak.admin.client.reactive.token; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; + +import org.keycloak.representations.AccessTokenResponse; + +/** + * @author rodrigo.sasaki@icarros.com.br + */ +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_FORM_URLENCODED) +public interface TokenService { + + @POST + @Path("/realms/{realm}/protocol/openid-connect/token") + AccessTokenResponse grantToken(@PathParam("realm") String realm, MultivaluedMap map); + + @POST + @Path("/realms/{realm}/protocol/openid-connect/token") + AccessTokenResponse refreshToken(@PathParam("realm") String realm, MultivaluedMap map); + +} diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/resources/META-INF/beans.xml b/extensions/keycloak-admin-client-reactive/runtime/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/keycloak-admin-client-reactive/runtime/src/main/resources/META-INF/quarkus-extension.yaml new file mode 100644 index 0000000000000..1b25b21992356 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -0,0 +1,12 @@ +--- +artifact: ${project.groupId}:${project.artifactId}:${project.version} +name: "Keycloak Admin Client Reactive" +metadata: + keywords: + - "keycloak" + - "keycloak-admin-client" + - "admin" + - "openid-connect" + categories: + - "security" + status: "experimental" diff --git a/extensions/pom.xml b/extensions/pom.xml index 9214213a58046..e080ce3a235bb 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -132,6 +132,7 @@ oidc-token-propagation-reactive keycloak-authorization keycloak-admin-client + keycloak-admin-client-reactive credentials From 587e67acf5b04c4cd8d179a48d6fcc4e6bf1880c Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Mon, 14 Mar 2022 11:00:37 +0200 Subject: [PATCH 2/2] Move keycloak-authorization IT to RESTEasy Reactive and Reactive Keycloak admin client --- .../keycloak-authorization/pom.xml | 31 +++++++------------ .../it/keycloak/AdminClientResource.java | 5 +-- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/integration-tests/keycloak-authorization/pom.xml b/integration-tests/keycloak-authorization/pom.xml index 40bdf4db83e3c..f7404d7d99329 100644 --- a/integration-tests/keycloak-authorization/pom.xml +++ b/integration-tests/keycloak-authorization/pom.xml @@ -24,15 +24,11 @@ io.quarkus - quarkus-resteasy-mutiny + quarkus-keycloak-admin-client-reactive io.quarkus - quarkus-keycloak-admin-client - - - io.quarkus - quarkus-resteasy-jackson + quarkus-resteasy-reactive-jackson io.quarkus @@ -50,24 +46,21 @@ rest-assured test - - - io.quarkus - quarkus-keycloak-admin-client-deployment - ${project.version} - pom - test + org.keycloak + keycloak-admin-client - * - * + jakarta.activation + jakarta.activation-api + + io.quarkus - quarkus-keycloak-authorization-deployment + quarkus-keycloak-admin-client-reactive-deployment ${project.version} pom test @@ -80,7 +73,7 @@ io.quarkus - quarkus-oidc-deployment + quarkus-keycloak-authorization-deployment ${project.version} pom test @@ -93,7 +86,7 @@ io.quarkus - quarkus-resteasy-jackson-deployment + quarkus-oidc-deployment ${project.version} pom test @@ -106,7 +99,7 @@ io.quarkus - quarkus-resteasy-mutiny-deployment + quarkus-resteasy-reactive-jackson-deployment ${project.version} pom test diff --git a/integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/AdminClientResource.java b/integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/AdminClientResource.java index 426dfe1bd10ed..7958df1704ca5 100644 --- a/integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/AdminClientResource.java +++ b/integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/AdminClientResource.java @@ -10,8 +10,6 @@ import javax.ws.rs.core.MediaType; import org.eclipse.microprofile.config.inject.ConfigProperty; -import org.keycloak.admin.client.Keycloak; -import org.keycloak.admin.client.KeycloakBuilder; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.RealmRepresentation; @@ -19,6 +17,9 @@ import org.keycloak.representations.idm.RolesRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import io.quarkus.keycloak.admin.client.reactive.Keycloak; +import io.quarkus.keycloak.admin.client.reactive.KeycloakBuilder; + @Path("/admin-client") public class AdminClientResource {