Skip to content

Commit

Permalink
Introducing the extensions/organization
Browse files Browse the repository at this point in the history
Signed-off-by: Pedro Igor <[email protected]>
  • Loading branch information
pedroigor committed Mar 13, 2024
1 parent 1788cf2 commit 32de22a
Show file tree
Hide file tree
Showing 13 changed files with 497 additions and 0 deletions.
55 changes: 55 additions & 0 deletions extensions/organization/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!--
~ 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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>999.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<name>Keycloak Organization Extension</name>
<modelVersion>4.0.0</modelVersion>

<artifactId>keycloak-organization</artifactId>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-junit5</artifactId>
</dependency>

<!-- Test -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2024 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 org.keycloak.organization;

public class OrganizationRepresentation {

private String name;
private String id;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2024 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 org.keycloak.organization.admin.resource;

import java.util.stream.Stream;

import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import org.keycloak.organization.OrganizationRepresentation;
import org.keycloak.utils.StringUtil;

@Path("/")
public class OrganizationAdminResource {

public OrganizationAdminResource() {}

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response create(OrganizationRepresentation organizaiton) {
return Response.status(Status.CREATED).build();
}

@Path("{id}")
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
public Response delete(@PathParam("id") String id) {
if (StringUtil.isBlank(id)) {
throw new BadRequestException();
}
return Response.noContent().build();
}

@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Stream<OrganizationRepresentation> get(@PathParam("id") String id) {
OrganizationRepresentation organization = new OrganizationRepresentation();

organization.setId("1");
organization.setName("acme");

return Stream.of(organization);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2024 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 org.keycloak.organization.admin.resource;

import org.keycloak.Config.Scope;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProvider;
import org.keycloak.services.resources.admin.ext.AdminRealmResourceProviderFactory;

public class OrganizationAdminResourceFactory implements AdminRealmResourceProviderFactory {

private OrganizationAdminResourceProvider PROVIDER_INSTANCE;

@Override
public AdminRealmResourceProvider create(KeycloakSession session) {
return PROVIDER_INSTANCE;
}

@Override
public void init(Scope config) {

}

@Override
public void postInit(KeycloakSessionFactory factory) {
PROVIDER_INSTANCE = new OrganizationAdminResourceProvider();
}

@Override
public void close() {

}

@Override
public String getId() {
return "organization";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2024 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 org.keycloak.organization.admin.resource;

import org.keycloak.models.KeycloakSession;
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.permissions.AdminPermissionEvaluator;

public class OrganizationAdminResourceProvider implements AdminRealmResourceProvider {

@Override
public Object getResource(KeycloakSession session, RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
return new OrganizationAdminResource();
}

@Override
public void close() {

}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# /*
# * Copyright 2024 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.
# */
#
org.keycloak.organization.admin.resource.OrganizationAdminResourceFactory
27 changes: 27 additions & 0 deletions extensions/organization/src/test/java/KeycloakTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2024 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.
*/

import org.keycloak.Keycloak;

public class KeycloakTest {

public static void main(String[] args) {
Keycloak.builder()
.addDependency("org.keycloak", "keycloak-organization", "999.0.0-SNAPSHOT")
.start(args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2024 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 org.keycloak.organization;

import java.util.List;

import io.restassured.RestAssured;
import io.restassured.common.mapper.TypeRef;
import io.restassured.specification.RequestSpecification;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response.Status;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;

public class OrganizationAdminRestApiTest {

private static final TypeRef<List<OrganizationRepresentation>> ORGANIZATION_LIST_TYPE_DEF = new TypeRef<List<OrganizationRepresentation>>() {};
private static final String BASE_SERVER_URL = "http://localhost:8180";

private Keycloak kcClient;
private String accessToken;
private RequestSpecification restAssured;

@BeforeEach
public void onBefore() {
kcClient = Keycloak.getInstance(BASE_SERVER_URL, "master", "admin", "admin", "admin-cli");
accessToken = kcClient.tokenManager().getAccessTokenString();
restAssured = RestAssured.given().auth().oauth2(accessToken);
}

@AfterEach
public void onAfter() {
if (kcClient != null) {
kcClient.close();
}
}

@Test
public void testCreate() {
OrganizationRepresentation org = new OrganizationRepresentation();

org.setName("acme");

restAssured.body(org)
.contentType(MediaType.APPLICATION_JSON)
.post(BASE_SERVER_URL.concat("/admin/realms/master/organization"))
.then()
.statusCode(Status.CREATED.getStatusCode());
}

@Test
public void testDelete() {
OrganizationRepresentation org = new OrganizationRepresentation();

org.setId("1");

restAssured.delete(BASE_SERVER_URL.concat("/admin/realms/master/organization/{id}"), org.getId())
.then()
.statusCode(Status.NO_CONTENT.getStatusCode());
}

@Test
public void testGet() {
List<OrganizationRepresentation> organizations = restAssured
.get(BASE_SERVER_URL.concat("/admin/realms/master/organization"))
.as(ORGANIZATION_LIST_TYPE_DEF);
Assertions.assertFalse(organizations.isEmpty());
}
}
Loading

0 comments on commit 32de22a

Please sign in to comment.