diff --git a/search-in-keycloak-with-spring-boot/.gitignore b/search-in-keycloak-with-spring-boot/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/search-in-keycloak-with-spring-boot/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/search-in-keycloak-with-spring-boot/pom.xml b/search-in-keycloak-with-spring-boot/pom.xml new file mode 100644 index 0000000..9a8b4d6 --- /dev/null +++ b/search-in-keycloak-with-spring-boot/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.0.6 + + + com.example + search-in-keycloak-with-spring-boot + 0.0.1-SNAPSHOT + search-in-keycloak-with-spring-boot + search-in-keycloak-with-spring-boot + + 17 + + + + org.springframework.boot + spring-boot-starter-web + + + org.keycloak + keycloak-admin-client + 19.0.1 + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/SearchInKeycloakWithSpringBootApplication.java b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/SearchInKeycloakWithSpringBootApplication.java new file mode 100644 index 0000000..d80088e --- /dev/null +++ b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/SearchInKeycloakWithSpringBootApplication.java @@ -0,0 +1,13 @@ +package com.example.searchinkeycloakwithspringboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SearchInKeycloakWithSpringBootApplication { + + public static void main(String[] args) { + SpringApplication.run(SearchInKeycloakWithSpringBootApplication.class, args); + } + +} diff --git a/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/config/Config.java b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/config/Config.java new file mode 100644 index 0000000..815be5b --- /dev/null +++ b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/config/Config.java @@ -0,0 +1,27 @@ +package com.example.searchinkeycloakwithspringboot.config; + +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; +import org.keycloak.OAuth2Constants; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.KeycloakBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +@Configuration +public class Config { + + @Bean + public Keycloak keycloak() { + return KeycloakBuilder.builder() + .serverUrl("http://localhost:8080/") + .realm("master") + .grantType(OAuth2Constants.PASSWORD) + .username("admin") + .password("admin") + .clientId("admin-cli") + .resteasyClient(new ResteasyClientBuilder() + .connectionPoolSize(10) + .build()).build(); + } +} diff --git a/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/exception/UserNotFoundInKeycloakException.java b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/exception/UserNotFoundInKeycloakException.java new file mode 100644 index 0000000..fae1419 --- /dev/null +++ b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/exception/UserNotFoundInKeycloakException.java @@ -0,0 +1,7 @@ +package com.example.searchinkeycloakwithspringboot.exception; + +public class UserNotFoundInKeycloakException extends Exception{ + public UserNotFoundInKeycloakException(String message) { + super(message); + } +} diff --git a/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/exception/handler/ExceptionController.java b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/exception/handler/ExceptionController.java new file mode 100644 index 0000000..91e1e84 --- /dev/null +++ b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/exception/handler/ExceptionController.java @@ -0,0 +1,18 @@ +package com.example.searchinkeycloakwithspringboot.exception.handler; + +import com.example.searchinkeycloakwithspringboot.exception.UserNotFoundInKeycloakException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class ExceptionController { + + + + @ExceptionHandler + public ResponseEntity handleUserNotFoundInKeycloakException(UserNotFoundInKeycloakException e){ + return ResponseEntity.badRequest().body(e.getMessage()); + } + +} diff --git a/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/service/KeycloakService.java b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/service/KeycloakService.java new file mode 100644 index 0000000..83a9d3a --- /dev/null +++ b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/service/KeycloakService.java @@ -0,0 +1,51 @@ +package com.example.searchinkeycloakwithspringboot.service; + +import com.example.searchinkeycloakwithspringboot.exception.UserNotFoundInKeycloakException; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.resource.RoleResource; +import org.keycloak.admin.client.resource.UserResource; +import org.keycloak.representations.idm.UserRepresentation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Set; + +@Service +public class KeycloakService { + + + @Autowired + private Keycloak keycloak; + + + public UserRepresentation searchById(String id) { + UserResource userResource = keycloak.realm("master").users().get(id); + return userResource.toRepresentation(); + } + public UserRepresentation searchByEmail(String email) throws UserNotFoundInKeycloakException { + List userRepresentations = keycloak.realm("master").users().search(null, null, null, email, 0, 1); + if (userRepresentations.isEmpty()) { + throw new UserNotFoundInKeycloakException("User with email " + email + " not found"); + } + return userRepresentations.get(0); + } + public UserRepresentation searchByUsername(String username) throws UserNotFoundInKeycloakException { + List userRepresentations = keycloak.realm("master").users().search(username, true); + if (userRepresentations.isEmpty()) { + throw new UserNotFoundInKeycloakException("User with username " + username + " not found"); + } + return userRepresentations.get(0); + } + public UserRepresentation searchByPhone(String phone) throws UserNotFoundInKeycloakException { + List userRepresentations = keycloak.realm("master").users().searchByAttributes("phone:" + phone); + if (userRepresentations.isEmpty()) { + throw new UserNotFoundInKeycloakException("User with phone number " + phone + " not found"); + } + return userRepresentations.get(0); + } + public Set searchByRole(String roleName) { + return keycloak.realm("master").roles().get(roleName).getRoleUserMembers() ; + } + +} diff --git a/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/web/SearchController.java b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/web/SearchController.java new file mode 100644 index 0000000..ffdba34 --- /dev/null +++ b/search-in-keycloak-with-spring-boot/src/main/java/com/example/searchinkeycloakwithspringboot/web/SearchController.java @@ -0,0 +1,50 @@ +package com.example.searchinkeycloakwithspringboot.web; + +import com.example.searchinkeycloakwithspringboot.exception.UserNotFoundInKeycloakException; +import com.example.searchinkeycloakwithspringboot.service.KeycloakService; +import lombok.AllArgsConstructor; +import org.keycloak.representations.idm.UserRepresentation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Set; + +@RestController +@RequestMapping("/search") +@AllArgsConstructor +public class SearchController { + + + + + private KeycloakService keycloakService ; + + + + @GetMapping("/id/{id}") + public ResponseEntity searchById(@PathVariable String id) { + return ResponseEntity.ok().body(keycloakService.searchById(id)); + } + @GetMapping("/email/{email}") + public ResponseEntity searchByEmail(@PathVariable String email ) throws UserNotFoundInKeycloakException { + return ResponseEntity.ok().body(keycloakService.searchByEmail(email)); + } + @GetMapping("/username/{username}") + public ResponseEntity searchByUsername(@PathVariable String username) throws UserNotFoundInKeycloakException { + return ResponseEntity.ok().body(keycloakService.searchByUsername(username)); + } + @GetMapping("/phone/{phone}") + public ResponseEntity searchByPhoneNumber(@PathVariable String phone) throws UserNotFoundInKeycloakException { + return ResponseEntity.ok().body(keycloakService.searchByPhone(phone)); + } + @GetMapping("/role/{role}") + public ResponseEntity> searchByRole(@PathVariable String role) { + return ResponseEntity.ok().body(keycloakService.searchByRole(role)); + } + +} diff --git a/search-in-keycloak-with-spring-boot/src/main/resources/application.properties b/search-in-keycloak-with-spring-boot/src/main/resources/application.properties new file mode 100644 index 0000000..51ad5eb --- /dev/null +++ b/search-in-keycloak-with-spring-boot/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=9090 diff --git a/search-in-keycloak-with-spring-boot/src/test/java/com/example/searchinkeycloakwithspringboot/SearchInKeycloakWithSpringBootApplicationTests.java b/search-in-keycloak-with-spring-boot/src/test/java/com/example/searchinkeycloakwithspringboot/SearchInKeycloakWithSpringBootApplicationTests.java new file mode 100644 index 0000000..6dacd75 --- /dev/null +++ b/search-in-keycloak-with-spring-boot/src/test/java/com/example/searchinkeycloakwithspringboot/SearchInKeycloakWithSpringBootApplicationTests.java @@ -0,0 +1,13 @@ +package com.example.searchinkeycloakwithspringboot; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SearchInKeycloakWithSpringBootApplicationTests { + + @Test + void contextLoads() { + } + +}