Compare commits

...

6 Commits

23 changed files with 1337 additions and 547 deletions

View File

@ -1,6 +1,6 @@
[node]
mode = offline
hostname = myhostname.isti.cnr.it
mode = online
hostname = idm.isti.cnr.it
protocol= http
port = 8080
infrastructure = gcube
@ -20,7 +20,7 @@ factory = org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFac
factory.endpoint = https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token
credentials.class = org.gcube.smartgears.security.SimpleCredentials
credentials.clientID =
credentials.clientID = idm-service-hosting-node-client
credentials.secret =

View File

@ -1,22 +1,21 @@
<!-- // da implementare rispetto al contesto -->
/2/users/get-profile // profilo utente corrente
/2/users/get-email // utente corrente
/2/users/get-fullname // utente corrente
* /2/users/get-profile // profilo utente corrente
* /2/users/get-email // utente corrente
* /2/users/get-fullname // utente corrente
/2/users/get-all-usernames
/2/users/get-all-fullnames-and-usernames
/2/users/get-usernames-by-role
/2/users/user-exists // https://howtodoinjava.com/devops/search-keycloak-users/
* /2/users/get-all-usernames
* /2/users/get-all-fullnames-and-usernames
* /2/users/get-usernames-by-role
* /2/users/user-exists // https://howtodoinjava.com/devops/search-keycloak-users/
// attenzione al risultato. vedere in seguito
/2/users/get-oauth-profile
* // attenzione al risultato. vedere in seguito
* /2/users/get-oauth-profile
// eventualemente in seguito. da approfondire
/2/users/get-custom-attribute
/2/users/get-usernames-by-global-role
* /2/users/get-custom-attribute
* /2/users/get-usernames-by-global-role
/2/people/profile
* /2/people/profile
# REF:
https://www.keycloak.org/docs-api/22.0.1/rest-api/index.html#_users

View File

@ -214,13 +214,6 @@ solution: bind version, or exclude them in usermanagement-core
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency> -->
<!-- END Required for Enunciate plugin -->
<!-- Test libraries -->

View File

@ -3,6 +3,8 @@ package org.gcube.service.idm.controller;
import java.util.List;
import java.util.Map;
import javax.ws.rs.ForbiddenException;
import org.gcube.common.keycloak.model.ModelUtils;
import org.gcube.common.security.Owner;
import org.gcube.common.security.providers.SecretManagerProvider;
@ -10,10 +12,17 @@ import org.gcube.common.security.secrets.Secret;
public class AuthController {
public final static String IDM_SERVICE_READ = "idm-service-read";
// can admin current context
public final static String IDM_SERVICE_ADMIN = "idm-service-admin";
public final static List<String> ACCESS_READ_ROLES = List.of(IDM_SERVICE_READ, IDM_SERVICE_ADMIN);
public final static List<String> ACCESS_ADMIN_ROLES = List.of(IDM_SERVICE_READ);
// can admin all realm, not only current context
public final static String IDM_SERVICE_REALM = "idm-service-realm";
public final static List<String> ACCESS_READ_ROLES = List.of(IDM_SERVICE_READ, IDM_SERVICE_ADMIN,
IDM_SERVICE_REALM);
public final static List<String> ACCESS_ADMIN_ROLES = List.of(IDM_SERVICE_ADMIN, IDM_SERVICE_REALM);
public final static List<String> ACCESS_ADMIN_REALM_ROLES = List.of(IDM_SERVICE_REALM);
public static String getAccessToken() {
Map<String, String> authorizations = SecretManagerProvider.get().getHTTPAuthorizationHeaders();
@ -76,4 +85,16 @@ public class AuthController {
return !owner.isApplication() && owner.getId().equals(username);
}
public static void checkIsRealmAdmin(String message) throws ForbiddenException {
if (!checkAnyRole(ACCESS_ADMIN_ROLES)) {
throw new ForbiddenException(message);
}
}
public static void checkIsContextmAdmin(String message) throws ForbiddenException {
if (!checkAnyRole(ACCESS_ADMIN_REALM_ROLES)) {
throw new ForbiddenException(message);
}
}
}

View File

@ -3,7 +3,7 @@ package org.gcube.service.idm.controller;
import java.util.HashMap;
import java.util.Map;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
@ -16,16 +16,16 @@ public class JWTController {
throws JsonMappingException, JsonProcessingException {
DecodedJWT decodedJWT = JWT.decode(token);
String headerJson = ContextSerializator.decodeBase64String(decodedJWT.getHeader());
String payloadJson = ContextSerializator.decodeBase64String(decodedJWT.getPayload());
String headerJson = IdmObjectSerializator.decodeBase64String(decodedJWT.getHeader());
String payloadJson = IdmObjectSerializator.decodeBase64String(decodedJWT.getPayload());
// String signatureJson =
// ContextSerializator.decodeBase64String(decodedJWT.getSignature());
Map<String, Object> decoded = new HashMap<String, Object>();
decoded.put("jwt_token", token);
decoded.put("token", decodedJWT.getToken());
decoded.put("header", ContextSerializator.jsonStringToHasmap(headerJson));
decoded.put("payload", ContextSerializator.jsonStringToHasmap(payloadJson));
decoded.put("header", IdmObjectSerializator.jsonStringToHasmap(headerJson));
decoded.put("payload", IdmObjectSerializator.jsonStringToHasmap(payloadJson));
// decoded.put("signature",
// ContextSerializator.jsonStringToHasmap(signatureJson));
decoded.put("decodedJWT", decodedJWT);

View File

@ -0,0 +1,142 @@
package org.gcube.service.idm.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.gcube.service.idm.keycloack.KkClientFactory;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.GroupResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RoleResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.NotFoundException;
public class KCClientsController {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(KCClientsController.class);
public enum REPR {
full, compact, name, id, client_id, none
}
public static Object formatRepr(ClientRepresentation client, REPR format) {
if (client == null || format.equals(REPR.none)) {
return null;
}
if (format.equals(REPR.name)) {
return client.getName();
}
if (format.equals(REPR.id)) {
return client.getId();
}
if (format.equals(REPR.client_id)) {
return client.getClientId();
}
if (format.equals(REPR.compact)) {
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("id", client.getId());
result.put("clientId", client.getClientId());
result.put("name", client.getName());
result.put("description", client.getDescription());
return result;
}
return client;
}
public static List<Object> formatList(List<ClientRepresentation> clients, REPR format) {
return clients.stream().map(x -> formatRepr(x, format)).filter(Objects::nonNull).collect(Collectors.toList());
}
public static List<RoleRepresentation> getRolesCurrent() {
logger.info("Searching users for context");
ClientResource client = KkClientFactory.getSingleton().getKKClient();
RolesResource roles_resource = client.roles();
List<RoleRepresentation> roles = roles_resource.list();
return roles;
}
public static RoleRepresentation getRoleByNameCurrent(String name) {
return getRoleByName(null, name);
}
public static RoleRepresentation getRoleByName(String clientId, String name) {
logger.info("Searching users for context");
ClientResource clientResource = KkClientFactory.getSingleton().getKKClientById(clientId);
RolesResource roles_resource = clientResource.roles();
RoleResource role = roles_resource.get(name);
if (role == null) {
throw new NotFoundException("cannot retrieve role " + name);
}
return role.toRepresentation();
}
public static List<UserRepresentation> getContextUsersByRoleCurrent(String role_name) {
return getContextUsersByRoleCurrent(role_name, null, null);
}
public static List<UserRepresentation> getContextUsersByRoleCurrent(String role_name, Integer firstResult,
Integer maxResults) {
return getContextUsersByRole(null, role_name, firstResult, maxResults);
}
public static List<UserRepresentation> getContextUsersByRole(String clientId, String role_name,
Integer firstResult,
Integer maxResults) {
ClientResource clientResource = KkClientFactory.getSingleton().getKKClientById(clientId);
RolesResource roles_resource = clientResource.roles();
RoleResource r = roles_resource.get(role_name);
List<UserRepresentation> users = r.getUserMembers(firstResult, maxResults);
return users;
}
/**
* returns the list of users of the client
* users list is a subset of members list, it's obtained from the group named as
* the context
*
* @param clientId null for current context
*/
public static List<UserRepresentation> getMemberGroupUsersCurrent() {
return getMemberGroupUsers(null, null, null);
}
/**
* returns the list of users of the client
* users list is a subset of members list, it's obtained from the group named as
* the context
*
* @param clientId null for current context
* @param firstResult
* @param maxResults
*/
public static List<UserRepresentation> getMemberGroupUsers(String clientId, Integer firstResult,
Integer maxResults) {
RealmResource realmResource = KkClientFactory.getSingleton().getKKRealm();
ClientResource clientResource = KkClientFactory.getSingleton().getKKClientById(clientId);
ClientRepresentation client = clientResource.toRepresentation();
GroupRepresentation g_repr = realmResource.getGroupByPath(client.getName());
GroupResource group = realmResource.groups().group(g_repr.getId());
List<UserRepresentation> user_members = group.members(firstResult, maxResults);
return user_members;
}
}

View File

@ -0,0 +1,49 @@
package org.gcube.service.idm.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.keycloak.representations.idm.GroupRepresentation;
import org.slf4j.LoggerFactory;
public class KCGroupsController {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(KCGroupsController.class);
public enum REPR {
full, compact, name, id, path, none
}
public static Object formatRepr(GroupRepresentation group, REPR format) {
if (group == null || format.equals(REPR.none)) {
return null;
}
if (format.equals(REPR.name)) {
return group.getName();
}
if (group.equals(REPR.id)) {
return group.getId();
}
if (group.equals(REPR.path)) {
return group.getPath();
}
if (format.equals(REPR.compact)) {
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("id", group.getId());
result.put("name", group.getName());
result.put("path", group.getPath());
return result;
}
return group;
}
public static List<Object> formatList(List<GroupRepresentation> groups, REPR format) {
return groups.stream().map(x -> formatRepr(x, format)).filter(Objects::nonNull).collect(Collectors.toList());
}
}

View File

@ -1,13 +1,15 @@
package org.gcube.service.idm.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.gcube.service.idm.keycloack.KkClientFactory;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RoleResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.NotFoundException;
@ -15,42 +17,51 @@ import jakarta.ws.rs.NotFoundException;
public class KCRolesController {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(KCRolesController.class);
public enum REPRESENTATION {
full, compact, name, id
public enum REPR {
full, compact, name, id, none
}
public static Object formatListRoles(List<RoleRepresentation> roles, KCRolesController.REPRESENTATION format) {
public static Object formatRepr(RoleRepresentation role, REPR format) {
if (role == null || format.equals(REPR.none)) {
return null;
}
if (format.equals(REPR.name)) {
return role.getName();
}
if (format.equals(KCRolesController.REPRESENTATION.id)) {
List<String> ids = new ArrayList<String>();
if (roles != null) {
for (RoleRepresentation role : roles) {
ids.add(role.getId());
}
}
return ids;
} else if (format.equals(KCRolesController.REPRESENTATION.name)) {
List<String> names = new ArrayList<String>();
if (roles != null) {
for (RoleRepresentation role : roles) {
names.add(role.getName());
}
}
return names;
} else
return roles;
if (format.equals(REPR.id)) {
return role.getId();
}
return role;
}
public static List<RoleRepresentation> getRoles() {
public static List<Object> formatList(List<RoleRepresentation> roles, REPR format) {
return roles.stream().map(x -> formatRepr(x, format)).filter(Objects::nonNull).collect(Collectors.toList());
}
public static List<Object> getFormattedRoles(REPR format) {
Boolean briefRepresentation = !format.equals(REPR.full);
List<RoleRepresentation> roles = getRolesForContext(briefRepresentation);
return formatList(roles, format);
}
public static List<RoleRepresentation> getRolesForContext() {
return getRolesForContext(true);
}
public static List<RoleRepresentation> getRolesForContext(Boolean compact) {
logger.info("Searching users for context");
ClientResource client = KkClientFactory.getSingleton().getKKClient();
RolesResource roles_resource = client.roles();
List<RoleRepresentation> roles = roles_resource.list();
List<RoleRepresentation> roles = roles_resource.list(compact);
return roles;
}
public static RoleRepresentation getRoleByName(String name) {
public static RoleRepresentation getRoleByNameCurrent(String name) {
logger.info("Searching users for context");
ClientResource client = KkClientFactory.getSingleton().getKKClient();
RolesResource roles_resource = client.roles();
@ -62,4 +73,20 @@ public class KCRolesController {
return role.toRepresentation();
}
public static List<UserRepresentation> getUsersByRoleForContext(String role_name) {
return getUsersByRoleForContext(role_name, null, null);
}
public static List<UserRepresentation> getUsersByRoleForContext(String role_name, Integer firstResult,
Integer maxResults) {
ClientResource client = KkClientFactory.getSingleton().getKKClient();
RolesResource roles_resource = client.roles();
RoleResource role_resource = roles_resource.get(role_name);
List<UserRepresentation> users = role_resource.getUserMembers(firstResult, maxResults);
return users;
}
}

View File

@ -1,15 +1,19 @@
package org.gcube.service.idm.controller;
import java.util.ArrayList;
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;
@ -20,60 +24,77 @@ 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 REPRESENTATION {
full, compact, username, email, id, email_username, fullname
public enum REPR {
full, compact, username, email, id, username_email, username_user, fullname, none
}
public static UsersResource users() {
public static UsersResource realmUsersResource() {
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
UsersResource users = realm.users();
return users;
}
public static Object formatListUsers(List<UserRepresentation> users, KCUserController.REPRESENTATION format) {
public static List<UserRepresentation> realmUser(
Integer firstResult,
Integer maxResults) {
UsersResource uresource = KCUserController.realmUsersResource();
List<UserRepresentation> users = uresource.list(firstResult, maxResults);
return users;
}
if (format.equals(KCUserController.REPRESENTATION.username)) {
List<String> usernames = new ArrayList<String>();
if (users != null) {
for (UserRepresentation user : users) {
usernames.add(user.getUsername());
}
}
return usernames;
public static List<UserRepresentation> contextUsers(
Integer firstResult,
Integer maxResults) {
} else if (format.equals(KCUserController.REPRESENTATION.email)) {
List<String> emails = new ArrayList<String>();
if (users != null) {
for (UserRepresentation user : users) {
emails.add(user.getEmail());
}
}
return emails;
} else if (format.equals(KCUserController.REPRESENTATION.id)) {
List<String> ids = new ArrayList<String>();
if (users != null) {
for (UserRepresentation user : users) {
ids.add(user.getId());
}
}
return ids;
} else if (format.equals(KCUserController.REPRESENTATION.email_username)) {
Map<String, String> usernamesAndFullnames = new HashMap<String, String>();
users.forEach(user -> usernamesAndFullnames.put(user.getUsername(), user.getEmail()));
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;
} else if (format.equals(KCUserController.REPRESENTATION.fullname)) {
List<String> fullnames = new ArrayList<String>();
if (users != null) {
for (UserRepresentation user : users) {
fullnames.add(user.getFirstName() + " " + user.getLastName());
}
}
return fullnames;
} else
return users;
}
// 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());
}
/**
@ -181,16 +202,6 @@ public class KCUserController {
return users;
}
public static List<UserRepresentation> users(
Integer firstResult,
Integer maxResults) {
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
List<UserRepresentation> users = realm.users()
.list(firstResult, maxResults);
return users;
}
public static List<ClientRepresentation> clients() {
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();

View File

@ -6,9 +6,6 @@ import java.util.List;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.service.idm.is.InfrastrctureServiceClient;
import org.gcube.service.idm.is.IsServerConfig;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.gcube.smartgears.security.SimpleCredentials;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.admin.client.resource.ClientResource;
@ -54,12 +51,13 @@ public class KkClientFactory {
if (this.config == null) {
this.config = fetchIsConfig();
}
logger.info("KeycloakAPICredentials object built {} - {}", config.getServerUrl(), config.getName());
} catch (
Exception e) {
logger.error("error obtaining IAM configuration from IS {} ", e);
}
logger.info("KeycloakAPICredentials object built {} - {}", config.getServerUrl(), config.getName());
}
// public IsServerConfig configFromINI() throws NotFoundException,
@ -142,6 +140,30 @@ public class KkClientFactory {
return realm.clients().get(id);
}
/**
* select the ClientResource by name, or current client if clientId parameter is null;
*
* @param clientId
* @return
*/
public ClientResource getKKClientById(String clientId) {
if (clientId == null)
return KkClientFactory.getSingleton().getKKClient();
RealmResource realmResource = getKKRealm();
List<ClientRepresentation> clients = realmResource.clients().findByClientId(clientId);
if (clients.size() == 0) {
throw new NotFoundException();
}
String id = clients.get(0).getId();
return realmResource.clients().get(id);
}
// TODO: REMOVE
// static IsServerConfig getTestConfig() {
// String serverUrl = "https://accounts.dev.d4science.org/auth";

View File

@ -1,75 +1,400 @@
package org.gcube.service.idm.rest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import jakarta.ws.rs.NotFoundException;
import java.util.Set;
import org.gcube.service.idm.IdMManager;
import org.gcube.service.idm.controller.AdminKeycloakController;
import org.gcube.service.idm.controller.AuthController;
import org.gcube.service.idm.controller.KCClientsController;
import org.gcube.service.idm.controller.KCGroupsController;
import org.gcube.service.idm.controller.KCRolesController;
import org.gcube.service.idm.controller.KCUserController;
import org.gcube.service.idm.keycloack.KkClientFactory;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import org.gcube.service.rest.ErrorMessages;
import org.gcube.service.rest.ResponseBean;
import org.gcube.service.rest.ResponseBeanMap;
import org.gcube.smartgears.annotations.ManagedBy;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.GroupResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RoleResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Response;
@ManagedBy(IdMManager.class)
@RequestHeaders({
@RequestHeader(name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader(name = "Content-Type", description = "application/json")
})
@Path("clients")
public class ClientsAPI {
/**
* returns the list of members of the client with the given role
*
* default client is the current client, optional clientId to show a different
* one
*
* default showed role is "Member"
*
* output format can be customized using format_users
*
* @param client_id optional clientId (aka encoded context). if absent,
* uses
* current context
*
* @param format_users response format for users. use "none" for skip
*
* @param role role to inspect, default Member.
*
* @param firstResult pagination offset
* @param maxResults maximum results size
*/
@GET
@Path("members")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response clientMembers(
@QueryParam("first") @DefaultValue("0") int firstResult,
@QueryParam("max") @DefaultValue("100") int maxResults,
@QueryParam("format_users") @DefaultValue("username") KCUserController.REPR format_users,
@QueryParam("role") @DefaultValue("Member") String role_name,
@QueryParam("client_id") String clientId) {
ResponseBean responseBean = new ResponseBean();
if (clientId != null) {
AuthController.checkIsRealmAdmin(ErrorMessages.RESERVED_PARAMETER + "client_id");
}
// RealmResource realmResource = KkClientFactory.getSingleton().getKKRealm();
// ClientResource clientResource = null;
// // select the client by name, or current client if client_name parameter is
// // null;
// if (clientId == null) {
// clientResource = KkClientFactory.getSingleton().getKKClient();
// } else {
// List<ClientRepresentation> clients =
// realmResource.clients().findByClientId(clientId);
// if (clients.size() == 0) {
// throw new NotFoundException();
// }
// String id = clients.get(0).getId();
// clientResource = realmResource.clients().get(id);
// }
// RolesResource roles_resource = clientResource.roles();
// RoleResource role_resource = roles_resource.get(role_name);
// List<UserRepresentation> user_members =
// role_resource.getUserMembers(firstResult, maxResults);
List<UserRepresentation> user_members = KCClientsController.getContextUsersByRole(clientId, role_name,
firstResult, maxResults);
Object result = KCUserController.formatList(user_members, format_users);
responseBean.setResult(result);
try {
responseBean.setSuccess(true);
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (
JsonProcessingException e) {
e.printStackTrace();
throw new InternalServerErrorException(e);
}
}
/**
* returns the list of users of the client
* users list is a subset of members list, it's obtained from the group named as
* the context
*
* default client is the current client, optional clientId to show a different
* one
*
* output format can be customized using format_users
*
* @param client_id optional clientId (aka encoded context). if absent,
* uses
* current context
*
* @param format_users response format for users. use "none" for skip
*
* @param role list of roles to inspect, default Member. can use
* multiple times. use '__all__' to get all roles in the
* client
* @param firstResult pagination offset
* @param maxResults maximum results size
*/
@GET
@Path("users")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response clientUsers(
@QueryParam("first") @DefaultValue("0") int firstResult,
@QueryParam("max") @DefaultValue("100") int maxResults,
@QueryParam("format_users") @DefaultValue("username") KCUserController.REPR format_users,
@QueryParam("client_id") String clientId) {
ResponseBean responseBean = new ResponseBean();
if (clientId != null) {
AuthController.checkIsRealmAdmin(ErrorMessages.RESERVED_PARAMETER + "client_id");
}
List<UserRepresentation> user_members = KCClientsController.getMemberGroupUsers(clientId, firstResult,
maxResults);
Object result = KCUserController.formatList(user_members, format_users);
responseBean.setResult(result);
try {
responseBean.setSuccess(true);
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (
JsonProcessingException e) {
e.printStackTrace();
throw new InternalServerErrorException(e);
}
}
/**
* returns an inspection of the client, showing roles and related members
* default client is the current client, optional clientId to show a different
* one
*
* output format can be customized using format_client, format_users,
* format_roles, format_groups
*
* default showed role is "Member", use role="__all__" to show all roles
*
* @param client_id optional clientId (aka encoded context). if absent,
* uses
* current context
*
* @param format_users response format for users. use "none" for skip
* @param format_roles response format for users. use "none" for skip
* @param format_client response format for client. use "none" for skip
* @param format_groups response format for group. use "none" for skip
*
* @param role list of roles to inspect, default Member. can use
* multiple times. use '__all__' to get all roles in the
* client
*/
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ClientsAPI.class);
@GET
@Path("/{name}")
@Path("info")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response clientByName(
@PathParam("name") String client_name) {
public Response client(
@QueryParam("format_client") @DefaultValue("compact") KCClientsController.REPR format_client,
@QueryParam("format_users") @DefaultValue("username") KCUserController.REPR format_users,
@QueryParam("format_roles") @DefaultValue("compact") KCRolesController.REPR format_roles,
@QueryParam("format_groups") @DefaultValue("name") KCGroupsController.REPR format_group,
@QueryParam("role") @DefaultValue("Member") final List<String> roles,
@QueryParam("client_id") String clientId) {
ResponseBeanMap responseBean = new ResponseBeanMap();
try {
if (clientId != null) {
AuthController.checkIsRealmAdmin(ErrorMessages.RESERVED_PARAMETER + "client_id");
}
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
List<ClientRepresentation> clients = realm.clients().findByClientId(client_name);
// String role_name = "Member";
boolean show_groups = !format_group.equals(KCGroupsController.REPR.none);
boolean show_client = !format_client.equals(KCClientsController.REPR.none);
boolean show_users = !format_users.equals(KCUserController.REPR.none);
boolean show_roles = !format_roles.equals(KCRolesController.REPR.none);
RealmResource realmResource = KkClientFactory.getSingleton().getKKRealm();
ClientResource clientResource = null;
ClientRepresentation client = null;
// select the client by name, or current client if client_name parameter is
// null;
if (clientId == null) {
clientResource = KkClientFactory.getSingleton().getKKClient();
client = clientResource.toRepresentation();
} else {
List<ClientRepresentation> clients = realmResource.clients().findByClientId(clientId);
if (clients.size() == 0) {
throw new NotFoundException();
}
String id = clients.get(0).getId();
ClientResource clientResource = realm.clients().get(id);
ClientRepresentation client = clientResource.toRepresentation();
clientResource = realmResource.clients().get(id);
client = clientResource.toRepresentation();
}
if (show_client)
responseBean.putResult("client", KCClientsController.formatRepr(client,
format_client));
if (format_client.equals(KCClientsController.REPR.full)) {
UserRepresentation service_account_user = clientResource.getServiceAccountUser();
responseBean.putResult("client", client);
responseBean.putResult("service_account_user", service_account_user);
responseBean.setSuccess(true);
responseBean.putResult("service_account_user",
KCUserController.formatRepr(service_account_user, format_users));
}
ObjectMapper objectMapper = ContextSerializator.getSerializer();
HashMap<String, Object> roles_dict = new HashMap<String, Object>();
responseBean.putResult("roles", roles_dict);
RolesResource roles_resource = clientResource.roles();
List<RoleRepresentation> roles_list = null;
if (roles == null || roles.isEmpty() || roles.contains("__all__")) {
roles_list = roles_resource.list();
} else {
roles_list = new ArrayList<RoleRepresentation>();
for (String role_name : roles) {
try {
RoleResource role_resource = roles_resource.get(role_name);
RoleRepresentation role_repr = role_resource.toRepresentation();
roles_list.add(role_repr);
} catch (Exception e) {
roles_dict.put(role_name, null);
continue;
}
}
}
for (RoleRepresentation role_repr : roles_list) {
String role_name = role_repr.getName();
RoleResource role_resource = roles_resource.get(role_name);
HashMap<String, Object> role_dict = new HashMap<String, Object>();
roles_dict.put(role_name, role_dict);
if (show_roles) {
role_dict.put("role", KCRolesController.formatRepr(role_repr, format_roles));
}
if (show_users) {
List<UserRepresentation> user_members = role_resource.getUserMembers();
role_dict.put("members",
KCUserController.formatList(user_members, format_users));
}
if (show_groups) {
HashMap<String, HashMap<String, Object>> groups_hash = new HashMap<String, HashMap<String, Object>>();
role_dict.put("groups", groups_hash);
Set<GroupRepresentation> groups_members = clientResource.roles().get(role_name).getRoleGroupMembers();
for (GroupRepresentation g_repr : groups_members) {
HashMap<String, Object> group_dict = new HashMap<String, Object>();
groups_hash.put(g_repr.getPath(), group_dict);
group_dict.put("group", KCGroupsController.formatRepr(g_repr, format_group));
if (show_users) {
GroupResource g = realmResource.groups().group(g_repr.getId());
List<UserRepresentation> members = g.members();
group_dict.put("members",
KCUserController.formatList(members, format_users));
}
}
}
}
try {
responseBean.setSuccess(true);
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
} catch (
JsonProcessingException e) {
e.printStackTrace();
throw new InternalServerErrorException(e);
}
}
// cannot pass the client name in the path. %2f blocked by tomcat security
// @GET
// @Path("/{name}")
// @Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
// public Response clientByName(
// @PathParam("name") String client_name) {
// ResponseBeanMap responseBean = new ResponseBeanMap();
// try {
// RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
// List<ClientRepresentation> clients =
// realm.clients().findByClientId(client_name);
// if (clients.size() == 0) {
// throw new NotFoundException();
// }
// String id = clients.get(0).getId();
// ClientResource clientResource = realm.clients().get(id);
// ClientRepresentation client = clientResource.toRepresentation();
// UserRepresentation service_account_user =
// clientResource.getServiceAccountUser();
// responseBean.putResult("client", client);
// responseBean.putResult("service_account_user", service_account_user);
// Set<GroupRepresentation> members =
// clientResource.roles().get("Member").getRoleGroupMembers();
// responseBean.putResult("members", members);
// responseBean.setSuccess(true);
// ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
// String jsonData = objectMapper.writeValueAsString(responseBean);
// return Response.ok(jsonData).build();
// } catch (JsonProcessingException e) {
// e.printStackTrace();
// throw new InternalServerErrorException(e);
// }
// }
public class ClientFromTemplateParams {
String client_name;
String client_id;
@ -77,7 +402,7 @@ public class ClientsAPI {
}
@POST
@Path("/fromTemplate/{name}")
@Path("fromTemplate/{name}")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response createClientFromTemplate(
@PathParam("name") String template_name,
@ -106,7 +431,7 @@ public class ClientsAPI {
responseBean.putResult("service_account_user", template_account_user);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
@ -134,7 +459,7 @@ public class ClientsAPI {
responseBean.putResult("created", newClient);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
@ -162,7 +487,7 @@ public class ClientsAPI {
responseBean.putResult("created", newClient);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();

View File

@ -3,18 +3,17 @@ package org.gcube.service.idm.rest;
import java.util.HashMap;
import java.util.Map;
import jakarta.ws.rs.core.MediaType;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.service.idm.controller.AuthController;
import org.gcube.service.idm.controller.JWTController;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import org.gcube.service.rest.ErrorMessages;
import org.gcube.service.rest.ResponseBean;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
@ -23,9 +22,14 @@ import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
@RequestHeaders({
@RequestHeader(name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader(name = "Content-Type", description = "application/json")
})
@Path("jwt")
public class JwtAPI {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(JwtAPI.class);
@ -45,7 +49,7 @@ public class JwtAPI {
ResponseBean responseBean = new ResponseBean();
try {
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
Map<String, Object> decoded = JWTController.decodeJwtToken(token);
responseBean.setResult(decoded);
responseBean.setSuccess(true);
@ -72,7 +76,7 @@ public class JwtAPI {
String token = AuthController.getAccessToken();
try {
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
Map<String, Object> response = new HashMap<String, Object>();

View File

@ -1,24 +1,29 @@
package org.gcube.service.idm.rest;
import java.util.List;
import java.util.Set;
import org.gcube.service.idm.IdMManager;
import org.gcube.service.idm.controller.KCRolesController;
import org.gcube.service.idm.controller.KCUserController;
import org.gcube.service.idm.keycloack.KkClientFactory;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import org.gcube.service.rest.ResponseBean;
import org.gcube.service.rest.ResponseBeanMap;
import org.gcube.service.rest.ResponseBeanPaginated;
import org.gcube.smartgears.annotations.ManagedBy;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RoleResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
@ -31,6 +36,10 @@ import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@ManagedBy(IdMManager.class)
@RequestHeaders({
@RequestHeader(name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader(name = "Content-Type", description = "application/json")
})
@Path("roles")
public class RolesAPI {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(RolesAPI.class);
@ -49,19 +58,19 @@ public class RolesAPI {
public Response search(@QueryParam("search") @DefaultValue("") String search,
@QueryParam("first") @DefaultValue("0") int firstResult,
@QueryParam("max") @DefaultValue("100") int maxResults,
@QueryParam("format") @DefaultValue("name") KCRolesController.REPRESENTATION format) {
@QueryParam("format") @DefaultValue("name") KCRolesController.REPR format) {
ResponseBean responseBean = new ResponseBeanPaginated(firstResult, maxResults);
Boolean briefRepresentation = !KCRolesController.REPRESENTATION.full.equals(format);
Boolean briefRepresentation = !KCRolesController.REPR.full.equals(format);
try {
ClientResource client = KkClientFactory.getSingleton().getKKClient();
List<RoleRepresentation> roles = client.roles().list(search, firstResult, maxResults, briefRepresentation);
responseBean.setResult(KCRolesController.formatListRoles(roles, format));
responseBean.setResult(KCRolesController.formatList(roles, format));
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
@ -86,12 +95,52 @@ public class RolesAPI {
ResponseBean responseBean = new ResponseBean();
try {
RoleRepresentation role = KCRolesController.getRoleByName(role_name);
RoleRepresentation role = KCRolesController.getRoleByNameCurrent(role_name);
responseBean.setResult(role);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new InternalServerErrorException(e);
}
}
/**
* Returns the list of members (users + services_accounts) with the given role
* in the context
*
* @param format users response format
* @param role_name the role
* @param firstResult pagination offset
* @param maxResults maximum results size
*/
@GET
@Path("/{role_name}/members")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response membersForRole(
@PathParam("role_name") String role_name,
@QueryParam("first") @DefaultValue("0") int firstResult,
@QueryParam("max") @DefaultValue("100") int maxResults,
@QueryParam("format") @DefaultValue("username") KCUserController.REPR format) {
ResponseBean responseBean = new ResponseBeanPaginated(firstResult, maxResults);
try {
ClientResource client = KkClientFactory.getSingleton().getKKClient();
RolesResource roles_resource = client.roles();
RoleResource r = roles_resource.get(role_name);
List<UserRepresentation> users = r.getUserMembers(firstResult, maxResults);
responseBean.setResult(KCUserController.formatList(users, format));
responseBean.setSuccess(true);
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
@ -117,21 +166,21 @@ public class RolesAPI {
@PathParam("role_name") String role_name,
@QueryParam("first") @DefaultValue("0") int firstResult,
@QueryParam("max") @DefaultValue("100") int maxResults,
@QueryParam("format") @DefaultValue("username") KCUserController.REPRESENTATION format) {
ResponseBean responseBean = new ResponseBeanPaginated(firstResult, maxResults);
@QueryParam("format") @DefaultValue("username") KCUserController.REPR format) {
ResponseBeanMap responseBean = new ResponseBeanMap();
try {
ClientResource client = KkClientFactory.getSingleton().getKKClient();
RolesResource roles_resource = client.roles();
RoleResource r = roles_resource.get(role_name);
List<UserRepresentation> users = r.getUserMembers(firstResult, maxResults);
// ruoli che danno quel
Set<GroupRepresentation> groups = r.getRoleGroupMembers(firstResult, maxResults);
responseBean.putResult("roleGroupMembers", groups);
responseBean.setResult(KCUserController.formatListUsers(users, format));
responseBean.setSuccess(true);
List<UserRepresentation> users = r.getUserMembers();
responseBean.putResult("users", users);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
@ -140,5 +189,25 @@ public class RolesAPI {
e.printStackTrace();
throw new InternalServerErrorException(e);
}
// throw new InternalServerErrorException("not implemented");
}
/**
* Returns the list of users with role in the context
*
* @param format users response format
* @param role_name the role
* @param firstResult pagination offset
* @param maxResults maximum results size
*/
@GET
@Path("/{role_name}/service_accounts")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response servicesAccountsForRole(
@PathParam("role_name") String role_name,
@QueryParam("first") @DefaultValue("0") int firstResult,
@QueryParam("max") @DefaultValue("100") int maxResults,
@QueryParam("format") @DefaultValue("username") KCUserController.REPR format) {
throw new InternalServerErrorException("not implemented");
}
}

View File

@ -0,0 +1,126 @@
package org.gcube.service.idm.rest;
import org.gcube.common.security.Owner;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.common.security.secrets.Secret;
import org.gcube.service.idm.IdMManager;
import org.gcube.service.idm.controller.LiferayProfileClient;
import org.gcube.service.rest.ErrorMessages;
import org.gcube.service.rest.ResponseBeanMap;
import org.gcube.smartgears.annotations.ManagedBy;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import jakarta.ws.rs.ForbiddenException;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
/**
* @responseExample application/json {
* "success": true,
* "message": null,
* "result": {
* "roles": [
* "Catalogue-Editor",
* "Member"
* ],
* "context": "[CONTEXT]",
* "avatar":
* "https://www.d4science.org:443/image/user_male_portrait?img_id=0&img_id_token=AAABBBCCC",
* "fullname": "FirstName LastName",
* "username": "user.name"
* }
* }
*/
@ManagedBy(IdMManager.class)
@RequestHeaders({
@RequestHeader(name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader(name = "Content-Type", description = "application/json")
})
@Path("2/people")
// @ResourceGroup("Users APIs")
// @ResourceLabel("Greetings APIs")
// @RequestHeaders({
// @RequestHeader(name = "Authorization", description = "Bearer token, see <a
// href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>")
// })
public class SocialPeopleAPI {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SocialPeopleAPI.class);
/**
* @responseExample application/json { "success" : true, "message" : null,
* "result" : { "roles" : [ ], "context" : "***", "avatar" :
* "https://*****3D", "fullname" : "John Smith", "username" :
* "john.smith" } }
* @return the user's profile. The user in this case is the one bound to the
* token
*/
@Produces(MediaType.APPLICATION_JSON)
@GET
@Path("profile")
@StatusCodes({
@ResponseCode(code = 200, condition = "Successful retrieval of user's profile, reported in the 'result' field of the returned object"),
@ResponseCode(code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getProfile() {
ResponseBeanMap responseBean = new ResponseBeanMap();
Status status = Status.OK;
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
String username = owner.getId();
String context = secret.getContext();
if (owner.isApplication()) {
logger.warn("Trying to access users method via a token different than USER is not allowed");
// only users can use "me"
throw new ForbiddenException(ErrorMessages.NOT_USER_TOKEN_CONTEXT_USED);
}
try {
GCubeUser profile = LiferayProfileClient.getUserProfileByUsername(username);
responseBean.putResult("username", username);
responseBean.putResult("avatar", profile.getUserAvatarURL());
responseBean.putResult("fullname", owner.getFirstName() + " " + owner.getLastName());
responseBean.putResult("context", context);
responseBean.putResult("roles", owner.getRoles());
// UserManager userManager =
// UserManagerWSBuilder.getInstance().getUserManager();
// RoleManager roleManager =
// RoleManagerWSBuilder.getInstance().getRoleManager();
// GroupManager groupManager =
// GroupManagerWSBuilder.getInstance().getGroupManager();
// user = userManager.getUserByUsername(username);
// List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(user.getUserId(),
// groupManager.getGroupIdFromInfrastructureScope(scope));
// List<String> rolesNames = new ArrayList<String>();
// for (GCubeRole gCubeRole : roles) {
// rolesNames.add(gCubeRole.getRoleName());
// }
// toReturn.put("roles", rolesNames);
responseBean.setSuccess(true);
} catch (Exception e) {
logger.error("Unable to retrieve user's profile", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
}

View File

@ -12,18 +12,22 @@ import org.gcube.service.idm.IdMManager;
import org.gcube.service.idm.controller.AuthController;
import org.gcube.service.idm.controller.KCUserController;
import org.gcube.service.idm.controller.LiferayProfileClient;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.idm.keycloack.KkClientFactory;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import org.gcube.service.rest.ErrorMessages;
import org.gcube.service.rest.ResponseBean;
import org.gcube.service.rest.ResponseBeanPaginated;
import org.gcube.smartgears.annotations.ManagedBy;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
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.UsersResource;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
@ -47,8 +51,311 @@ import jakarta.ws.rs.core.Response.Status;
// @RequestHeader(name = "Authorization", description = "Bearer token, see <a
// href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>")
// })
public class UsersSocialAPI {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(UsersSocialAPI.class);
public class SocialUsersAPI {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SocialUsersAPI.class);
/**
* Get the profile associated to the token
*
* @responseExample application/json { "success" : true, "message" : null,
* "result" : { "user_id" : 23769487, "username" :
* "john.smith", "email" : "********", "first_name" : "John",
* "middle_name" : "", "last_name" : "Smith", "fullname" :
* "John Smith", "registration_date" : 1475151491415,
* "user_avatar_url" : "https://******D", "male" : true,
* "job_title" : "", "location_industry" : "no",
* "custom_attrs_map" : null, "email_addresses" : [ ],
* "screen_name" : "john.smith", "user_avatar_id" :
* "https://****sY%3D" } }
* @return the user's profile. The user is the one owning the token
*/
@GET
@Path("get-profile")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes({
@ResponseCode(code = 200, condition = "The user's profile is reported in the 'result' field of the returned object"),
@ResponseCode(code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getUserProfile() {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try {
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
String username = owner.getId();
GCubeUser profile = LiferayProfileClient.getUserProfileByUsername(username);
responseBean.setResult(profile);
responseBean.setResult(profile);
responseBean.setSuccess(true);
ObjectMapper objectMapper = new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (Exception e) {
logger.error("Unable to retrieve user's profile", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
}
/**
* Read the user's email address. The user is the one owning the token
*
* @return rhe user's email address
*
* @responseExample application/json {
* "success": true,
* "message": null,
* "result": "email@isti.cnr.it"
* }
*/
@GET
@Path("/get-email")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response getCurrentEmail() {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try {
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
String email = owner.getEmail();
responseBean.setResult(email);
responseBean.setSuccess(true);
} catch (Exception e) {
logger.error("Unable to retrieve user's email", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Read the user's fullname. The user is the one owning the token
*
* @return the user's fullname
*
* @responseExample application/json {
* "success": true,
* "message": null,
* "result": "FirstName LastName"
* }
*/
@GET
@Path("get-fullname")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes({
@ResponseCode(code = 200, condition = "The user's fullname is reported in the 'result' field of the returned object"),
@ResponseCode(code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getUserFullname() {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
String username = owner.getId();
String fullName = null;
if (owner.isApplication()) {
logger.warn("Trying to access users method via a token different than USER is not allowed");
// only users can use "me"
throw new ForbiddenException(ErrorMessages.NOT_USER_TOKEN_CONTEXT_USED);
}
try {
GCubeUser profile = LiferayProfileClient.getUserProfileByUsername(username);
fullName = profile.getFullname();
logger.info("Found fullname " + fullName + " for user " + username);
responseBean.setResult(fullName);
responseBean.setSuccess(true);
} catch (Exception e) {
logger.error("Unable to retrieve attribute for user.", e);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@GET
@Path("/get-all-usernames")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response getUsernamesByRole(
@QueryParam("first") @DefaultValue("0") int first,
@QueryParam("max") @DefaultValue("100") int max,
@QueryParam("firstResult") @DefaultValue("0") int firstResult,
@QueryParam("maxResults") @DefaultValue("100") int maxResults) {
if (firstResult > 0) {
first = firstResult;
}
if (maxResults != 100) {
max = maxResults;
}
Status status = Status.OK;
ResponseBean responseBean = new ResponseBean();
try {
List<UserRepresentation> users = KCUserController.contextUsers(first, max);
Object result = KCUserController.formatList(users, KCUserController.REPR.compact);
responseBean.setResult(result);
responseBean.setSuccess(true);
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
return Response.serverError().build();
} catch (Exception e) {
logger.error("Unable to retrieve users with the requested role", e);
// responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@GET
@Path("/get-all-fullnames-and-usernames")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response getAllUsernamesFullnames(
@QueryParam("emailVerified") Boolean emailVerified,
@QueryParam("enabled") Boolean enabled,
@QueryParam("first") @DefaultValue("0") int first,
@QueryParam("max") @DefaultValue("100") int max,
@QueryParam("firstResult") @DefaultValue("0") int firstResult,
@QueryParam("maxResults") @DefaultValue("100") int maxResults) {
if (firstResult > 0) {
first = firstResult;
}
if (maxResults != 100) {
max = maxResults;
}
Status status = Status.OK;
ResponseBean responseBean = new ResponseBean();
try {
UsersResource users_resource = KCUserController.realmUsersResource();
List<UserRepresentation> users = users_resource.search(emailVerified, first, max, enabled,
true);
Map<String, String> usernamesAndFullnames = new HashMap<String, String>();
users.forEach(user -> usernamesAndFullnames.put(user.getUsername(), user.getEmail()));
responseBean.setResult(usernamesAndFullnames);
responseBean.setSuccess(true);
} catch (Exception e) {
logger.error("Unable to retrieve users", e);
// responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@GET
@Path("/get-usernames-by-role")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response getUsernamesByRole(
@QueryParam("role-name") String roleName,
@QueryParam("first") @DefaultValue("0") int first,
@QueryParam("max") @DefaultValue("100") int max,
@QueryParam("firstResult") @DefaultValue("0") int firstResult,
@QueryParam("maxResults") @DefaultValue("100") int maxResults) {
if (firstResult > 0) {
first = firstResult;
}
if (maxResults != 100) {
max = maxResults;
}
Status status = Status.OK;
ResponseBean responseBean = new ResponseBean();
List<String> usernames = new ArrayList<String>();
try {
List<UserRepresentation> users = KCUserController.searchUsersByRole(roleName, first, max);
if (users != null) {
for (UserRepresentation user : users) {
usernames.add(user.getUsername());
}
}
responseBean.setResult(usernames);
responseBean.setSuccess(true);
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
return Response.serverError().build();
} catch (Exception e) {
logger.error("Unable to retrieve users with the requested role", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
}
@GET
@Path("/user-exists")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response checkUserExists(@QueryParam("username") String username) {
Status status = Status.OK;
ResponseBean responseBean = new ResponseBean();
try {
UserRepresentation user = KCUserController.getUserByUsername(username);
boolean user_exists = user != null;
responseBean.setResult(user_exists);
responseBean.setSuccess(true);
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
return Response.serverError().build();
} catch (Exception e) {
logger.error("Unable to check if user exists with username " + username, e);
// responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Read a user's custom attribute. The user is the one owning the token
@ -58,7 +365,7 @@ public class UsersSocialAPI {
* @throws ValidationException
*/
@GET
@Path("get-custom-attribute/")
@Path("get-custom-attribute")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes({
@ResponseCode(code = 200, condition = "Successful read of the attribute, reported in the 'result' field of the returned object"),
@ -109,293 +416,6 @@ public class UsersSocialAPI {
return Response.status(status).entity(responseBean).build();
}
/**
* Read the user's fullname. The user is the one owning the token
*
* @return the user's fullname
*/
@GET
@Path("get-fullname")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes({
@ResponseCode(code = 200, condition = "The user's fullname is reported in the 'result' field of the returned object"),
@ResponseCode(code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getUserFullname() {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
String username = owner.getId();
String fullName = null;
if (owner.isApplication()) {
logger.warn("Trying to access users method via a token different than USER is not allowed");
// only users can use "me"
throw new ForbiddenException(ErrorMessages.NOT_USER_TOKEN_CONTEXT_USED);
}
try {
GCubeUser profile = LiferayProfileClient.getUserProfileByUsername(username);
fullName = profile.getFullname();
logger.info("Found fullname " + fullName + " for user " + username);
responseBean.setResult(fullName);
responseBean.setSuccess(true);
} catch (Exception e) {
logger.error("Unable to retrieve attribute for user.", e);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Read the user's email address. The user is the one owning the token
*
* @return rhe user's email address
*/
@GET
@Path("/get-email")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response getCurrentEmail() {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try {
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
String email = owner.getEmail();
responseBean.setResult(email);
responseBean.setSuccess(true);
} catch (Exception e) {
logger.error("Unable to retrieve user's email", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Get the profile associated to the token
*
* @responseExample application/json { "success" : true, "message" : null,
* "result" : { "user_id" : 23769487, "username" :
* "john.smith", "email" : "********", "first_name" : "John",
* "middle_name" : "", "last_name" : "Smith", "fullname" :
* "John Smith", "registration_date" : 1475151491415,
* "user_avatar_url" : "https://******D", "male" : true,
* "job_title" : "", "location_industry" : "no",
* "custom_attrs_map" : null, "email_addresses" : [ ],
* "screen_name" : "john.smith", "user_avatar_id" :
* "https://****sY%3D" } }
* @return the user's profile. The user is the one owning the token
*/
@GET
@Path("get-profile")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes({
@ResponseCode(code = 200, condition = "The user's profile is reported in the 'result' field of the returned object"),
@ResponseCode(code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getUserProfile() {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try {
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
String username = owner.getId();
GCubeUser profile = LiferayProfileClient.getUserProfileByUsername(username);
responseBean.setResult(profile);
responseBean.setResult(profile);
responseBean.setSuccess(true);
} catch (Exception e) {
logger.error("Unable to retrieve user's profile", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@GET
@Path("/get-usernames-by-role")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response getUsernamesByRole(
@QueryParam("role-name") String roleName,
@QueryParam("first") Integer first,
@QueryParam("max") Integer max,
@QueryParam("firstResult") Integer firstResult,
@QueryParam("maxResults") Integer maxResults) {
if (first > 0) {
firstResult = first;
}
if (max > 0) {
maxResults = first;
}
Status status = Status.OK;
ResponseBean responseBean;
responseBean = new ResponseBean();
List<String> usernames = new ArrayList<String>();
try {
List<UserRepresentation> users = KCUserController.searchUsersByRole(roleName, firstResult, maxResults);
if (users != null) {
for (UserRepresentation user : users) {
usernames.add(user.getUsername());
}
}
responseBean.setResult(usernames);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
return Response.serverError().build();
} catch (Exception e) {
logger.error("Unable to retrieve users with the requested role", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
}
@GET
@Path("/get-all-fullnames-and-usernames")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response getAllUsernamesFullnames(
@QueryParam("emailVerified") Boolean emailVerified,
@QueryParam("enabled") Boolean enabled,
@QueryParam("first") Integer first,
@QueryParam("max") Integer max,
@QueryParam("firstResult") Integer firstResult,
@QueryParam("maxResults") Integer maxResults) {
if (first > 0) {
firstResult = first;
}
if (max > 0) {
maxResults = first;
}
Status status = Status.OK;
ResponseBean responseBean;
if (firstResult != null || maxResults != null) {
responseBean = new ResponseBeanPaginated(firstResult, maxResults);
} else {
responseBean = new ResponseBean();
}
try {
UsersResource users_resource = KCUserController.users();
List<UserRepresentation> users = users_resource.search(emailVerified, firstResult, maxResults, enabled,
true);
Map<String, String> usernamesAndFullnames = new HashMap<String, String>();
users.forEach(user -> usernamesAndFullnames.put(user.getUsername(), user.getEmail()));
responseBean.setResult(usernamesAndFullnames);
responseBean.setSuccess(true);
} catch (Exception e) {
logger.error("Unable to retrieve users", e);
// responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@GET
@Path("/get-all-usernames")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response getUsernamesByRole(
@QueryParam("first") Integer firstResult,
@QueryParam("max") Integer maxResults) {
Status status = Status.OK;
ResponseBean responseBean;
if (firstResult != null || maxResults != null) {
responseBean = new ResponseBeanPaginated(firstResult, maxResults);
} else {
responseBean = new ResponseBean();
}
List<String> usernames = new ArrayList<String>();
try {
List<UserRepresentation> users = KCUserController.users(firstResult, maxResults);
if (users != null) {
for (UserRepresentation user : users) {
usernames.add(user.getUsername());
}
}
responseBean.setResult(usernames);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
return Response.serverError().build();
} catch (Exception e) {
logger.error("Unable to retrieve users with the requested role", e);
// responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@GET
@Path("/user-exists")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response checkUserExists(@QueryParam("username") String username) {
Status status = Status.OK;
ResponseBean responseBean = new ResponseBean();
try {
UserRepresentation user = KCUserController.getUserByUsername(username);
boolean user_exists = user != null;
responseBean.setResult(user_exists);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
return Response.serverError().build();
} catch (Exception e) {
logger.error("Unable to check if user exists with username " + username, e);
// responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@GET
@Path("/get-oauth-profile")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
@ -412,7 +432,7 @@ public class UsersSocialAPI {
responseBean.setResult(user);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
@ -428,4 +448,57 @@ public class UsersSocialAPI {
return Response.status(status).entity(responseBean).build();
}
/**
* Get the list of users having a given global-role, e.g. 'Administrator'.
* (Legacy)
*
* @param roleName the name of the role to be checked (e.g. Administrator)
* @return the list of users having a given global-role
*/
@GET
@Path("get-usernames-by-global-role")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes({
@ResponseCode(code = 200, condition = "The list is put into the 'result' field of the returned object"),
@ResponseCode(code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getUsernamesByGlobalRole(
@QueryParam("role-name") String role_name,
@QueryParam("first") @DefaultValue("0") int first,
@QueryParam("max") @DefaultValue("100") int max,
@QueryParam("firstResult") @DefaultValue("0") int firstResult,
@QueryParam("maxResults") @DefaultValue("100") int maxResults) {
if (firstResult > 0) {
first = firstResult;
}
if (maxResults != 100) {
max = maxResults;
}
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
if (!owner.isApplication()) {
logger.warn(ErrorMessages.NOT_USER_TOKEN_CONTEXT_USED);
throw new ForbiddenException(ErrorMessages.NOT_SERVICE_TOKEN_CONTEXT_USED);
}
RealmResource realmResource = KkClientFactory.getSingleton().getKKRealm();
RolesResource roles_resource = realmResource.roles();
RoleResource r = roles_resource.get(role_name);
List<UserRepresentation> users = r.getUserMembers(first, max);
responseBean.setResult(KCUserController.formatList(users, KCUserController.REPR.username));
responseBean.setSuccess(true);
return Response.status(status).entity(responseBean).build();
}
}

View File

@ -13,7 +13,7 @@ import org.gcube.service.idm.controller.JWTController;
import org.gcube.service.idm.controller.KCUserController;
import org.gcube.service.idm.controller.LiferayProfileClient;
import org.gcube.service.idm.keycloack.KkClientFactory;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import org.gcube.service.rest.ErrorMessages;
import org.gcube.service.rest.ResponseBean;
import org.gcube.service.rest.ResponseBeanMap;
@ -29,6 +29,8 @@ import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
@ -62,6 +64,10 @@ import jakarta.ws.rs.core.Response;
*/
@ManagedBy(IdMManager.class)
@RequestHeaders({
@RequestHeader(name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader(name = "Content-Type", description = "application/json")
})
@Path("users")
public class UserAPI {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(UserAPI.class);
@ -104,7 +110,7 @@ public class UserAPI {
@QueryParam("inspect") @DefaultValue("false") Boolean inspect) {
logger.info("/users/me");
ResponseBean responseBean = new ResponseBean();
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
@ -173,7 +179,7 @@ public class UserAPI {
@QueryParam("inspect") @DefaultValue("false") Boolean inspect) {
ResponseBeanMap responseBean = new ResponseBeanMap();
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
if (!AuthController.checkAnyRole(AuthController.ACCESS_READ_ROLES)) {
// the user can see only his profile
@ -225,8 +231,6 @@ public class UserAPI {
for (GroupRepresentation g : groups) {
groupRolesClients.put(g.getId(), g.getClientRoles());
}
groups.get(0).getClientRoles();
}
return result;
}
@ -255,7 +259,7 @@ public class UserAPI {
responseBean.setResult(owner);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
@ -290,7 +294,7 @@ public class UserAPI {
// UserResource user = KCUserController.getUserById();
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
@ -362,7 +366,7 @@ public class UserAPI {
@PathParam("parameter") USER_DETAILS parameter) {
ResponseBean responseBean = new ResponseBean();
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
Secret secret = SecretManagerProvider.get();
Owner owner = secret.getOwner();
@ -431,7 +435,7 @@ public class UserAPI {
}
/**
* Returns users, filtered according to query parameters.
* Search users in all realm, filtered according to query parameters.
*
* @param format response format
* @param exact Boolean which defines whether the params 'last', 'first',
@ -455,7 +459,7 @@ public class UserAPI {
@Path("/search")
@Produces(MediaType.APPLICATION_JSON)
public Response search(
@QueryParam("format") @DefaultValue("username") KCUserController.REPRESENTATION format,
@QueryParam("format") @DefaultValue("username") KCUserController.REPR format,
@QueryParam("exact") @DefaultValue("true") Boolean exact,
@QueryParam("username") String username,
@ -470,23 +474,23 @@ public class UserAPI {
responseBean = new ResponseBeanPaginated(firstResult, maxResults);
try {
if (!format.equals(KCUserController.REPRESENTATION.username)
if (!format.equals(KCUserController.REPR.username)
&& !AuthController.checkAnyRole(AuthController.ACCESS_READ_ROLES)) {
// the user can see only his profile
throw new ForbiddenException(ErrorMessages.USER_NOT_AUTHORIZED_PRIVATE);
}
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
Boolean briefRepresentation = !KCUserController.REPRESENTATION.full.equals(format);
Boolean briefRepresentation = !KCUserController.REPR.full.equals(format);
List<UserRepresentation> users = realm.users().search(
username, firstName, lastName, email,
firstResult, maxResults,
enabled, briefRepresentation, exact);
responseBean.setResult(KCUserController.formatListUsers(users, format));
responseBean.setResult(KCUserController.formatList(users, format));
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();

View File

@ -13,7 +13,7 @@ import org.gcube.common.security.Owner;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.common.security.secrets.Secret;
import org.gcube.service.idm.IdMManager;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.annotations.ManagedBy;
import org.gcube.smartgears.context.container.ContainerContext;
@ -70,7 +70,7 @@ public class HelloService {
ContainerContext container = ContextProvider.get().container();
data.put("container", container);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
try {
String jsonData = objectMapper.writeValueAsString(data);

View File

@ -4,7 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import org.gcube.service.idm.IdMManager;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import org.gcube.smartgears.annotations.ManagedBy;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
@ -73,7 +73,7 @@ public class KeycloakTestService {
// responseBean.setResult(usernames);
// responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(usernames);
return Response.ok(jsonData).build();

View File

@ -22,7 +22,7 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
*
*/
public class ContextSerializator {
public class IdmObjectSerializator {
private static ObjectMapper serializer = null;
protected static TypeReference<HashMap<String, Object>> typeRefHashmap = new TypeReference<HashMap<String, Object>>() {

View File

@ -5,9 +5,17 @@ public class ErrorMessages {
public static final String ERROR_IN_API_RESULT = "The error is reported into the 'message' field of the returned object";
public static final String INVALID_ATTRIBUTE = "Such an attribute doesn't exist";
public static final String NOT_USER_TOKEN_CONTEXT_USED = "User's information can only be retrieved through a user token (not qualified)";
public static final String NOT_SERVICE_TOKEN_CONTEXT_USED = "This method can only be called with an infrastructure token";
public static final String USER_NOT_AUTHORIZED_PRIVATE = "User is not authorized to access private data";
public static final String CANNOT_RETRIEVE_PROFILE = "Unable to retrieve user profile";
public static final String RESERVED_PARAMETER = "The parameter can be used only by realm administrators: ";
//
// protected static final String CANNOT_RETRIEVE_SERVICE_ENDPOINT_INFORMATION =
// "Unable to retrieve such service endpoint information";

View File

@ -1,17 +0,0 @@
package org.gcube.service.rest.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import jakarta.ws.rs.HttpMethod;
/**
* @author Luca Frosini (ISTI - CNR)
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PATCH")
public @interface PATCH {
}

View File

@ -1,17 +0,0 @@
package org.gcube.service.rest.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import jakarta.ws.rs.HttpMethod;
/**
* @author Luca Frosini (ISTI - CNR)
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PURGE")
public @interface PURGE {
}

View File

@ -1,49 +0,0 @@
package org.gcube.service.rest.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class HTTPUtility {
private static final Logger logger = LoggerFactory.getLogger(HTTPUtility.class);
public static StringBuilder getStringBuilder(InputStream inputStream) throws IOException {
StringBuilder result = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
}
return result;
}
public static String getResultAsString(HttpURLConnection httpURLConnection) throws IOException {
int responseCode = httpURLConnection.getResponseCode();
if (responseCode >= Status.BAD_REQUEST.getStatusCode()) {
Status status = Status.fromStatusCode(responseCode);
InputStream inputStream = httpURLConnection.getErrorStream();
StringBuilder result = getStringBuilder(inputStream);
logger.trace(result.toString());
throw new WebApplicationException(result.toString(), status);
}
InputStream inputStream = httpURLConnection.getInputStream();
String ret = getStringBuilder(inputStream).toString();
logger.trace("Got Respose is {}", ret);
return ret;
}
}