diff --git a/MyINPulse-back/src/main/java/enseirb/myinpulse/utils/keycloak/KeycloakApi.java b/MyINPulse-back/src/main/java/enseirb/myinpulse/utils/keycloak/KeycloakApi.java new file mode 100644 index 0000000..ff6dde2 --- /dev/null +++ b/MyINPulse-back/src/main/java/enseirb/myinpulse/utils/keycloak/KeycloakApi.java @@ -0,0 +1,135 @@ +package enseirb.myinpulse.utils.keycloak; + +import static org.springframework.http.MediaType.APPLICATION_JSON; + +import enseirb.myinpulse.exceptions.UserNotFoundException; +import enseirb.myinpulse.utils.keycloak.datatypes.RoleRepresentation; +import enseirb.myinpulse.utils.keycloak.datatypes.UserRepresentation; + +import org.springframework.web.client.RestClient; + +import javax.management.relation.RoleNotFoundException; + +public class KeycloakApi { + + static final String keycloakUrl; + static final String realmName; + + static { + if (System.getenv("VITE_KEYCLOAK_URL") == null) { + System.exit(-1); + } + keycloakUrl = System.getenv("VITE_KEYCLOAK_URL"); + } + + static { + if (System.getenv("VITE_KEYCLOAK_REALM") == null) { + System.exit(-1); + } + realmName = System.getenv("VITE_KEYCLOAK_REALM"); + } + + /** + * Uses Keycloak API to retrieve a role representation of a role by its name + * + * @param roleName name of the role + * @param bearer authorization header used by the client to authenticate to keycloak + */ + public static RoleRepresentation getRoleRepresentationByName(String roleName, String bearer) + throws RoleNotFoundException { + RoleRepresentation[] response = + RestClient.builder() + .baseUrl(keycloakUrl) + .defaultHeader("Authorization", bearer) + .build() + .get() + .uri("/admin/realms/{realmName}/roles/{roleName}", realmName, roleName) + .retrieve() + .body(RoleRepresentation[].class); + + if (response == null || response.length == 0) { + throw new RoleNotFoundException("Role not found"); + } + return response[0]; + } + + /** + * Use keycloak API to to retreive a userID via his name or email. + * + * @param username username or mail of the user + * @param bearer bearer of the user, allowing access to database + * @return the userid, as a String + * @throws UserNotFoundException + */ + public static String getUserIdByName(String username, String bearer) + throws UserNotFoundException { + UserRepresentation[] response = + RestClient.builder() + .baseUrl(keycloakUrl) + .defaultHeader("Authorization", bearer) + .build() + .get() + .uri( + "/admin/realms/{realmName}/users?username={username}", + realmName, + username) + .retrieve() + .body(UserRepresentation[].class); + + if (response == null || response.length == 0) { + throw new UserNotFoundException("User not found"); + } + return response[0].id; + } + + /** + * TODO: check for error + * + *

Set a keycloak role to a keycloak user. + * + *

Usual roles should be `MyINPulse-admin` and `MyINPulse-entrepreneur` + * + * @param username + * @param roleName + * @param bearer + * @throws RoleNotFoundException + * @throws UserNotFoundException + */ + public static void setRoleToUser(String username, String roleName, String bearer) + throws RoleNotFoundException, UserNotFoundException { + RoleRepresentation roleRepresentation = getRoleRepresentationByName(roleName, bearer); + String userId = getUserIdByName(username, bearer); + + RestClient.builder() + .baseUrl(keycloakUrl) + .defaultHeader("Authorization", bearer) + .build() + .post() + .uri( + "/admin/realms/${realmName}/users/${userId}/role-mappings/realm", + realmName, + userId) + .body(roleRepresentation) + .contentType(APPLICATION_JSON) + .retrieve(); + } + + /** + * Delete a user from Keycloak database. TODO: check the bearer permission. + * + * @param username + * @param bearer + * @throws UserNotFoundException + */ + public static void deleteUser(String username, String bearer) throws UserNotFoundException { + String userId = getUserIdByName(username, bearer); + + RestClient.builder() + .baseUrl(keycloakUrl) + .defaultHeader("Authorization", bearer) + .build() + .delete() + .uri("/admin/realms/${realmName}/users/${userId}", realmName, userId) + .retrieve(); + } +} diff --git a/front/MyINPulse-front/src/views/testComponent.vue b/front/MyINPulse-front/src/views/testComponent.vue index 9ba1d5a..a73d879 100644 --- a/front/MyINPulse-front/src/views/testComponent.vue +++ b/front/MyINPulse-front/src/views/testComponent.vue @@ -1,6 +1,9 @@