idm-service/src/main/java/org/gcube/service/idm/controller/KCUserController.java

255 lines
8.4 KiB
Java

package org.gcube.service.idm.controller;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.service.idm.keycloack.KeycloackApiClient;
import org.gcube.service.idm.keycloack.KkClientFactory;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RoleResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.NotFoundException;
public class KCUserController {
public static String MEMBER_ROLE_NAME = "Member";
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(KCUserController.class);
public enum REPR {
full, compact, username, email, id, username_email, username_user, fullname, none
}
public static UsersResource realmUsersResource() {
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
UsersResource users = realm.users();
return users;
}
public static List<UserRepresentation> realmUser(
Integer firstResult,
Integer maxResults) {
UsersResource uresource = KCUserController.realmUsersResource();
List<UserRepresentation> users = uresource.list(firstResult, maxResults);
return users;
}
public static List<UserRepresentation> contextUsers(
Integer firstResult,
Integer maxResults) {
ClientResource client = KkClientFactory.getSingleton().getKKClient();
RolesResource roles_resource = client.roles();
RoleResource r = roles_resource.get(MEMBER_ROLE_NAME);
List<UserRepresentation> users = r.getUserMembers(firstResult, maxResults);
return users;
}
public static Object formatRepr(UserRepresentation user, REPR format) {
if (user == null || format.equals(REPR.none)) {
return null;
}
if (format.equals(REPR.username)) {
return user.getUsername();
}
if (format.equals(REPR.email)
|| format.equals(REPR.username_email)) {
return user.getEmail();
}
if (format.equals(REPR.id)) {
return user.getId();
}
if (format.equals(REPR.fullname)) {
return user.getFirstName() + " " + user.getLastName();
}
return user;
}
public static Object formatList(List<UserRepresentation> users, REPR format) {
if (format.equals(REPR.username_email)
|| format.equals(REPR.username_user)
) {
HashMap<String, Object> usernamesAndFullnames = new HashMap<String, Object>();
users.forEach(user -> usernamesAndFullnames.put(user.getUsername(), formatRepr(user, format)));
return usernamesAndFullnames;
}
// https://stackoverflow.com/questions/3907394/java-is-there-a-map-function/3907448#3907448
return users.stream().map(x -> formatRepr(x, format)).filter(Objects::nonNull).collect(Collectors.toList());
}
/**
* Search for users based on the given filters.
*
* @param username a value contained in username
* @param firstName a value contained in first name
* @param lastName a value contained in last name
* @param email a value contained in email
* @param emailVerified whether the email has been verified
* @param idpAlias the alias of the Identity Provider
* @param idpUserId the userId at the Identity Provider
* @param firstResult the position of the first result to retrieve
* @param maxResults the maximum number of results to retrieve
* @param enabled only return enabled or disabled users
* @param briefRepresentation Only return basic information (only guaranteed to
* return id, username, created, first
* and last name, email, enabled state, email
* verification state, federation link, and access.
* Note that it means that namely user attributes,
* required actions, and not before are not
* returned.)
* @return a list of {@link UserRepresentation}
*/
public static List<UserRepresentation> search(String username,
String firstName,
String lastName,
String email,
Boolean emailVerified,
String idpAlias,
String idpUserId,
Integer firstResult,
Integer maxResults,
Boolean enabled,
Boolean briefRepresentation) {
logger.info("Searching users with params");
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
List<UserRepresentation> users = realm.users().search(username, firstName, lastName, email, emailVerified,
idpAlias, idpUserId, firstResult, maxResults, enabled, briefRepresentation);
return users;
}
public static UserRepresentation getUserByEmail(String email) {
logger.info("Searching user by email: {}", email);
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
UserRepresentation user = realm.users()
.searchByEmail(email, true).stream().findFirst().orElse(null);
if (user == null) {
throw new NotFoundException("cannot retrieve user for email" + email);
}
return user;
}
public static UserRepresentation getUserById(String username) {
logger.info("Searching user by username: {}", username);
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
UserRepresentation user = realm.users().search(username).stream().findFirst().orElse(null);
if (user == null) {
throw new NotFoundException("cannot retrieve user " + username);
}
return user;
}
public static UserRepresentation getUserByUsername(String username) {
logger.info("Searching user by username: {}", username);
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
UserRepresentation user = realm.users()
.search(username, true).stream().findFirst().orElse(null);
if (user == null) {
throw new NotFoundException("cannot retrieve user " + username);
}
return user;
}
public static UserResource getUserResourceByUsername(String username) {
logger.info("Searching user by username: {}", username);
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
UserRepresentation user = realm.users()
.search(username, true).stream().findFirst().orElse(null);
if (user == null) {
throw new NotFoundException("cannot retrieve user " + username);
}
UserResource userRes = realm.users().get(user.getId());
if (userRes == null) {
throw new NotFoundException("cannot retrieve user " + username);
}
return userRes;
}
public static List<UserRepresentation> searchUsersByRole(String roleName, Integer firstResult, Integer maxResults) {
logger.info("Searching users by role: {}", roleName);
ClientResource client = KkClientFactory.getSingleton().getKKClient();
List<UserRepresentation> users = client.roles().get(roleName)
.getUserMembers(firstResult, maxResults);
return users;
}
public static List<ClientRepresentation> clients() {
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
String ctx = SecretManagerProvider.get().getContext();
KeycloackApiClient keycloackApiClient = KkClientFactory.getSingleton()
.createtKeycloakInstance(ctx);
List<ClientRepresentation> clients = realm.clients().findByClientId(keycloackApiClient.clientIdContext);
return clients;
}
public static Object getUserParameter(String username, String parameter) {
UserRepresentation user = getUserByUsername(username);
if (user == null) {
throw new NotFoundException("cannot retrieve user " + username);
}
if (parameter == null)
return user;
else if (parameter.equals("email"))
return user.getEmail();
else if (parameter.equals("roles_realm"))
return user.getRealmRoles();
else if (parameter.equals("roles_clients"))
return user.getClientRoles();
else if (parameter.equals("groups"))
return user.getGroups();
else if (parameter.equals("id"))
return user.getId();
else if (parameter.equals("username"))
return user.getUsername();
else if (parameter.equals("name"))
return user.getFirstName() + " " + user.getLastName();
else if (parameter.equals("attributes"))
return user.getAttributes();
else
throw new BadRequestException("unknow parameter " + parameter);
}
}