revert kotlin back to java (#3183)

removing all extra dependencies
This commit is contained in:
Erik Jan de Wit 2022-08-24 15:35:38 +02:00 committed by GitHub
parent b5ea27c194
commit a0a154d9c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 556 additions and 562 deletions

View file

@ -37,8 +37,6 @@
<frontend.maven.plugin.nodeVersion>v18.7.0</frontend.maven.plugin.nodeVersion>
<keycloak.version>19.0.1</keycloak.version>
<kotlin.version>1.7.10</kotlin.version>
<mapstruct.version>1.5.2.Final</mapstruct.version>
</properties>
<licenses>
@ -93,27 +91,11 @@
<artifactId>keycloak-services</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.openapi</groupId>
<artifactId>microprofile-openapi-api</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
@ -191,78 +173,10 @@
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/java</sourceDir>
</sourceDirs>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<source>8</source>
<target>8</target>

View file

@ -0,0 +1,35 @@
package org.keycloak.admin.ui.rest;
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.services.resources.admin.AdminEventBuilder;
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProvider;
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProviderFactory;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
public final class AvailableRoleMappingProvider implements AdminRealmResourceProviderFactory, AdminRealmResourceProvider {
public AdminRealmResourceProvider create(KeycloakSession session) {
return this;
}
public void init(Config.Scope config) {
}
public void postInit(KeycloakSessionFactory factory) {
}
public void close() {
}
public String getId() {
return "admin-ui-available-roles";
}
public Object getResource(KeycloakSession session, RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
return new AvailableRoleMappingResource(realm, auth);
}
}

View file

@ -1,32 +0,0 @@
package org.keycloak.admin.ui.rest
import org.keycloak.Config
import org.keycloak.models.KeycloakSession
import org.keycloak.models.KeycloakSessionFactory
import org.keycloak.models.RealmModel
import org.keycloak.services.resources.admin.AdminEventBuilder
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProvider
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProviderFactory
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator
class AvailableRoleMappingProvider : AdminRealmResourceProviderFactory, AdminRealmResourceProvider {
override fun create(session: KeycloakSession): AdminRealmResourceProvider {
return this
}
override fun init(config: Config.Scope) {}
override fun postInit(factory: KeycloakSessionFactory) {}
override fun close() {}
override fun getId(): String {
return "admin-ui-available-roles"
}
override fun getResource(
session: KeycloakSession,
realm: RealmModel,
auth: AdminPermissionEvaluator,
adminEvent: AdminEventBuilder
): Any {
return AvailableRoleMappingResource(realm, auth)
}
}

View file

@ -0,0 +1,184 @@
package org.keycloak.admin.ui.rest;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.keycloak.admin.ui.rest.model.ClientRole;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
public class AvailableRoleMappingResource extends RoleMappingResource {
@Context
private KeycloakSession session;
private final RealmModel realm;
private final AdminPermissionEvaluator auth;
public AvailableRoleMappingResource(RealmModel realm, AdminPermissionEvaluator auth) {
super(realm, auth);
this.realm = realm;
this.auth = auth;
}
@GET
@Path("/clientScopes/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all composite client roles for this client scope",
description = "This endpoint returns all the client role mapping for a specific client scope"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeClientScopeRoleMappings(@PathParam("id") String id, @QueryParam("first")
@DefaultValue("0") long first, @QueryParam("max") @DefaultValue("10") long max, @QueryParam("search") @DefaultValue("") String search) {
ClientScopeModel scopeModel = this.realm.getClientScopeById(id);
if (scopeModel == null) {
throw new NotFoundException("Could not find client scope");
} else {
this.auth.clients().requireView(scopeModel);
return this.mapping(((Predicate<RoleModel>) scopeModel::hasDirectScope).negate(), first, max, search);
}
}
@GET
@Path("/clients/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all composite client roles for this client",
description = "This endpoint returns all the client role mapping for a specific client"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeClientRoleMappings(@PathParam("id") String id, @QueryParam("first")
@DefaultValue("0") long first, @QueryParam("max") @DefaultValue("10") long max, @QueryParam("search") @DefaultValue("") String search) {
ClientModel client = this.realm.getClientById(id);
if (client == null) {
throw new NotFoundException("Could not find client");
} else {
this.auth.clients().requireView(client);
return this.mapping(((Predicate<RoleModel>) client::hasDirectScope).negate(), first, max, search);
}
}
@GET
@Path("/groups/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all composite client roles for this group",
description = "This endpoint returns all the client role mapping for a specific group"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeGroupRoleMappings(@PathParam("id") String id, @QueryParam("first")
@DefaultValue("0") long first, @QueryParam("max") @DefaultValue("10") long max, @QueryParam("search") @DefaultValue("") String search) {
GroupModel group = this.realm.getGroupById(id);
if (group == null) {
throw new NotFoundException("Could not find group");
} else {
this.auth.groups().requireView(group);
return this.mapping(((Predicate<RoleModel>) group::hasDirectRole).negate(), first, max, search);
}
}
@GET
@Path("/users/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all composite client roles for this user",
description = "This endpoint returns all the client role mapping for a specific user"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeUserRoleMappings(@PathParam("id") String id, @QueryParam("first") @DefaultValue("0") long first,
@QueryParam("max") @DefaultValue("10") long max, @QueryParam("search") @DefaultValue("") String search) {
UserProvider users = Objects.requireNonNull(session).users();
UserModel userModel = users.getUserById(this.realm, id);
if (userModel == null) {
if (auth.users().canQuery()) throw new NotFoundException("User not found");
else throw new ForbiddenException();
}
this.auth.users().requireView(userModel);
return this.mapping(((Predicate<RoleModel>) userModel::hasDirectRole).negate(), first, max, search);
}
@GET
@Path("/roles/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all composite client roles",
description = "This endpoint returns all the client role"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeRoleMappings(@QueryParam("first") @DefaultValue("0") long first,
@QueryParam("max") @DefaultValue("10") long max, @QueryParam("search") @DefaultValue("") String search) {
return this.mapping(o -> true, first, max, search);
}
}

View file

@ -1,178 +0,0 @@
package org.keycloak.admin.ui.rest
import org.eclipse.microprofile.openapi.annotations.Operation
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType
import org.eclipse.microprofile.openapi.annotations.media.Content
import org.eclipse.microprofile.openapi.annotations.media.Schema
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse
import org.keycloak.admin.ui.rest.model.ClientRole
import org.keycloak.admin.ui.rest.model.RoleMapper
import org.keycloak.models.KeycloakSession
import org.keycloak.models.RealmModel
import org.keycloak.models.RoleModel
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator
import org.mapstruct.factory.Mappers
import java.util.*
import java.util.function.Predicate
import java.util.stream.Collectors
import javax.ws.rs.*
import javax.ws.rs.core.Context
import javax.ws.rs.core.MediaType
@Path("/")
open class AvailableRoleMappingResource(
private var realm: RealmModel,
private var auth: AdminPermissionEvaluator,
) : RoleMappingResource(realm, auth) {
@Context
var session: KeycloakSession? = null
@GET
@Path("/clientScopes/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all composite client roles for this client scope",
description = "This endpoint returns all the client role mapping for a specific client scope"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeClientScopeRoleMappings(
@PathParam("id") id: String,
@QueryParam("first") @DefaultValue("0") first: Long,
@QueryParam("max") @DefaultValue("10") max: Long,
@QueryParam("search") @DefaultValue("") search: String
): List<ClientRole> {
val scopeContainer = realm.getClientScopeById(id) ?: throw NotFoundException("Could not find client scope")
auth.clients().requireView(scopeContainer)
return mapping(Predicate<RoleModel?> { r -> scopeContainer.hasDirectScope(r) }.negate(), first, max, search)
}
@GET
@Path("/clients/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all composite client roles for this client",
description = "This endpoint returns all the client role mapping for a specific client"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeClientRoleMappings(
@PathParam("id") id: String,
@QueryParam("first") @DefaultValue("0") first: Long,
@QueryParam("max") @DefaultValue("10") max: Long,
@QueryParam("search") @DefaultValue("") search: String
): List<ClientRole> {
val scopeContainer = realm.getClientById(id) ?: throw NotFoundException("Could not find client")
auth.clients().requireView(scopeContainer)
return mapping(Predicate<RoleModel?> { r -> scopeContainer.hasDirectScope(r) }.negate(), first, max, search)
}
@GET
@Path("/groups/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all composite client roles for this group",
description = "This endpoint returns all the client role mapping for a specific group"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeGroupRoleMappings(
@PathParam("id") id: String,
@QueryParam("first") @DefaultValue("0") first: Long,
@QueryParam("max") @DefaultValue("10") max: Long,
@QueryParam("search") @DefaultValue("") search: String
): List<ClientRole> {
val scopeContainer = realm.getGroupById(id) ?: throw NotFoundException("Could not find group")
auth.groups().requireView(scopeContainer)
return mapping(Predicate<RoleModel?> { r -> scopeContainer.hasDirectRole(r) }.negate(), first, max, search)
}
@GET
@Path("/users/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all composite client roles for this user",
description = "This endpoint returns all the client role mapping for a specific user"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeUserRoleMappings(
@PathParam("id") id: String,
@QueryParam("first") @DefaultValue("0") first: Long,
@QueryParam("max") @DefaultValue("10") max: Long,
@QueryParam("search") @DefaultValue("") search: String
): List<ClientRole> {
val user = session?.users()?.getUserById(realm, id)
?: if (auth.users().canQuery()) throw NotFoundException("User not found") else throw ForbiddenException()
auth.users().requireView(user)
return mapping(Predicate<RoleModel?> { r -> user.hasDirectRole(r) }.negate(), first, max, search)
}
@GET
@Path("/roles/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all composite client roles",
description = "This endpoint returns all the client role"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeRoleMappings(
@QueryParam("first") @DefaultValue("0") first: Long,
@QueryParam("max") @DefaultValue("10") max: Long,
@QueryParam("search") @DefaultValue("") search: String
): List<ClientRole> {
return mapping({ true }, first, max, search)
}
}

View file

@ -0,0 +1,35 @@
package org.keycloak.admin.ui.rest;
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.services.resources.admin.AdminEventBuilder;
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProvider;
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProviderFactory;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
public final class EffectiveRoleMappingProvider implements AdminRealmResourceProviderFactory, AdminRealmResourceProvider {
public AdminRealmResourceProvider create(KeycloakSession session) {
return this;
}
public void init(Config.Scope config) {
}
public void postInit(KeycloakSessionFactory factory) {
}
public void close() {
}
public String getId() {
return "admin-ui-effective-roles";
}
public Object getResource(KeycloakSession session, RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
return new EffectiveRoleMappingResource(realm, auth);
}
}

View file

@ -1,32 +0,0 @@
package org.keycloak.admin.ui.rest
import org.keycloak.Config
import org.keycloak.models.KeycloakSession
import org.keycloak.models.KeycloakSessionFactory
import org.keycloak.models.RealmModel
import org.keycloak.services.resources.admin.AdminEventBuilder
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProvider
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProviderFactory
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator
class EffectiveRoleMappingProvider : AdminRealmResourceProviderFactory, AdminRealmResourceProvider {
override fun create(session: KeycloakSession): AdminRealmResourceProvider {
return this
}
override fun init(config: Config.Scope) {}
override fun postInit(factory: KeycloakSessionFactory) {}
override fun close() {}
override fun getId(): String {
return "admin-ui-effective-roles"
}
override fun getResource(
session: KeycloakSession,
realm: RealmModel,
auth: AdminPermissionEvaluator,
adminEvent: AdminEventBuilder
): Any {
return EffectiveRoleMappingResource(realm, auth)
}
}

View file

@ -0,0 +1,171 @@
package org.keycloak.admin.ui.rest;
import java.util.List;
import java.util.stream.Collectors;
import javax.ws.rs.Consumes;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.keycloak.admin.ui.rest.model.ClientRole;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
public class EffectiveRoleMappingResource extends RoleMappingResource {
@Context
private KeycloakSession session;
private RealmModel realm;
private AdminPermissionEvaluator auth;
public EffectiveRoleMappingResource(RealmModel realm, AdminPermissionEvaluator auth) {
super(realm, auth);
this.realm = realm;
this.auth = auth;
}
@GET
@Path("/clientScopes/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all effective roles for this client scope",
description = "This endpoint returns all the client role mapping for a specific client scope"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeClientScopeRoleMappings(@PathParam("id") String id) {
ClientScopeModel clientScope = this.realm.getClientScopeById(id);
if (clientScope == null) {
throw new NotFoundException("Could not find client scope");
}
this.auth.clients().requireView(clientScope);
return this.mapping(clientScope::hasScope).collect(Collectors.toList());
}
@GET
@Path("/clients/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all effective roles for this client",
description = "This endpoint returns all the client role mapping for a specific client"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeClientsRoleMappings(@PathParam("id") String id) {
ClientModel client = this.realm.getClientById(id);
if (client == null) {
throw new NotFoundException("Could not find client");
}
auth.clients().requireView(client);
return mapping(client::hasScope).collect(Collectors.toList());
}
@GET
@Path("/groups/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all effective roles for this group",
description = "This endpoint returns all the client role mapping for a specific group"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeGroupsRoleMappings(@PathParam("id") String id) {
GroupModel group = this.realm.getGroupById(id);
if (group == null) {
throw new NotFoundException("Could not find group");
}
return mapping(group::hasDirectRole).collect(Collectors.toList());
}
@GET
@Path("/users/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all effective roles for this users",
description = "This endpoint returns all the client role mapping for a specific users"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeUsersRoleMappings(@PathParam("id") String id) {
UserModel user = session.users().getUserById(this.realm, id);
if (user == null) {
if (auth.users().canQuery()) throw new NotFoundException("User not found");
else throw new ForbiddenException();
}
return mapping(user::hasDirectRole).collect(Collectors.toList());
}
@GET
@Path("/roles/{id}")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(
summary = "List all effective roles for this realm role",
description = "This endpoint returns all the client role mapping for a specific realm role"
)
@APIResponse(
responseCode = "200",
description = "",
content = {@Content(
schema = @Schema(
implementation = ClientRole.class,
type = SchemaType.ARRAY
)
)}
)
public final List<ClientRole> listCompositeRealmRoleMappings() {
return mapping (o -> true ).collect(Collectors.toList());
}
}

View file

@ -1,156 +0,0 @@
package org.keycloak.admin.ui.rest
import org.eclipse.microprofile.openapi.annotations.Operation
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType
import org.eclipse.microprofile.openapi.annotations.media.Content
import org.eclipse.microprofile.openapi.annotations.media.Schema
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse
import org.keycloak.admin.ui.rest.model.ClientRole
import org.keycloak.models.KeycloakSession
import org.keycloak.models.RealmModel
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator
import java.util.stream.Collectors
import javax.ws.rs.*
import javax.ws.rs.core.Context
import javax.ws.rs.core.MediaType
@Path("/")
open class EffectiveRoleMappingResource(
private var realm: RealmModel,
private var auth: AdminPermissionEvaluator,
) : RoleMappingResource(realm, auth) {
@Context
var session: KeycloakSession? = null
@GET
@Path("/clientScopes/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all effective roles for this client scope",
description = "This endpoint returns all the client role mapping for a specific client scope"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeClientScopeRoleMappings(
@PathParam("id") id: String,
): List<ClientRole> {
val scopeContainer = realm.getClientScopeById(id) ?: throw NotFoundException("Could not find client scope")
auth.clients().requireView(scopeContainer)
return mapping(scopeContainer::hasScope).collect(Collectors.toList())
}
@GET
@Path("/clients/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all effective roles for this client",
description = "This endpoint returns all the client role mapping for a specific client"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeClientsRoleMappings(
@PathParam("id") id: String,
): List<ClientRole> {
val scopeContainer = realm.getClientById(id) ?: throw NotFoundException("Could not find client")
auth.clients().requireView(scopeContainer)
return mapping(scopeContainer::hasScope).collect(Collectors.toList())
}
@GET
@Path("/groups/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all effective roles for this group",
description = "This endpoint returns all the client role mapping for a specific group"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeGroupsRoleMappings(
@PathParam("id") id: String,
): List<ClientRole> {
val scopeContainer = realm.getGroupById(id) ?: throw NotFoundException("Could not find group")
return mapping(scopeContainer::hasDirectRole).collect(Collectors.toList())
}
@GET
@Path("/users/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all effective roles for this users",
description = "This endpoint returns all the client role mapping for a specific users"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeUsersRoleMappings(
@PathParam("id") id: String,
): List<ClientRole> {
val user = session?.users()?.getUserById(realm, id)
?: if (auth.users().canQuery()) throw NotFoundException("User not found") else throw ForbiddenException()
auth.users().requireView(user)
return mapping(user::hasDirectRole).collect(Collectors.toList())
}
@GET
@Path("/roles/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "List all effective roles for this realm role",
description = "This endpoint returns all the client role mapping for a specific realm role"
)
@APIResponse(
responseCode = "200",
description = "",
content = [Content(
schema = Schema(
type = SchemaType.ARRAY,
implementation = ClientRole::class
)
)]
)
fun listCompositeRealmRoleMappings(
): List<ClientRole> {
return mapping { true }.collect(Collectors.toList())
}
}

View file

@ -0,0 +1,35 @@
package org.keycloak.admin.ui.rest;
import static org.keycloak.admin.ui.rest.model.RoleMapper.convertToRepresentation;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.admin.ui.rest.model.ClientRole;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
public abstract class RoleMappingResource {
private RealmModel realm;
private AdminPermissionEvaluator auth;
public final Stream<ClientRole> mapping(Predicate<RoleModel> predicate) {
return realm.getClientsStream().flatMap(RoleContainerModel::getRolesStream).filter(predicate)
.filter(auth.roles()::canMapClientScope).map(roleModel -> convertToRepresentation(roleModel, realm.getClientsStream()));
}
public final List<ClientRole> mapping(Predicate<RoleModel> predicate, long first, long max, final String search) {
return mapping(predicate).filter(clientRole -> clientRole.getClient().contains(search) || clientRole.getRole().contains(search))
.skip("".equals(search) ? first : 0).limit(max).collect(Collectors.toList());
}
public RoleMappingResource(RealmModel realm, AdminPermissionEvaluator auth) {
this.realm = realm;
this.auth = auth;
}
}

View file

@ -1,45 +0,0 @@
package org.keycloak.admin.ui.rest
import org.keycloak.admin.ui.rest.model.ClientRole
import org.keycloak.admin.ui.rest.model.RoleMapper
import org.keycloak.models.RealmModel
import org.keycloak.models.RoleModel
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator
import org.mapstruct.factory.Mappers
import java.util.*
import java.util.function.Predicate
import java.util.stream.Collectors
import java.util.stream.Stream
abstract class RoleMappingResource(
private var realm: RealmModel,
private var auth: AdminPermissionEvaluator,
) {
fun mapping(
predicate: Predicate<RoleModel?>,
): Stream<ClientRole> {
val mapper = Mappers.getMapper(RoleMapper::class.java)
return realm.clientsStream
.flatMap { c -> c.rolesStream }
.filter(predicate)
.filter(auth.roles()::canMapClientScope)
.map { r -> mapper.convertToRepresentation(r, realm.clientsStream) }
}
fun mapping(
predicate: Predicate<RoleModel?>,
first: Long,
max: Long,
search: String
): List<ClientRole> {
return mapping(predicate)
.filter { r -> r.client!!.contains(search, true) || r.role.contains(search, true) }
.skip(if (search.isBlank()) first else 0)
.limit(max)
.collect(Collectors.toList()) ?: Collections.emptyList()
}
}

View file

@ -0,0 +1,79 @@
package org.keycloak.admin.ui.rest.model;
import java.util.Objects;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
public final class ClientRole {
@Schema(required = true) private final String id;
@Schema(required = true) private final String role;
@Schema(required = true) private String client;
@Schema(required = true) private String clientId;
private String description;
public String getId() {
return this.id;
}
public String getRole() {
return this.role;
}
public String getClient() {
return this.client;
}
public void setClient(String client) {
this.client = client;
}
public String getClientId() {
return this.clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public ClientRole(String id, String role, String description) {
this.id = id;
this.role = role;
this.description = description;
}
public ClientRole(String id, String role, String client, String clientId, String description) {
this.id = id;
this.role = role;
this.client = client;
this.clientId = clientId;
this.description = description;
}
public ClientRole copy(String id, String role, String client, String clientId, String description) {
return new ClientRole(id, role, client, clientId, description);
}
@Override public String toString() {
return "ClientRole{" + "id='" + id + '\'' + ", role='" + role + '\'' + ", client='" + client + '\'' + ", clientId='" + clientId + '\'' + ", description='" + description + '\'' + '}';
}
@Override public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ClientRole that = (ClientRole) o;
return id.equals(that.id) && role.equals(that.role) && client.equals(that.client) && clientId.equals(that.clientId);
}
@Override public int hashCode() {
return Objects.hash(id, role, client, clientId);
}
}

View file

@ -1,12 +0,0 @@
package org.keycloak.admin.ui.rest.model
import org.eclipse.microprofile.openapi.annotations.media.Schema
data class ClientRole(
@field:Schema(required = true) var id: String,
@field:Schema(required = true) var role: String,
@field:Schema(required = true) var client: String?,
@field:Schema(required = true) var clientId: String?,
var description: String?
) {
}

View file

@ -0,0 +1,17 @@
package org.keycloak.admin.ui.rest.model;
import java.util.stream.Stream;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RoleModel;
public class RoleMapper {
public static ClientRole convertToRepresentation(RoleModel roleModel, Stream<ClientModel> clients) {
ClientRole clientRole = new ClientRole(roleModel.getId(), roleModel.getName(), roleModel.getDescription());
ClientModel clientModel = clients.filter(c -> roleModel.getContainerId().equals(c.getId())).findFirst()
.orElseThrow(() -> new IllegalArgumentException("Could not find referenced client"));
clientRole.setClientId(clientModel.getId());
clientRole.setClient(clientModel.getClientId());
return clientRole;
}
}

View file

@ -1,21 +0,0 @@
package org.keycloak.admin.ui.rest.model
import org.keycloak.models.ClientModel
import org.keycloak.models.RoleModel
import org.mapstruct.*
import java.util.stream.Stream
@Mapper
abstract class RoleMapper {
@Mapping(source = "name", target = "role")
@Mapping(target = "client", ignore = true)
abstract fun convertToRepresentation(role: RoleModel, @Context clientModel: Stream<ClientModel>): ClientRole
@AfterMapping
fun convert(role: RoleModel, @MappingTarget clientRole: ClientRole, @Context list: Stream<ClientModel>) {
val clientModel = list.filter { c -> role.containerId == c.id }.findFirst().get()
clientRole.clientId = clientModel.id
clientRole.client = clientModel.clientId
}
}