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 @@
@@ -55,6 +58,14 @@ import { callApi } from "@/services/api.ts";
res
+
+
+
+
+
+
+
+