diff --git a/Backend/alfresco/module/src/main/java/org/edu_sharing/metadataset/v2/MetadataReader.java b/Backend/alfresco/module/src/main/java/org/edu_sharing/metadataset/v2/MetadataReader.java index 60fa43ff79..2c4f56d87a 100644 --- a/Backend/alfresco/module/src/main/java/org/edu_sharing/metadataset/v2/MetadataReader.java +++ b/Backend/alfresco/module/src/main/java/org/edu_sharing/metadataset/v2/MetadataReader.java @@ -949,6 +949,21 @@ private List getSorts() throws XPathExpressionException { } } } + if (name.equals("defaultSearch")) { + NodeList list3 = data.getChildNodes(); + for (int k = 0; k < list3.getLength(); k++) { + if(sort.getDefaultValueSearch() == null) { + sort.setDefaultValueSearch(new MetadataSort.MetadataSortDefault()); + } + Node data2 = list3.item(k); + if (data2.getNodeName().equals("sortBy")) { + sort.getDefaultValueSearch().setSortBy(data2.getTextContent()); + } + if (data2.getNodeName().equals("sortAscending")) { + sort.getDefaultValueSearch().setSortAscending(Boolean.parseBoolean(data2.getTextContent())); + } + } + } if (name.equals("columns")) { List columns = getMetadataSortColumns(data); sort.setColumns(columns); diff --git a/Backend/alfresco/module/src/main/java/org/edu_sharing/metadataset/v2/MetadataSort.java b/Backend/alfresco/module/src/main/java/org/edu_sharing/metadataset/v2/MetadataSort.java index 0733a468b5..8c3362ea18 100644 --- a/Backend/alfresco/module/src/main/java/org/edu_sharing/metadataset/v2/MetadataSort.java +++ b/Backend/alfresco/module/src/main/java/org/edu_sharing/metadataset/v2/MetadataSort.java @@ -1,11 +1,14 @@ package org.edu_sharing.metadataset.v2; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import lombok.Getter; +import lombok.Setter; + import java.io.Serializable; -import java.util.ArrayList; import java.util.List; public class MetadataSort implements Serializable { - public class MetadataSortDefault implements Serializable { + public static class MetadataSortDefault implements Serializable { private String sortBy; private boolean sortAscending; @@ -27,7 +30,14 @@ public void setSortAscending(boolean sortAscending) { } private String id; private String mode; + @JsonPropertyDescription("Default sort state (for both with and without a search string)") + @Getter + @Setter private MetadataSortDefault defaultValue=new MetadataSortDefault(); + @JsonPropertyDescription("Default sort state only when searching (when unset, defaultValue is used)") + @Getter + @Setter + private MetadataSortDefault defaultValueSearch=null; private List columns; public String getId() { @@ -53,14 +63,6 @@ public void setColumns(List columns) { this.columns = columns; } - public MetadataSortDefault getDefaultValue() { - return defaultValue; - } - - public void setDefaultValue(MetadataSortDefault defaultValue) { - this.defaultValue = defaultValue; - } - @Override public boolean equals(Object obj) { if(obj instanceof MetadataSort){ diff --git a/Backend/services/core/src/main/java/org/edu_sharing/repository/client/tools/I18nAngular.java b/Backend/services/core/src/main/java/org/edu_sharing/repository/client/tools/I18nAngular.java index cb2f4f054a..62f15bc634 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/repository/client/tools/I18nAngular.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/repository/client/tools/I18nAngular.java @@ -10,11 +10,14 @@ import jakarta.servlet.ServletContext; import java.io.File; +import java.util.HashMap; +import java.util.Map; /** * Class to load language data from the angular i18n files (json) */ public class I18nAngular { + private static Map I18N_CACHE = new HashMap<>(); public static final String GENDER_SEPARATOR = "*"; public static Logger logger=Logger.getLogger(I18nAngular.class); public static String getTranslationAngular(String scope,String key){ @@ -54,9 +57,16 @@ public static JSONObject getLanguageStrings() throws Exception{ */ private static String getTranslationAngular(String scope,String key,String language){ try { + String cache = I18N_CACHE.get(language + ":" + key); + if(cache != null) { + return cache; + } String override=getTranslationFromOverride(key,language); - if(override!=null) - return replaceGenderSeperator(override); + if(override!=null) { + override = replaceGenderSeperator(override); + I18N_CACHE.put(language + ":" + key, override); + return override; + } // Using global instance singe it only is used for file reading ServletContext servletContext = Context.getGlobalContext(); if(servletContext == null) { @@ -75,7 +85,9 @@ private static String getTranslationAngular(String scope,String key,String langu object=object.getJSONObject(list[i]); } String result = object.getString(list[list.length-1]); - return replaceGenderSeperator(result); + result = replaceGenderSeperator(result); + I18N_CACHE.put(language + ":" + key, result); + return result; } catch (Exception e) { if(language.startsWith("de-")) { return getTranslationAngular(scope, key, "de"); diff --git a/Backend/services/core/src/main/java/org/edu_sharing/restservices/GroupDao.java b/Backend/services/core/src/main/java/org/edu_sharing/restservices/GroupDao.java index 788e75aa6f..1d67ca9679 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/restservices/GroupDao.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/restservices/GroupDao.java @@ -3,9 +3,11 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.permissions.AccessDeniedException; +import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; @@ -25,6 +27,7 @@ import org.edu_sharing.restservices.shared.GroupProfile; import org.edu_sharing.service.authority.AuthorityService; import org.edu_sharing.service.authority.AuthorityServiceFactory; +import org.edu_sharing.service.authority.AuthorityServiceHelper; import org.edu_sharing.service.nodeservice.NodeServiceHelper; import org.edu_sharing.service.notification.NotificationService; import org.edu_sharing.service.notification.NotificationServiceFactoryUtility; @@ -38,6 +41,8 @@ import java.util.*; import java.util.stream.Collectors; +import static org.alfresco.service.cmr.security.PermissionService.GROUP_PREFIX; + public class GroupDao { static Logger logger = Logger.getLogger(GroupDao.class); @@ -59,31 +64,34 @@ public static GroupDao getGroup(RepositoryDao repoDao, String groupName) throws } } - public static GroupDao createGroup(RepositoryDao repoDao, String groupName, GroupProfile profile, String parentGroup) throws DAOException { + public static String createGroup(RepositoryDao repoDao, String groupName, GroupProfile profile, String parentGroup) throws DAOException { try { AuthorityService authorityService = AuthorityServiceFactory.getAuthorityService(repoDao.getApplicationInfo().getAppId()); String result = authorityService.createGroup(groupName, profile.getDisplayName(), parentGroup); - GroupDao groupDao = GroupDao.getGroup(repoDao, result); if (result != null) { // permission check was done already, so run as system to allow org admin to set properties AuthenticationUtil.runAsSystem(() -> { - groupDao.applyProfile(profile); + applyProfile(result.startsWith(GROUP_PREFIX) ? result : GROUP_PREFIX + result, profile); return null; }); } - // reload data after it was changed - return GroupDao.getGroup(repoDao, result); + return result; } catch (Exception e) { throw DAOException.mapping(e); } } - void applyProfile(GroupProfile profile) { - setGroupEmail(profile); - setGroupType(profile); - setScopeType(profile); + static void applyProfile(String authorityName, GroupProfile profile) { + ApplicationContext alfApplicationContext = AlfAppContextGate.getApplicationContext(); + ServiceRegistry serviceRegistry = (ServiceRegistry) alfApplicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY); + NodeService nodeService = serviceRegistry.getNodeService(); + + NodeRef authorityRef = AuthorityServiceHelper.getAuthorityNodeRef(authorityName); + setGroupEmail(nodeService, authorityRef, profile); + setGroupType(nodeService, authorityRef, profile); + setScopeType(nodeService, authorityRef, profile); if(profile.getCustomAttributes() != null && !profile.getCustomAttributes().isEmpty()) { - authorityService.setCustomAttributes(authorityName, profile.getCustomAttributes()); + AuthorityServiceFactory.getLocalService().setCustomAttributes(authorityName, profile.getCustomAttributes()); } } @@ -138,13 +146,13 @@ public GroupDao(RepositoryDao repoDao, String groupName) throws DAOException { this.repoDao = repoDao; this.authorityName = - groupName.startsWith(PermissionService.GROUP_PREFIX) + groupName.startsWith(GROUP_PREFIX) ? groupName - : PermissionService.GROUP_PREFIX + groupName; + : GROUP_PREFIX + groupName; this.groupName = - groupName.startsWith(PermissionService.GROUP_PREFIX) - ? groupName.substring(PermissionService.GROUP_PREFIX.length()) + groupName.startsWith(GROUP_PREFIX) + ? groupName.substring(GROUP_PREFIX.length()) : groupName; this.displayName = ((MCAlfrescoAPIClient) baseClient).getGroupDisplayName(this.groupName); @@ -181,7 +189,7 @@ public void changeProfile(GroupProfile profile) throws DAOException { @Override public Void doWork() throws Exception { ((MCAlfrescoAPIClient) repoDao.getBaseClient()).createOrUpdateGroup(groupName, profile.getDisplayName()); - applyProfile(profile); + applyProfile(authorityName, profile); // rename admin group renameSubGroup(profile, org.edu_sharing.alfresco.service.AuthorityService.ADMINISTRATORS_GROUP, org.edu_sharing.alfresco.service.AuthorityService.ADMINISTRATORS_GROUP_DISPLAY_POSTFIX); @@ -210,7 +218,7 @@ private void renameOrganisationFolder() { } private void renameSubGroup(GroupProfile profile, String subgroup, String postfix) { - String authorityName = PermissionService.GROUP_PREFIX + org.edu_sharing.alfresco.service.AuthorityService.getGroupName( + String authorityName = GROUP_PREFIX + org.edu_sharing.alfresco.service.AuthorityService.getGroupName( subgroup, groupName); if (authorityService.authorityExists(authorityName)) { String newDisplayName = profile.getDisplayName() + postfix; @@ -220,23 +228,23 @@ private void renameSubGroup(GroupProfile profile, String subgroup, String postfi } } - protected void setGroupType(GroupProfile profile) { + static protected void setGroupType(NodeService nodeService, NodeRef authorityRef, GroupProfile profile) { if (profile.getGroupType() != null) { - authorityService.addAuthorityAspect(PermissionService.GROUP_PREFIX + groupName, CCConstants.CCM_ASPECT_GROUPEXTENSION); + nodeService.addAspect(authorityRef, QName.createQName(CCConstants.CCM_ASPECT_GROUPEXTENSION), new HashMap<>()); } - authorityService.setAuthorityProperty(PermissionService.GROUP_PREFIX + groupName, CCConstants.CCM_PROP_GROUPEXTENSION_GROUPTYPE, profile.getGroupType()); + NodeServiceHelper.setProperty(authorityRef, CCConstants.CCM_PROP_GROUPEXTENSION_GROUPTYPE, profile.getGroupType(), true); } - protected void setGroupEmail(GroupProfile profile) { - authorityService.setAuthorityProperty(PermissionService.GROUP_PREFIX + groupName, CCConstants.CCM_PROP_GROUPEXTENSION_GROUPEMAIL, profile.getGroupEmail()); + static protected void setGroupEmail(NodeService nodeService, NodeRef authorityRef, GroupProfile profile) { + nodeService.setProperty(authorityRef, QName.createQName(CCConstants.CCM_PROP_GROUPEXTENSION_GROUPEMAIL), profile.getGroupEmail()); } - protected void setScopeType(GroupProfile profile) { + static protected void setScopeType(NodeService nodeService, NodeRef authorityRef, GroupProfile profile) { if (profile.getScopeType() != null) { - authorityService.addAuthorityAspect(PermissionService.GROUP_PREFIX + groupName, CCConstants.CCM_ASPECT_SCOPE); + nodeService.addAspect(authorityRef, QName.createQName(CCConstants.CCM_ASPECT_SCOPE), new HashMap<>()); } - authorityService.setAuthorityProperty(PermissionService.GROUP_PREFIX + groupName, CCConstants.CCM_PROP_SCOPE_TYPE, profile.getScopeType()); + nodeService.setProperty(authorityRef, QName.createQName(CCConstants.CCM_PROP_SCOPE_TYPE), profile.getScopeType()); } public void delete() throws DAOException { @@ -246,7 +254,7 @@ public void delete() throws DAOException { AuthenticationUtil.runAsSystem(new RunAsWork() { @Override public Void doWork() throws Exception { - authorityService.deleteAuthority(PermissionService.GROUP_PREFIX + groupName); + authorityService.deleteAuthority(GROUP_PREFIX + groupName); return null; } }); @@ -333,7 +341,7 @@ public Group asGroup(boolean resolveOrganizations) { data.setProfile(profile); data.setProperties(getProperties()); data.setAspects(getAspects()); - data.setSignupMethod(getSignupMethod(ref)); + data.setSignupMethod(getSignupMethod(properties)); return data; } @@ -342,8 +350,8 @@ private Map getCustomAttributes() { return authorityService.getCustomAttributes(authorityName); } - public static GroupSignupMethod getSignupMethod(NodeRef ref) { - String method = NodeServiceHelper.getProperty(ref, CCConstants.CCM_PROP_GROUP_SIGNUP_METHOD); + public static GroupSignupMethod getSignupMethod(Map properties) { + String method = (String) properties.get(CCConstants.CCM_PROP_GROUP_SIGNUP_METHOD); if (method == null) { return null; } @@ -426,7 +434,7 @@ public GroupSignupResult signupUser(String password) throws DAOException { try { ToolPermissionHelper.throwIfToolpermissionMissing(CCConstants.CCM_VALUE_TOOLPERMISSION_SIGNUP_GROUP); return AuthenticationUtil.runAsSystem(() -> { - GroupSignupMethod method = getSignupMethod(ref); + GroupSignupMethod method = getSignupMethod(properties); boolean addMember = false; NodeRef userRef = authorityService.getAuthorityNodeRef(AuthenticationUtil.getFullyAuthenticatedUser()); diff --git a/Backend/services/core/src/main/java/org/edu_sharing/restservices/NodeDao.java b/Backend/services/core/src/main/java/org/edu_sharing/restservices/NodeDao.java index 381db63fc0..17a6287101 100755 --- a/Backend/services/core/src/main/java/org/edu_sharing/restservices/NodeDao.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/restservices/NodeDao.java @@ -2687,22 +2687,23 @@ public void setOwner(String username) { nodeService.setOwner(this.getId(), username); } - public void setProperty(String property, Serializable value, boolean keepModifiedDate) { + public static void setProperty(RepositoryDao repoDao, String nodeId, String property, Serializable value, boolean keepModifiedDate) { + NodeService nodeService = NodeServiceFactory.getNodeService(repoDao.getId()); if (keepModifiedDate) { nodeService.keepModifiedDate( - StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol(), StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier(), this.getId(), - () -> setPropertyInternal(property, value) + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol(), StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier(), nodeId, + () -> setPropertyInternal(nodeService, nodeId, property, value) ); } else { - setPropertyInternal(property, value); + setPropertyInternal(nodeService, nodeId, property, value); } } - private void setPropertyInternal(String property, Serializable value) { + private static void setPropertyInternal(NodeService nodeService, String nodeId, String property, Serializable value) { if (value == null) { - nodeService.removeProperty(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol(), StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier(), this.getId(), property); + nodeService.removeProperty(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol(), StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier(), nodeId, property); } else { - nodeService.setProperty(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol(), StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier(), this.getId(), property, value, false); + nodeService.setProperty(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol(), StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier(), nodeId, property, value, false); } } diff --git a/Backend/services/core/src/main/java/org/edu_sharing/restservices/OrganizationDao.java b/Backend/services/core/src/main/java/org/edu_sharing/restservices/OrganizationDao.java index c66a4ae1b9..a5f5a9d5cf 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/restservices/OrganizationDao.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/restservices/OrganizationDao.java @@ -1,31 +1,24 @@ package org.edu_sharing.restservices; -import java.util.List; -import java.util.stream.Collectors; - import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.cmr.security.PermissionService; -import org.apache.commons.codec.digest.DigestUtils; import org.edu_sharing.alfresco.authentication.HttpContext; import org.edu_sharing.alfresco.service.OrganisationService; import org.edu_sharing.repository.client.rpc.EduGroup; import org.edu_sharing.repository.client.tools.CCConstants; import org.edu_sharing.repository.server.MCAlfrescoAPIClient; -import org.edu_sharing.restservices.organization.v1.model.GroupSignupDetails; -import org.edu_sharing.restservices.shared.Authority; -import org.edu_sharing.restservices.shared.GroupProfile; -import org.edu_sharing.restservices.shared.NodeRef; -import org.edu_sharing.restservices.shared.Organization; +import org.edu_sharing.restservices.shared.*; import org.edu_sharing.service.authority.AuthorityServiceFactory; -import org.edu_sharing.service.nodeservice.NodeServiceHelper; import org.edu_sharing.service.organization.OrganizationService; import org.edu_sharing.service.organization.OrganizationServiceFactory; -import org.edu_sharing.service.organization.GroupSignupMethod; import org.edu_sharing.service.search.SearchServiceFactory; import org.edu_sharing.spring.ApplicationContextFactory; +import java.util.List; +import java.util.stream.Collectors; + public class OrganizationDao { @@ -168,10 +161,11 @@ public Organization asOrganization() { data.setAuthorityType(Authority.Type.GROUP); data.setGroupName(groupName); data.setAdministrationAccess(hasAdministrationAccess()); - data.setSignupMethod(GroupDao.getSignupMethod(ref)); try { - data.setProfile(GroupDao.getGroup(repoDao, authorityName).asGroup().getProfile()); + Group group = GroupDao.getGroup(repoDao, authorityName).asGroup(); + data.setSignupMethod(group.getSignupMethod()); + data.setProfile(group.getProfile()); }catch(Throwable t){ throw new RuntimeException("Error getting profile for organization "+authorityName,t); } diff --git a/Backend/services/core/src/main/java/org/edu_sharing/restservices/iam/v1/IamApi.java b/Backend/services/core/src/main/java/org/edu_sharing/restservices/iam/v1/IamApi.java index 3b89cec0d0..f241480f5f 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/restservices/iam/v1/IamApi.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/restservices/iam/v1/IamApi.java @@ -52,23 +52,23 @@ public class IamApi { private static Logger logger = Logger.getLogger(IamApi.class); - @GET - - @Path("/people/{repository}") - - @Operation(summary = "Search users.", description = "Search users. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = UserEntries.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response searchUser( + @GET + + @Path("/people/{repository}") + + @Operation(summary = "Search users.", description = "Search users. (admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = UserEntries.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response searchUser( @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, @Parameter(description = "pattern",required=true) @QueryParam("pattern") String pattern, @Parameter(description = "global search context, defaults to true, otherwise just searches for users within the organizations", required = false, schema = @Schema(defaultValue="true")) @QueryParam("global") Boolean global, @@ -79,92 +79,92 @@ public Response searchUser( @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, @Context HttpServletRequest req) { - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); Map filter=new HashMap<>(); if(status!=null) filter.put(CCConstants.getValidLocalName(CCConstants.CM_PROP_PERSON_ESPERSONSTATUS),status.name()); SearchResult search=SearchServiceFactory.getSearchService(repoDao.getId()).searchUsers( - pattern, - global==null ? true : global, - skipCount!=null ? skipCount : 0, - maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, - new SortDefinition(sortProperties,sortAscending), - filter - ); - - List result = new ArrayList<>(); - for (String user: search.getData()) { - result.add(new PersonDao(repoDao,user).asPersonSimple(true)); - } - UserEntries response = new UserEntries(); - response.setList(result); - response.setPagination(new Pagination(search)); - - - return Response.status(Response.Status.OK).entity(response).build(); - - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } - - - @OPTIONS - @Path("/people/{repository}") - @Hidden - - public Response options01() { - - return Response.status(Response.Status.OK).header("Allow", "OPTIONS, GET").build(); - } - - @GET - @Path("/people/{repository}/{person}") - @Operation(summary = "Get the user.", description = "Get the user. (Not all information are feteched for foreign profiles if current user is not an admin)") - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = UserEntry.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - public Response getUser( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Context HttpServletRequest req) { - - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - - UserEntry response = new UserEntry(); - response.setPerson(personDao.asPerson()); - - org.edu_sharing.alfresco.repository.server.authentication.Context context = org.edu_sharing.alfresco.repository.server.authentication.Context.getCurrentInstance(); - String username = context.getSessionAttribute(CCConstants.AUTH_USERNAME); - String authType = context.getAuthType(); - if(person.equals("-me-") || person.equals(username)) { - if(authType != null && !authType.equals(CCConstants.AUTH_TYPE_DEFAULT)) { - response.setEditProfile(false); - }else { - response.setEditProfile(true); + pattern, + global==null ? true : global, + skipCount!=null ? skipCount : 0, + maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, + new SortDefinition(CCConstants.NAMESPACE_CM,sortProperties,sortAscending), + filter + ); + + List result = new ArrayList<>(); + for (String user: search.getData()) { + result.add(new PersonDao(repoDao,user).asPersonSimple(true)); } + UserEntries response = new UserEntries(); + response.setList(result); + response.setPagination(new Pagination(search)); + + + return Response.status(Response.Status.OK).entity(response).build(); + + + } catch (Throwable t) { + return ErrorResponse.createResponse(t); } + } + + + @OPTIONS + @Path("/people/{repository}") + @Hidden + + public Response options01() { + + return Response.status(Response.Status.OK).header("Allow", "OPTIONS, GET").build(); + } + @GET + @Path("/people/{repository}/{person}") + @Operation(summary = "Get the user.", description = "Get the user. (Not all information are feteched for foreign profiles if current user is not an admin)") + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = UserEntry.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + public Response getUser( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + + UserEntry response = new UserEntry(); + response.setPerson(personDao.asPerson()); + + org.edu_sharing.alfresco.repository.server.authentication.Context context = org.edu_sharing.alfresco.repository.server.authentication.Context.getCurrentInstance(); + String username = context.getSessionAttribute(CCConstants.AUTH_USERNAME); + String authType = context.getAuthType(); + if(person.equals("-me-") || person.equals(username)) { + if(authType != null && !authType.equals(CCConstants.AUTH_TYPE_DEFAULT)) { + response.setEditProfile(false); + }else { + response.setEditProfile(true); + } + } + + + return Response.status(Response.Status.OK).entity(response).build(); - return Response.status(Response.Status.OK).entity(response).build(); - - } catch (Throwable t) { - return ErrorResponse.createResponse(t, ErrorResponse.ErrorResponseLogging.relaxed); - } - } + } catch (Throwable t) { + return ErrorResponse.createResponse(t, ErrorResponse.ErrorResponseLogging.relaxed); + } + } @GET @Path("/people/{repository}/{person}/stats") @@ -190,165 +190,165 @@ public Response getUserStats( return ErrorResponse.createResponse(t, ErrorResponse.ErrorResponseLogging.relaxed); } } - @GET - @Path("/people/{repository}/{person}/nodeList/{list}") - @Operation(summary = "Get a specific node list for a user", description = "For guest users, the list will be temporary stored in the current session") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = NodeEntries.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response getNodeList( + @GET + @Path("/people/{repository}/{person}/nodeList/{list}") + @Operation(summary = "Get a specific node list for a user", description = "For guest users, the list will be temporary stored in the current session") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = NodeEntries.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response getNodeList( @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, @Parameter(description = "list name",required=true) @PathParam("list") String list, @Parameter(description = RestConstants.MESSAGE_PROPERTY_FILTER, array = @ArraySchema(schema = @Schema(defaultValue="-all-"))) @QueryParam("propertyFilter") List propertyFilter, - @Parameter(description = RestConstants.MESSAGE_SORT_PROPERTIES) @QueryParam("sortProperties") List sortProperties, - @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, - @Context HttpServletRequest req) { + @Parameter(description = RestConstants.MESSAGE_SORT_PROPERTIES) @QueryParam("sortProperties") List sortProperties, + @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, + @Context HttpServletRequest req) { try{ RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); + PersonDao personDao = PersonDao.getPerson(repoDao, person); SortDefinition sortDefinition = new SortDefinition(sortProperties,sortAscending); - Filter propFilter = new Filter(propertyFilter); - NodeEntries result=new NodeEntries(); - List refList = personDao.getNodeList(list); - if(refList!=null){ - refList=NodeDao.sortApiNodeRefs(repoDao,refList,null,sortDefinition); - result=NodeDao.convertToRest(repoDao,propFilter,refList,0,Integer.MAX_VALUE); - } - return Response.status(Response.Status.OK).entity(result).build(); + Filter propFilter = new Filter(propertyFilter); + NodeEntries result=new NodeEntries(); + List refList = personDao.getNodeList(list); + if(refList!=null){ + refList=NodeDao.sortApiNodeRefs(repoDao,refList,null,sortDefinition); + result=NodeDao.convertToRest(repoDao,propFilter,refList,0,Integer.MAX_VALUE); + } + return Response.status(Response.Status.OK).entity(result).build(); }catch(Throwable t){ return ErrorResponse.createResponse(t); } - } - @PUT - @Path("/people/{repository}/{person}/nodeList/{list}/{node}") - @Operation(summary = "Add a node to node a list of a user", description = "For guest users, the list will be temporary stored in the current session") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response addNodeList( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Parameter(description = "list name. If this list does not exist, it will be created",required=true) @PathParam("list") String list, - @Parameter(description = RestConstants.MESSAGE_NODE_ID,required=true) @PathParam("node") String node, - @Context HttpServletRequest req) { + } + @PUT + @Path("/people/{repository}/{person}/nodeList/{list}/{node}") + @Operation(summary = "Add a node to node a list of a user", description = "For guest users, the list will be temporary stored in the current session") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response addNodeList( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Parameter(description = "list name. If this list does not exist, it will be created",required=true) @PathParam("list") String list, + @Parameter(description = RestConstants.MESSAGE_NODE_ID,required=true) @PathParam("node") String node, + @Context HttpServletRequest req) { try{ RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - personDao.addNodeList(list, node); - return Response.status(Response.Status.OK).build(); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + personDao.addNodeList(list, node); + return Response.status(Response.Status.OK).build(); }catch(Throwable t){ return ErrorResponse.createResponse(t); } - } - @DELETE - @Path("/people/{repository}/{person}/nodeList/{list}/{node}") - @Operation(summary = "Delete a node of a node list of a user", description = "For guest users, the list will be temporary stored in the current session") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response removeNodeList( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Parameter(description = "list name",required=true) @PathParam("list") String list, - @Parameter(description = RestConstants.MESSAGE_NODE_ID,required=true) @PathParam("node") String node, - @Context HttpServletRequest req) { + } + @DELETE + @Path("/people/{repository}/{person}/nodeList/{list}/{node}") + @Operation(summary = "Delete a node of a node list of a user", description = "For guest users, the list will be temporary stored in the current session") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response removeNodeList( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Parameter(description = "list name",required=true) @PathParam("list") String list, + @Parameter(description = RestConstants.MESSAGE_NODE_ID,required=true) @PathParam("node") String node, + @Context HttpServletRequest req) { try{ RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - personDao.removeNodeList(list, node); - return Response.status(Response.Status.OK).build(); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + personDao.removeNodeList(list, node); + return Response.status(Response.Status.OK).build(); }catch(Throwable t){ return ErrorResponse.createResponse(t); } - } - @GET - @Path("/people/{repository}/{person}/preferences") - @Operation(summary = "Get preferences stored for user", description = "Will fail for guest") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Preferences.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response getPreferences( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Context HttpServletRequest req) { + } + @GET + @Path("/people/{repository}/{person}/preferences") + @Operation(summary = "Get preferences stored for user", description = "Will fail for guest") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Preferences.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response getPreferences( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Context HttpServletRequest req) { try{ org.edu_sharing.service.authority.AuthorityService service=AuthorityServiceFactory.getAuthorityService(ApplicationInfoList.getHomeRepository().getAppId()); if(service.isGuest()) throw new Exception("Not allowed for guest user"); RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - String preferences=personDao.getPreferences(); - Preferences pref=new Preferences(); - pref.setPreferences(preferences); - return Response.status(Response.Status.OK).entity(pref).build(); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + String preferences=personDao.getPreferences(); + Preferences pref=new Preferences(); + pref.setPreferences(preferences); + return Response.status(Response.Status.OK).entity(pref).build(); }catch(Throwable t){ return ErrorResponse.createResponse(t); } - } - @PUT - @Path("/people/{repository}/{person}/preferences") - @Operation(summary = "Set preferences for user", description = "Will fail for guest") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response setPreferences( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Parameter(description = "preferences (json string)", required = true, schema = @Schema(defaultValue="-me-" )) String content, - @Context HttpServletRequest req) { + } + @PUT + @Path("/people/{repository}/{person}/preferences") + @Operation(summary = "Set preferences for user", description = "Will fail for guest") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response setPreferences( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Parameter(description = "preferences (json string)", required = true, schema = @Schema(defaultValue="-me-" )) String content, + @Context HttpServletRequest req) { try{ org.edu_sharing.service.authority.AuthorityService service=AuthorityServiceFactory.getAuthorityService(ApplicationInfoList.getHomeRepository().getAppId()); if(service.isGuest()) throw new Exception("Not allowed for guest user"); RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - personDao.setPreferences(content); - return Response.status(Response.Status.OK).build(); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + personDao.setPreferences(content); + return Response.status(Response.Status.OK).build(); }catch(Throwable t){ return ErrorResponse.createResponse(t); } - } + } @GET @Path("/people/{repository}/{person}/profileSettings") @@ -377,168 +377,558 @@ public Response getProfileSettings( ProfileSettings personDaoProfileSettings = personDao.getProfileSettings(); return Response.status(Response.Status.OK).entity(personDaoProfileSettings).build(); } catch (Throwable t) { - return ErrorResponse.createResponse(t); + return ErrorResponse.createResponse(t); + } + } + + + @PUT + @Path("/people/{repository}/{person}/profileSettings") + @Operation(summary = "Set profileSettings Configuration", description = "Will fail for guest") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response setProfileSettings( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-")) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-")) @PathParam("person") String person, + @Parameter(description = "ProfileSetting Object", required = true) ProfileSettings profileSettings, + @Context HttpServletRequest req) { + try { + org.edu_sharing.service.authority.AuthorityService service = AuthorityServiceFactory.getAuthorityService(ApplicationInfoList.getHomeRepository().getAppId()); + if (service.isGuest()) + throw new Exception("Not allowed for guest user"); + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + personDao.setProfileSettings(profileSettings); + return Response.status(Response.Status.OK).build(); + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } + + + + @POST + + @Path("/people/{repository}/{person}") + + @Operation(summary = "Create a new user.", description = "Create a new user. (admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = User.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response createUser( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username",required=true) @PathParam("person") String person, + @Parameter(description = "profile" ,required=true ) UserProfileEdit profile, + @Parameter(description = "Password, leave empty if you don't want to set any" ,required=false )@QueryParam("password") @ValidPassword String password, + @Parameter(description = "returnResult, if true the created person object will be returned.", required=false) @QueryParam("returnResult") @DefaultValue("true") boolean returnResult, + @Parameter(description = "setupHomeDir, if true the created persons homedir will be setup with the default folders.", required=false) @QueryParam("setupHomeDir") @DefaultValue("true") boolean setupHomeDir, + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + if(!setupHomeDir){ + OnUpdatePersonPropertiesPolicy.constructPersonFolders.set(false); + } + PersonDao personDao = PersonDao.createPerson(repoDao, person, password, profile,returnResult); + User result; + if(personDao == null){ + result = new User(); + result.setUserName(person); + }else{ + result = personDao.asPerson(); + } + + return Response.status(Response.Status.OK).entity(result).build(); + + } catch (DAOValidationException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(t)).build(); + + } catch (DAOSecurityException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.FORBIDDEN).entity(new ErrorResponse(t)).build(); + + } catch (DAOMissingException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(t)).build(); + + } catch (Throwable t) { + + logger.error(t.getMessage(), t); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(t)).build(); + }finally { + OnUpdatePersonPropertiesPolicy.constructPersonFolders.set(null); + } + } + + @PUT + @Path("/people/{repository}/{person}/status/{status}") + @Operation(summary = "update the user status.", description = "update the user status. (admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response updateUserStatus( + @Parameter(description = RestConstants.MESSAGE_REPOSITORY_ID, required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username",required=true) @PathParam("person") String person, + @Parameter(description = "the new status to set",required=true) @PathParam("status") PersonLifecycleService.PersonStatus status, + @Parameter(description = "notify the user via mail", required = true, schema = @Schema(defaultValue="true")) @QueryParam("notify") Boolean notifyMail, + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + + personDao.setStatus(status,notifyMail==null ? true : notifyMail); + + return Response.status(Response.Status.OK).build(); + + } catch (DAOValidationException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(t)).build(); + + } catch (DAOSecurityException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.FORBIDDEN).entity(new ErrorResponse(t)).build(); + + } catch (DAOMissingException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(t)).build(); + + } catch (Throwable t) { + + logger.error(t.getMessage(), t); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(t)).build(); + } + } + + @DELETE + + @Path("/people/{repository}/{person}") + + @Operation(summary = "Delete the user.", description = "Delete the user. (admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response deleteUser( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username",required=true) @PathParam("person") String person, + @Parameter(description = "force the deletion (if false then only persons which are previously marked for deletion are getting deleted)", required = false, schema = @Schema(defaultValue="false")) @QueryParam("force") Boolean force, + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + + personDao.delete(force != null && force); + + return Response.status(Response.Status.OK).build(); + + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } + + @OPTIONS + @Path("/people/{repository}/{person}") + @Hidden + + public Response options02() { + + return Response.status(Response.Status.OK).header("Allow", "OPTIONS, GET, POST, DELETE").build(); + } + + @PUT + + @Path("/people/{repository}/{person}/profile") + + @Operation(summary = "Set profile of the user.", description = "Set profile of the user. (To set foreign profiles, admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response changeUserProfile( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Parameter(description = "properties" ,required=true ) UserProfileEdit profile, + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + + personDao.changeProfile(profile); + + return Response.status(Response.Status.OK).build(); + + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } + @PUT + @Path("/people/{repository}/{person}/avatar") + @Operation(summary = "Set avatar of the user.", description = "Set avatar of the user. (To set foreign avatars, admin rights are required.)") + @Consumes({ "multipart/form-data" }) + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response changeUserAvatar( + @Parameter(description = RestConstants.MESSAGE_REPOSITORY_ID, required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Parameter(description = "avatar image" ,required=true ) @FormDataParam("avatar") InputStream avatar, + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + + personDao.changeAvatar(avatar); + + return Response.status(Response.Status.OK).build(); + + } catch (Throwable t) { + + return ErrorResponse.createResponse(t); + } + } + @DELETE + @Path("/people/{repository}/{person}/avatar") + @Operation(summary = "Remove avatar of the user.", description = "Remove avatar of the user. (To Remove foreign avatars, admin rights are required.)") + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response removeUserAvatar( + @Parameter(description = RestConstants.MESSAGE_REPOSITORY_ID, required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Context HttpServletRequest req) { + + try { + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + personDao.removeAvatar(); + return Response.status(Response.Status.OK).build(); + + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } + + @OPTIONS + @Path("/people/{repository}/{person}/profile") + @Hidden + + public Response options03() { + + return Response.status(Response.Status.OK).header("Allow", "OPTIONS, PUT").build(); + } + + @PUT + + @Path("/people/{repository}/{person}/credential") + + @Operation(summary = "Change/Set password of the user.", description = "Change/Set password of the user. (To change foreign passwords or set passwords, admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response changeUserPassword( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, + @Parameter(description = "credential" ,required=true ) @Valid UserCredential credential, + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + PersonDao personDao = PersonDao.getPerson(repoDao, person); + + personDao.changePassword(credential.getOldPassword(), credential.getNewPassword()); + + return Response.status(Response.Status.OK).build(); + + } catch (DAOValidationException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(t)).build(); + + } catch (DAOSecurityException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.FORBIDDEN).entity(new ErrorResponse(t)).build(); + + } catch (DAOMissingException t) { + + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(t)).build(); + + } catch (Throwable t) { + + logger.error(t.getMessage(), t); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(t)).build(); + } + } + + @OPTIONS + @Path("/people/{repository}/{person}/credential") + @Hidden + + public Response options04() { + + return Response.status(Response.Status.OK).header("Allow", "OPTIONS, PUT").build(); + } + + @GET + + @Path("/groups/{repository}") + + @Operation(summary = "Search groups.", description = "Search groups. (admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = GroupEntries.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response searchGroups( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "pattern",required=true) @QueryParam("pattern") String pattern, + @Parameter(description = "find a specific groupType",required=false) @QueryParam("groupType") String groupType, + @Parameter(description = "find a specific signupMethod for groups (or asterisk for all including one)",required=false) @QueryParam("signupMethod") String signupMethod, + @Parameter(description = "global search context, defaults to true, otherwise just searches for groups within the organizations", required = false, schema = @Schema(defaultValue="true")) @QueryParam("global") Boolean global, + @Parameter(description = RestConstants.MESSAGE_MAX_ITEMS, schema = @Schema(defaultValue=""+RestConstants.DEFAULT_MAX_ITEMS)) @QueryParam("maxItems") Integer maxItems, + @Parameter(description = RestConstants.MESSAGE_SKIP_COUNT, schema = @Schema(defaultValue="0")) @QueryParam("skipCount") Integer skipCount, + @Parameter(description = RestConstants.MESSAGE_SORT_PROPERTIES) @QueryParam("sortProperties") List sortProperties, + @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, + @Context HttpServletRequest req) { + + try { + Map props = new HashMap<>(); + if(groupType!=null && !groupType.isEmpty()){ + props.put(CCConstants.getValidLocalName(CCConstants.CCM_PROP_GROUPEXTENSION_GROUPTYPE), groupType); + } + if(signupMethod!=null && !signupMethod.isEmpty()){ + props.put(CCConstants.getValidLocalName(CCConstants.CCM_PROP_GROUP_SIGNUP_METHOD), signupMethod); + } + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + SearchResult search=SearchServiceFactory.getSearchService(repoDao.getId()).findAuthorities( + AuthorityType.GROUP, + pattern, + global==null ? true : global, + skipCount!=null ? skipCount : 0, + maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, + new SortDefinition(sortProperties,sortAscending), + props + ); + + List result = new ArrayList<>(); + for (String group: search.getData()) { + try { + result.add(new GroupDao(repoDao, group).asGroup()); + } catch(DAOMissingException e) { + logger.warn("Group " + group + " as provided by search was not found", e); + Group groupObj = new Group(); + groupObj.setAuthorityName(group); + result.add(groupObj); + } + } + GroupEntries response = new GroupEntries(); + response.setList(result); + response.setPagination(new Pagination(search)); + + return Response.status(Response.Status.OK).entity(response).build(); + + + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } + + + @OPTIONS + @Path("/groups/{repository}") + @Hidden + + public Response options05() { + + return Response.status(Response.Status.OK).header("Allow", "OPTIONS, GET").build(); + } + + @GET + + @Path("/groups/{repository}/{group}") + + @Operation(summary = "Get the group.", description = "Get the group. (To get foreign profiles, admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = GroupEntry.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response getGroup( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "groupname",required=true) @PathParam("group") String group, + @Parameter(description = "resolve the organization(s) this group is part of? disabling will slightly improve performance and should considered for bulk calls",required=false) @QueryParam("resolveOrganizations") Boolean resolveOrganizations, + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + GroupDao groupDao = GroupDao.getGroup(repoDao, group); + + GroupEntry response = new GroupEntry(); + response.setGroup(groupDao.asGroup(resolveOrganizations == null || resolveOrganizations)); + + return Response.status(Response.Status.OK).entity(response).build(); + + } catch (Throwable t) { + return ErrorResponse.createResponse(t, ErrorResponse.ErrorResponseLogging.relaxed); } } + @POST - @PUT - @Path("/people/{repository}/{person}/profileSettings") - @Operation(summary = "Set profileSettings Configuration", description = "Will fail for guest") + @Path("/groups/{repository}/{group}") + + @Operation(summary = "Create a new group.", description = "Create a new group. (admin rights are required.)") @ApiResponses( value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Group.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) - public Response setProfileSettings( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-")) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-")) @PathParam("person") String person, - @Parameter(description = "ProfileSetting Object", required = true) ProfileSettings profileSettings, + public Response createGroup( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "groupname",required=true) @PathParam("group") String group, + @Parameter(description = "parent (will be added to this parent, also for name hashing), may be null",required=false) @QueryParam("parent") String parent, + @Parameter(description = "returnResult, if true the created group object will be returned.", required=false) @QueryParam("returnResult") @DefaultValue("true") Boolean returnResult, + @Parameter(description = "properties" ,required=true ) GroupProfile profile, @Context HttpServletRequest req) { + try { - org.edu_sharing.service.authority.AuthorityService service = AuthorityServiceFactory.getAuthorityService(ApplicationInfoList.getHomeRepository().getAppId()); - if (service.isGuest()) - throw new Exception("Not allowed for guest user"); + RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - personDao.setProfileSettings(profileSettings); - return Response.status(Response.Status.OK).build(); - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } + String groupId = GroupDao.createGroup(repoDao, group, profile,parent); + Group result; + if(returnResult == null || returnResult) { + result = GroupDao.getGroup(repoDao, groupId).asGroup(); + } else { + result = new Group(); + result.setAuthorityName(groupId); + } + return Response.status(Response.Status.OK).entity(result).build(); + } catch (DAOValidationException t) { + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(t)).build(); - @POST + } catch (DAOSecurityException t) { - @Path("/people/{repository}/{person}") - - @Operation(summary = "Create a new user.", description = "Create a new user. (admin rights are required.)") + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.FORBIDDEN).entity(new ErrorResponse(t)).build(); - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = User.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) + } catch (DAOMissingException t) { - public Response createUser( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username",required=true) @PathParam("person") String person, - @Parameter(description = "profile" ,required=true ) UserProfileEdit profile, - @Parameter(description = "Password, leave empty if you don't want to set any" ,required=false )@QueryParam("password") @ValidPassword String password, - @Parameter(description = "returnResult, if true the created person object will be returned.", required=false) @QueryParam("returnResult") @DefaultValue("true") boolean returnResult, - @Parameter(description = "setupHomeDir, if true the created persons homedir will be setup with the default folders.", required=false) @QueryParam("setupHomeDir") @DefaultValue("true") boolean setupHomeDir, - @Context HttpServletRequest req) { + logger.warn(t.getMessage(), t); + return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(t)).build(); - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - if(!setupHomeDir){ - OnUpdatePersonPropertiesPolicy.constructPersonFolders.set(false); - } - PersonDao personDao = PersonDao.createPerson(repoDao, person, password, profile,returnResult); - User result; - if(personDao == null){ - result = new User(); - result.setUserName(person); - }else{ - result = personDao.asPerson(); - } - - return Response.status(Response.Status.OK).entity(result).build(); - - } catch (DAOValidationException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(t)).build(); - - } catch (DAOSecurityException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.FORBIDDEN).entity(new ErrorResponse(t)).build(); - - } catch (DAOMissingException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(t)).build(); - - } catch (Throwable t) { - - logger.error(t.getMessage(), t); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(t)).build(); - }finally { - OnUpdatePersonPropertiesPolicy.constructPersonFolders.set(null); + } catch (Throwable t) { + + logger.error(t.getMessage(), t); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(t)).build(); } - } - - @PUT - @Path("/people/{repository}/{person}/status/{status}") - @Operation(summary = "update the user status.", description = "update the user status. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response updateUserStatus( - @Parameter(description = RestConstants.MESSAGE_REPOSITORY_ID, required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username",required=true) @PathParam("person") String person, - @Parameter(description = "the new status to set",required=true) @PathParam("status") PersonLifecycleService.PersonStatus status, - @Parameter(description = "notify the user via mail", required = true, schema = @Schema(defaultValue="true")) @QueryParam("notify") Boolean notifyMail, - @Context HttpServletRequest req) { - - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - - personDao.setStatus(status,notifyMail==null ? true : notifyMail); - - return Response.status(Response.Status.OK).build(); - - } catch (DAOValidationException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(t)).build(); - - } catch (DAOSecurityException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.FORBIDDEN).entity(new ErrorResponse(t)).build(); - - } catch (DAOMissingException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(t)).build(); - - } catch (Throwable t) { - - logger.error(t.getMessage(), t); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(t)).build(); - } - } + } @DELETE - @Path("/people/{repository}/{person}") + @Path("/groups/{repository}/{group}") - @Operation(summary = "Delete the user.", description = "Delete the user. (admin rights are required.)") + @Operation(summary = "Delete the group.", description = "Delete the group. (admin rights are required.)") @ApiResponses( value = { @@ -550,19 +940,19 @@ public Response updateUserStatus( @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) - public Response deleteUser( + public Response deleteGroup( @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username",required=true) @PathParam("person") String person, - @Parameter(description = "force the deletion (if false then only persons which are previously marked for deletion are getting deleted)", required = false, schema = @Schema(defaultValue="false")) @QueryParam("force") Boolean force, + @Parameter(description = "groupname",required=true) @PathParam("group") String group, @Context HttpServletRequest req) { try { + new MCAlfrescoAPIClient().doInTransaction(()-> { + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + GroupDao groupDao = GroupDao.getGroup(repoDao, group); - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - - personDao.delete(force != null && force); - + groupDao.delete(); + return groupDao; + }); return Response.status(Response.Status.OK).build(); } catch (Throwable t) { @@ -570,420 +960,38 @@ public Response deleteUser( } } - @OPTIONS - @Path("/people/{repository}/{person}") - @Hidden - - public Response options02() { - - return Response.status(Response.Status.OK).header("Allow", "OPTIONS, GET, POST, DELETE").build(); - } - - @PUT - - @Path("/people/{repository}/{person}/profile") - - @Operation(summary = "Set profile of the user.", description = "Set profile of the user. (To set foreign profiles, admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response changeUserProfile( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Parameter(description = "properties" ,required=true ) UserProfileEdit profile, - @Context HttpServletRequest req) { - - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - - personDao.changeProfile(profile); - - return Response.status(Response.Status.OK).build(); - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } - @PUT - @Path("/people/{repository}/{person}/avatar") - @Operation(summary = "Set avatar of the user.", description = "Set avatar of the user. (To set foreign avatars, admin rights are required.)") - @Consumes({ "multipart/form-data" }) + @OPTIONS + @Path("/groups/{repository}/{group}") + @Hidden + + public Response options06() { + + return Response.status(Response.Status.OK).header("Allow", "OPTIONS, GET, POST, DELETE").build(); + } + + @PUT + + @Path("/groups/{repository}/{group}/profile") + + @Operation(summary = "Set profile of the group.", description = "Set profile of the group. (admin rights are required.)") + @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response changeUserAvatar( - @Parameter(description = RestConstants.MESSAGE_REPOSITORY_ID, required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Parameter(description = "avatar image" ,required=true ) @FormDataParam("avatar") InputStream avatar, - @Context HttpServletRequest req) { - - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - - personDao.changeAvatar(avatar); - - return Response.status(Response.Status.OK).build(); - - } catch (Throwable t) { - - return ErrorResponse.createResponse(t); - } - } - @DELETE - @Path("/people/{repository}/{person}/avatar") - @Operation(summary = "Remove avatar of the user.", description = "Remove avatar of the user. (To Remove foreign avatars, admin rights are required.)") - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response removeUserAvatar( - @Parameter(description = RestConstants.MESSAGE_REPOSITORY_ID, required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Context HttpServletRequest req) { - - try { - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - personDao.removeAvatar(); - return Response.status(Response.Status.OK).build(); - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } - - @OPTIONS - @Path("/people/{repository}/{person}/profile") - @Hidden - - public Response options03() { - - return Response.status(Response.Status.OK).header("Allow", "OPTIONS, PUT").build(); - } - - @PUT - - @Path("/people/{repository}/{person}/credential") - - @Operation(summary = "Change/Set password of the user.", description = "Change/Set password of the user. (To change foreign passwords or set passwords, admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response changeUserPassword( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "username (or \"-me-\" for current user)", required = true, schema = @Schema(defaultValue="-me-" )) @PathParam("person") String person, - @Parameter(description = "credential" ,required=true ) @Valid UserCredential credential, - @Context HttpServletRequest req) { - - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - PersonDao personDao = PersonDao.getPerson(repoDao, person); - - personDao.changePassword(credential.getOldPassword(), credential.getNewPassword()); - - return Response.status(Response.Status.OK).build(); - - } catch (DAOValidationException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(t)).build(); - - } catch (DAOSecurityException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.FORBIDDEN).entity(new ErrorResponse(t)).build(); - - } catch (DAOMissingException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(t)).build(); - - } catch (Throwable t) { - - logger.error(t.getMessage(), t); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(t)).build(); - } - } - - @OPTIONS - @Path("/people/{repository}/{person}/credential") - @Hidden - - public Response options04() { - - return Response.status(Response.Status.OK).header("Allow", "OPTIONS, PUT").build(); - } - - @GET - - @Path("/groups/{repository}") - - @Operation(summary = "Search groups.", description = "Search groups. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = GroupEntries.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response searchGroups( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "pattern",required=true) @QueryParam("pattern") String pattern, - @Parameter(description = "find a specific groupType",required=false) @QueryParam("groupType") String groupType, - @Parameter(description = "find a specific signupMethod for groups (or asterisk for all including one)",required=false) @QueryParam("signupMethod") String signupMethod, - @Parameter(description = "global search context, defaults to true, otherwise just searches for groups within the organizations", required = false, schema = @Schema(defaultValue="true")) @QueryParam("global") Boolean global, - @Parameter(description = RestConstants.MESSAGE_MAX_ITEMS, schema = @Schema(defaultValue=""+RestConstants.DEFAULT_MAX_ITEMS)) @QueryParam("maxItems") Integer maxItems, - @Parameter(description = RestConstants.MESSAGE_SKIP_COUNT, schema = @Schema(defaultValue="0")) @QueryParam("skipCount") Integer skipCount, - @Parameter(description = RestConstants.MESSAGE_SORT_PROPERTIES) @QueryParam("sortProperties") List sortProperties, - @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, - @Context HttpServletRequest req) { - - try { - Map props = new HashMap<>(); - if(groupType!=null && !groupType.isEmpty()){ - props.put(CCConstants.getValidLocalName(CCConstants.CCM_PROP_GROUPEXTENSION_GROUPTYPE), groupType); - } - if(signupMethod!=null && !signupMethod.isEmpty()){ - props.put(CCConstants.getValidLocalName(CCConstants.CCM_PROP_GROUP_SIGNUP_METHOD), signupMethod); - } - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - SearchResult search=SearchServiceFactory.getSearchService(repoDao.getId()).findAuthorities( - AuthorityType.GROUP, - pattern, - global==null ? true : global, - skipCount!=null ? skipCount : 0, - maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, - new SortDefinition(sortProperties,sortAscending), - props - ); - - List result = new ArrayList<>(); - for (String group: search.getData()) { - try { - result.add(new GroupDao(repoDao, group).asGroup()); - } catch(DAOMissingException e) { - logger.warn("Group " + group + " as provided by search was not found", e); - Group groupObj = new Group(); - groupObj.setAuthorityName(group); - result.add(groupObj); - } - } - GroupEntries response = new GroupEntries(); - response.setList(result); - response.setPagination(new Pagination(search)); - - return Response.status(Response.Status.OK).entity(response).build(); - - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } - - - @OPTIONS - @Path("/groups/{repository}") - @Hidden - - public Response options05() { - - return Response.status(Response.Status.OK).header("Allow", "OPTIONS, GET").build(); - } - - @GET - - @Path("/groups/{repository}/{group}") - - @Operation(summary = "Get the group.", description = "Get the group. (To get foreign profiles, admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = GroupEntry.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response getGroup( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "groupname",required=true) @PathParam("group") String group, - @Context HttpServletRequest req) { - - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - GroupDao groupDao = GroupDao.getGroup(repoDao, group); - - GroupEntry response = new GroupEntry(); - response.setGroup(groupDao.asGroup()); - - return Response.status(Response.Status.OK).entity(response).build(); - - } catch (Throwable t) { - return ErrorResponse.createResponse(t, ErrorResponse.ErrorResponseLogging.relaxed); - } - } - - @POST - - @Path("/groups/{repository}/{group}") - - @Operation(summary = "Create a new group.", description = "Create a new group. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Group.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response createGroup( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "groupname",required=true) @PathParam("group") String group, - @Parameter(description = "parent (will be added to this parent, also for name hashing), may be null",required=false) @QueryParam("parent") String parent, - @Parameter(description = "properties" ,required=true ) GroupProfile profile, - @Context HttpServletRequest req) { - - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - Group groupResult = GroupDao.createGroup(repoDao, group, profile,parent).asGroup(); - - return Response.status(Response.Status.OK).entity(groupResult).build(); - - } catch (DAOValidationException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(t)).build(); - - } catch (DAOSecurityException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.FORBIDDEN).entity(new ErrorResponse(t)).build(); - - } catch (DAOMissingException t) { - - logger.warn(t.getMessage(), t); - return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(t)).build(); - - } catch (Throwable t) { - - logger.error(t.getMessage(), t); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(t)).build(); - } - } - - @DELETE - - @Path("/groups/{repository}/{group}") - - @Operation(summary = "Delete the group.", description = "Delete the group. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response deleteGroup( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "groupname",required=true) @PathParam("group") String group, - @Context HttpServletRequest req) { - - try { - new MCAlfrescoAPIClient().doInTransaction(()-> { - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - GroupDao groupDao = GroupDao.getGroup(repoDao, group); + value = { + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) - groupDao.delete(); - return groupDao; - }); - return Response.status(Response.Status.OK).build(); - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } - - @OPTIONS - @Path("/groups/{repository}/{group}") - @Hidden - - public Response options06() { - - return Response.status(Response.Status.OK).header("Allow", "OPTIONS, GET, POST, DELETE").build(); - } - - @PUT - - @Path("/groups/{repository}/{group}/profile") - - @Operation(summary = "Set profile of the group.", description = "Set profile of the group. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response changeGroupProfile( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "groupname",required=true ) @PathParam("group") String group, - @Parameter(description = "properties" ,required=true ) GroupProfile profile, - @Context HttpServletRequest req) { - - try { + public Response changeGroupProfile( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "groupname",required=true ) @PathParam("group") String group, + @Parameter(description = "properties" ,required=true ) GroupProfile profile, + @Context HttpServletRequest req) { + + try { new MCAlfrescoAPIClient().doInTransaction(()->{ RepositoryDao repoDao = RepositoryDao.getRepository(repository); GroupDao groupDao = GroupDao.getGroup(repoDao, group); @@ -991,19 +999,19 @@ public Response changeGroupProfile( return groupDao; }); return Response.status(Response.Status.OK).build(); - } catch (Throwable t) { + } catch (Throwable t) { return ErrorResponse.createResponse(t); - } - } + } + } + + @OPTIONS + @Path("/groups/{repository}/{group}/profile") + @Hidden - @OPTIONS - @Path("/groups/{repository}/{group}/profile") - @Hidden + public Response options07() { - public Response options07() { - - return Response.status(Response.Status.OK).header("Allow", "OPTIONS, PUT").build(); - } + return Response.status(Response.Status.OK).header("Allow", "OPTIONS, PUT").build(); + } @POST @Path("/groups/{repository}/{group}/signup/config") @@ -1179,105 +1187,105 @@ public Response rejectSignup( @GET - @Path("/people/{repository}/{person}/memberships") + @Path("/people/{repository}/{person}/memberships") - @Operation(summary = "Get all groups the given user is member of.") + @Operation(summary = "Get all groups the given user is member of.") - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = GroupEntries.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = GroupEntries.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) - public Response getUserGroups( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "authority name",required=true ) @PathParam("person") String person, - @Parameter(description = "pattern",required=false) @QueryParam("pattern") String pattern, - @Parameter(description = RestConstants.MESSAGE_MAX_ITEMS, schema = @Schema(defaultValue=""+RestConstants.DEFAULT_MAX_ITEMS)) @QueryParam("maxItems") Integer maxItems, - @Parameter(description = RestConstants.MESSAGE_SKIP_COUNT, schema = @Schema(defaultValue="0")) @QueryParam("skipCount") Integer skipCount, - @Parameter(description = RestConstants.MESSAGE_SORT_PROPERTIES) @QueryParam("sortProperties") List sortProperties, - @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, + public Response getUserGroups( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "authority name",required=true ) @PathParam("person") String person, + @Parameter(description = "pattern",required=false) @QueryParam("pattern") String pattern, + @Parameter(description = RestConstants.MESSAGE_MAX_ITEMS, schema = @Schema(defaultValue=""+RestConstants.DEFAULT_MAX_ITEMS)) @QueryParam("maxItems") Integer maxItems, + @Parameter(description = RestConstants.MESSAGE_SKIP_COUNT, schema = @Schema(defaultValue="0")) @QueryParam("skipCount") Integer skipCount, + @Parameter(description = RestConstants.MESSAGE_SORT_PROPERTIES) @QueryParam("sortProperties") List sortProperties, + @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, - @Context HttpServletRequest req) { + @Context HttpServletRequest req) { - try { + try { - RepositoryDao repoDao = RepositoryDao.getRepository(repository); + RepositoryDao repoDao = RepositoryDao.getRepository(repository); GroupEntries response = PersonDao.getPerson(repoDao, person).getMemberships( - pattern, - skipCount!=null ? skipCount : 0, - maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, + pattern, + skipCount!=null ? skipCount : 0, + maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, + new SortDefinition(sortProperties,sortAscending) + ); + + return Response.status(Response.Status.OK).entity(response).build(); + + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } + + + @GET + + @Path("/groups/{repository}/{group}/members") + + @Operation(summary = "Get all members of the group.", description = "Get all members of the group. (admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = AuthorityEntries.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response getMembership( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "authority name (begins with GROUP_)",required=true ) @PathParam("group") String group, + @Parameter(description = "pattern",required=false) @QueryParam("pattern") String pattern, + @Parameter(description = "authorityType either GROUP or USER, empty to show all",required=false) @QueryParam("authorityType") String authorityType, + @Parameter(description = RestConstants.MESSAGE_MAX_ITEMS, schema = @Schema(defaultValue=""+RestConstants.DEFAULT_MAX_ITEMS)) @QueryParam("maxItems") Integer maxItems, + @Parameter(description = RestConstants.MESSAGE_SKIP_COUNT, schema = @Schema(defaultValue="0")) @QueryParam("skipCount") Integer skipCount, + @Parameter(description = RestConstants.MESSAGE_SORT_PROPERTIES) @QueryParam("sortProperties") List sortProperties, + @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, + + @Context HttpServletRequest req) { + + try { + + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + GroupDao.getGroup(repoDao, group).checkAdminAccess(); + SearchResult search=SearchServiceFactory.getSearchService(repoDao.getId()).searchGroupMembers( + group, + pattern, + authorityType, + skipCount!=null ? skipCount : 0, + maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, new SortDefinition(sortProperties,sortAscending) ); + AuthorityEntries response = new AuthorityEntries(); + List result = new ArrayList<>(); + for (String member: search.getData()) { + result.add( + member.startsWith(PermissionService.GROUP_PREFIX) ? + new GroupDao(repoDao,member).asGroup() : + new PersonDao(repoDao, member).asPerson()); + } + response.setList(result); + response.setPagination(new Pagination(search)); + return Response.status(Response.Status.OK).entity(response).build(); - return Response.status(Response.Status.OK).entity(response).build(); - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } - - - @GET - - @Path("/groups/{repository}/{group}/members") - - @Operation(summary = "Get all members of the group.", description = "Get all members of the group. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = AuthorityEntries.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response getMembership( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "authority name (begins with GROUP_)",required=true ) @PathParam("group") String group, - @Parameter(description = "pattern",required=false) @QueryParam("pattern") String pattern, - @Parameter(description = "authorityType either GROUP or USER, empty to show all",required=false) @QueryParam("authorityType") String authorityType, - @Parameter(description = RestConstants.MESSAGE_MAX_ITEMS, schema = @Schema(defaultValue=""+RestConstants.DEFAULT_MAX_ITEMS)) @QueryParam("maxItems") Integer maxItems, - @Parameter(description = RestConstants.MESSAGE_SKIP_COUNT, schema = @Schema(defaultValue="0")) @QueryParam("skipCount") Integer skipCount, - @Parameter(description = RestConstants.MESSAGE_SORT_PROPERTIES) @QueryParam("sortProperties") List sortProperties, - @Parameter(description = RestConstants.MESSAGE_SORT_ASCENDING) @QueryParam("sortAscending") List sortAscending, - - @Context HttpServletRequest req) { - - try { - - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - GroupDao.getGroup(repoDao, group).checkAdminAccess(); - SearchResult search=SearchServiceFactory.getSearchService(repoDao.getId()).searchGroupMembers( - group, - pattern, - authorityType, - skipCount!=null ? skipCount : 0, - maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, - new SortDefinition(sortProperties,sortAscending) - ); - AuthorityEntries response = new AuthorityEntries(); - List result = new ArrayList<>(); - for (String member: search.getData()) { - result.add( - member.startsWith(PermissionService.GROUP_PREFIX) ? - new GroupDao(repoDao,member).asGroup() : - new PersonDao(repoDao, member).asPerson()); - } - response.setList(result); - response.setPagination(new Pagination(search)); - return Response.status(Response.Status.OK).entity(response).build(); - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } @GET @@ -1319,113 +1327,113 @@ public Response getSubgroupByType( @PUT - @Path("/groups/{repository}/{group}/members/{member}") - - @Operation(summary = "Add member to the group.", description = "Add member to the group. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="409", description=RestConstants.HTTP_409, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response addMembership( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "groupname",required=true ) @PathParam("group") String group, - @Parameter(description = "authorityName of member",required=true ) @PathParam("member") String member, - @Context HttpServletRequest req) { - - try { + @Path("/groups/{repository}/{group}/members/{member}") + + @Operation(summary = "Add member to the group.", description = "Add member to the group. (admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="409", description=RestConstants.HTTP_409, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response addMembership( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "groupname",required=true ) @PathParam("group") String group, + @Parameter(description = "authorityName of member",required=true ) @PathParam("member") String member, + @Context HttpServletRequest req) { + + try { new MCAlfrescoAPIClient().doInTransaction(()-> { RepositoryDao repoDao = RepositoryDao.getRepository(repository); GroupDao groupDao = GroupDao.getGroup(repoDao, group); groupDao.addMember(member); return groupDao; }); - return Response.status(Response.Status.OK).build(); - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } - - @DELETE - - @Path("/groups/{repository}/{group}/members/{member}") - - @Operation(summary = "Delete member from the group.", description = "Delete member from the group. (admin rights are required.)") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Void.class))), - @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response deleteMembership( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "groupname",required=true ) @PathParam("group") String group, - @Parameter(description = "authorityName of member",required=true ) @PathParam("member") String member, - @Context HttpServletRequest req) { - - try { + return Response.status(Response.Status.OK).build(); + + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } + + @DELETE + + @Path("/groups/{repository}/{group}/members/{member}") + + @Operation(summary = "Delete member from the group.", description = "Delete member from the group. (admin rights are required.)") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description="OK.", content = @Content(schema = @Schema(implementation = Void.class))), + @ApiResponse(responseCode="400", description="Preconditions are not present.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description="Authorization failed.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description="Session user has insufficient rights to perform this operation.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description="Ressources are not found.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description="Fatal error occured.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response deleteMembership( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "groupname",required=true ) @PathParam("group") String group, + @Parameter(description = "authorityName of member",required=true ) @PathParam("member") String member, + @Context HttpServletRequest req) { + + try { new MCAlfrescoAPIClient().doInTransaction(()-> { RepositoryDao repoDao = RepositoryDao.getRepository(repository); GroupDao groupDao = GroupDao.getGroup(repoDao, group); groupDao.deleteMember(member); return groupDao; }); - return Response.status(Response.Status.OK).build(); - } catch (Throwable t) { + return Response.status(Response.Status.OK).build(); + } catch (Throwable t) { return ErrorResponse.createResponse(t); } - } - - @OPTIONS - @Path("/groups/{repository}/{group}/members/{member}") - @Hidden - - public Response options09() { - - return Response.status(Response.Status.OK).header("Allow", "OPTIONS, PUT, DELETE").build(); - } - - - @GET - - @Path("/authorities/{repository}") - - @Operation(summary = "Search authorities.", description = "Search authorities.") - - @ApiResponses( - value = { - @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = AuthorityEntries.class))), - @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - - public Response searchAuthorities( - @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, - @Parameter(description = "pattern",required=true) @QueryParam("pattern") String pattern, - @Parameter(description = "global search context, defaults to true, otherwise just searches for users within the organizations", required = false, schema = @Schema(defaultValue="true")) @QueryParam("global") Boolean global, + } + + @OPTIONS + @Path("/groups/{repository}/{group}/members/{member}") + @Hidden + + public Response options09() { + + return Response.status(Response.Status.OK).header("Allow", "OPTIONS, PUT, DELETE").build(); + } + + + @GET + + @Path("/authorities/{repository}") + + @Operation(summary = "Search authorities.", description = "Search authorities.") + + @ApiResponses( + value = { + @ApiResponse(responseCode="200", description=RestConstants.HTTP_200, content = @Content(schema = @Schema(implementation = AuthorityEntries.class))), + @ApiResponse(responseCode="400", description=RestConstants.HTTP_400, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="401", description=RestConstants.HTTP_401, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="403", description=RestConstants.HTTP_403, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="404", description=RestConstants.HTTP_404, content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode="500", description=RestConstants.HTTP_500, content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + + public Response searchAuthorities( + @Parameter(description = "ID of repository (or \"-home-\" for home repository)", required = true, schema = @Schema(defaultValue="-home-" )) @PathParam("repository") String repository, + @Parameter(description = "pattern",required=true) @QueryParam("pattern") String pattern, + @Parameter(description = "global search context, defaults to true, otherwise just searches for users within the organizations", required = false, schema = @Schema(defaultValue="true")) @QueryParam("global") Boolean global, @Parameter(description = "find a specific groupType (does nothing for persons)",required=false) @QueryParam("groupType") String groupType, @Parameter(description = "find a specific signupMethod for groups (or asterisk for all including one) (does nothing for persons)",required=false) @QueryParam("signupMethod") String signupMethod, @Parameter(description = RestConstants.MESSAGE_MAX_ITEMS, schema = @Schema(defaultValue=""+RestConstants.DEFAULT_MAX_ITEMS)) @QueryParam("maxItems") Integer maxItems, - @Parameter(description = RestConstants.MESSAGE_SKIP_COUNT, schema = @Schema(defaultValue="0")) @QueryParam("skipCount") Integer skipCount, - @Context HttpServletRequest req) { + @Parameter(description = RestConstants.MESSAGE_SKIP_COUNT, schema = @Schema(defaultValue="0")) @QueryParam("skipCount") Integer skipCount, + @Context HttpServletRequest req) { - try { + try { Map props = new HashMap<>(); if(groupType!=null && !groupType.isEmpty()){ props.put(CCConstants.getValidLocalName(CCConstants.CCM_PROP_GROUPEXTENSION_GROUPTYPE), groupType); @@ -1433,34 +1441,34 @@ public Response searchAuthorities( if(signupMethod!=null && !signupMethod.isEmpty()){ props.put(CCConstants.getValidLocalName(CCConstants.CCM_PROP_GROUP_SIGNUP_METHOD), signupMethod); } - RepositoryDao repoDao = RepositoryDao.getRepository(repository); - SearchResult search=SearchServiceFactory.getSearchService(repoDao.getId()).findAuthorities( - null, - pattern, - global==null ? true : global, - skipCount!=null ? skipCount : 0, - maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, - null, - props - - ); - - List result = new ArrayList<>(); - for (String user: search.getData()) { - result.add(getUserOrGroup(repoDao, user)); - } - AuthorityEntries response = new AuthorityEntries(); - response.setList(result); - response.setPagination(new Pagination(search)); - - - return Response.status(Response.Status.OK).entity(response).build(); - - - } catch (Throwable t) { - return ErrorResponse.createResponse(t); - } - } + RepositoryDao repoDao = RepositoryDao.getRepository(repository); + SearchResult search=SearchServiceFactory.getSearchService(repoDao.getId()).findAuthorities( + null, + pattern, + global==null ? true : global, + skipCount!=null ? skipCount : 0, + maxItems!=null ? maxItems : RestConstants.DEFAULT_MAX_ITEMS, + null, + props + + ); + + List result = new ArrayList<>(); + for (String user: search.getData()) { + result.add(getUserOrGroup(repoDao, user)); + } + AuthorityEntries response = new AuthorityEntries(); + response.setList(result); + response.setPagination(new Pagination(search)); + + + return Response.status(Response.Status.OK).entity(response).build(); + + + } catch (Throwable t) { + return ErrorResponse.createResponse(t); + } + } @GET @Path("/authorities/{repository}/recent") diff --git a/Backend/services/core/src/main/java/org/edu_sharing/restservices/mds/v1/model/MdsSort.java b/Backend/services/core/src/main/java/org/edu_sharing/restservices/mds/v1/model/MdsSort.java index 19bdc48113..13c1789c68 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/restservices/mds/v1/model/MdsSort.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/restservices/mds/v1/model/MdsSort.java @@ -33,7 +33,10 @@ public void setSortAscending(boolean sortAscending) { } } private String id; + @JsonProperty(value = "default") private MdsSortDefault defaultValue; + @JsonProperty("defaultSearch") + private MdsSortDefault defaultValueSearch; private List columns; public MdsSort(){} @@ -44,6 +47,11 @@ public MdsSort(MetadataSort sort) { this.defaultValue.setSortBy(sort.getDefaultValue().getSortBy()); this.defaultValue.setSortAscending(sort.getDefaultValue().isSortAscending()); } + if(sort.getDefaultValueSearch()!=null){ + this.defaultValueSearch=new MdsSortDefault(); + this.defaultValueSearch.setSortBy(sort.getDefaultValueSearch().getSortBy()); + this.defaultValueSearch.setSortAscending(sort.getDefaultValueSearch().isSortAscending()); + } if(sort.getColumns()!=null){ columns=new ArrayList<>(); for(MetadataSortColumn column : sort.getColumns()){ @@ -67,14 +75,5 @@ public List getColumns() { public void setColumns(List columns) { this.columns = columns; } - - @JsonProperty("default") - public MdsSortDefault getDefaultValue() { - return defaultValue; - } - - public void setDefaultValue(MdsSortDefault defaultValue) { - this.defaultValue = defaultValue; - } } diff --git a/Backend/services/core/src/main/java/org/edu_sharing/restservices/node/v1/NodeApi.java b/Backend/services/core/src/main/java/org/edu_sharing/restservices/node/v1/NodeApi.java index 2b3711e86f..edb515a808 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/restservices/node/v1/NodeApi.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/restservices/node/v1/NodeApi.java @@ -2286,8 +2286,9 @@ public Response setProperty( try { RepositoryDao repoDao = RepositoryDao.getRepository(repository); - NodeDao nodeDao = NodeDao.getNode(repoDao, node); - nodeDao.setProperty( + NodeDao.setProperty( + repoDao, + node, property, value == null || value.size() != 1? (Serializable) value : value.get(0), keepModifiedDate != null && keepModifiedDate diff --git a/Backend/services/core/src/main/java/org/edu_sharing/service/config/ConfigServiceImpl.java b/Backend/services/core/src/main/java/org/edu_sharing/service/config/ConfigServiceImpl.java index 9fa1fa26ce..4fdec35792 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/service/config/ConfigServiceImpl.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/service/config/ConfigServiceImpl.java @@ -116,12 +116,17 @@ public Context getContext(String domain) throws Exception { @Override public List getAvailableContext() throws Exception { - buildContextCache(); - return contextCache.getKeys() - .stream() - .map(contextCache::get) - .filter(Objects::nonNull) //maybe gets null while we are iterating over - .collect(Collectors.toList()); + return AuthenticationUtil.runAsSystem(() -> { + String eduSharingSystemFolderContext = userEnvironmentTool.getEdu_SharingContextFolder(); + Map> dynamicContextObjects = nodeService.getChildrenPropsByType(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, eduSharingSystemFolderContext, CCConstants.CCM_TYPE_CONTEXT); + return dynamicContextObjects + .values() + .stream() + .map(x -> x.get(CCConstants.CCM_PROP_CONTEXT_CONFIG).toString()) + .map(CheckedFunction.wrap(x -> objectMapper.readValue(x, Context.class), null)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + }); } private void buildContextCache() throws Exception { diff --git a/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceImpl.java b/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceImpl.java index dffa6ba788..d25617f5ec 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceImpl.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceImpl.java @@ -34,7 +34,6 @@ import org.edu_sharing.alfrescocontext.gate.AlfAppContextGate; import org.edu_sharing.repository.client.rpc.*; import org.edu_sharing.repository.client.tools.CCConstants; -import org.edu_sharing.repository.server.AuthenticationToolAPI; import org.edu_sharing.repository.server.MCAlfrescoAPIClient; import org.edu_sharing.repository.server.tools.ApplicationInfo; import org.edu_sharing.repository.server.tools.ApplicationInfoList; @@ -57,8 +56,8 @@ import org.springframework.stereotype.Service; import java.io.Serializable; -import java.util.*; import java.util.Collection; +import java.util.*; import java.util.stream.Collectors; import static java.util.stream.Collectors.toList; @@ -87,7 +86,7 @@ public class PermissionServiceImpl implements org.edu_sharing.service.permission AuthorityService authorityService = serviceRegistry.getAuthorityService(); BehaviourFilter policyBehaviourFilter = (BehaviourFilter) applicationContext.getBean("policyBehaviourFilter"); MCAlfrescoAPIClient repoClient = new MCAlfrescoAPIClient(); - private GuestService guestService = applicationContext.getBean(GuestService.class); + private GuestService guestService = applicationContext.getBean(GuestService.class); private PermissionService permissionService; private final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper(); @@ -169,7 +168,7 @@ public void setPermissions(String nodeId, List aces, Boolean inheritPermiss } // flag to remove expired aces from acesNew - if(ace.getTo() != null && ace.getTo() <= now){ + if (ace.getTo() != null && ace.getTo() <= now) { remove = true; } @@ -197,7 +196,7 @@ public void setPermissions(String nodeId, List aces, Boolean inheritPermiss } for (ACE aceOld : acesOld) { - if(!aceOld.isInherited() && activeTimedAces.stream().anyMatch(x-> Objects.equals(x.getPermission(), aceOld.getPermission()) && Objects.equals(x.getAuthority(), aceOld.getAuthority()))){ + if (!aceOld.isInherited() && activeTimedAces.stream().anyMatch(x -> Objects.equals(x.getPermission(), aceOld.getPermission()) && Objects.equals(x.getAuthority(), aceOld.getAuthority()))) { continue; } @@ -309,12 +308,12 @@ public void updateTimedPermissions() { retryingTransactionHelper.doInTransaction(() -> AuthenticationUtil.runAs(() -> { NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, timedPermission.getNode_id()); - if(!nodeService.exists(nodeRef)) { - timedPermissionMapper.delete(timedPermission); - return null; - } try { + if (!nodeService.exists(nodeRef)) { + timedPermissionMapper.delete(timedPermission); + return null; + } addPermissions(timedPermission.getNode_id(), Map.of(timedPermission.getAuthority(), new String[]{timedPermission.getPermission()}), false, null, false, timedPermission.getUser()); if (timedPermission.getTo() == null) { @@ -333,15 +332,19 @@ public void updateTimedPermissions() { for (TimedPermission timedPermission : permissionsToRemove) { retryingTransactionHelper.doInTransaction(() -> AuthenticationUtil.runAs(() -> { - NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, timedPermission.getNode_id()); - if(nodeService.exists(nodeRef)) { - permissionService.deletePermission( - nodeRef, - timedPermission.getAuthority(), - timedPermission.getPermission()); - createNotifyObject(timedPermission.getNode_id(), timedPermission.getUser(), CCConstants.CCM_VALUE_NOTIFY_ACTION_PERMISSION_CHANGE); + try { + NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, timedPermission.getNode_id()); + if (nodeService.exists(nodeRef)) { + permissionService.deletePermission( + nodeRef, + timedPermission.getAuthority(), + timedPermission.getPermission()); + createNotifyObject(timedPermission.getNode_id(), timedPermission.getUser(), CCConstants.CCM_VALUE_NOTIFY_ACTION_PERMISSION_CHANGE); + } + timedPermissionMapper.delete(timedPermission); + } catch (Throwable e) { + log.error(e.getMessage(), e); } - timedPermissionMapper.delete(timedPermission); return null; }, timedPermission.getUser())); } @@ -372,7 +375,7 @@ private void addPermissions(String _nodeId, Map _authPerm, Boo } } - createNotifyObject(_nodeId, user, CCConstants.CCM_VALUE_NOTIFY_ACTION_PERMISSION_ADD); + createNotifyObject(_nodeId, user, CCConstants.CCM_VALUE_NOTIFY_ACTION_PERMISSION_ADD); for (String authority : _authPerm.keySet()) { String[] permissions = _authPerm.get(authority); @@ -584,23 +587,25 @@ private List addCollectionCoordinatorPermission(NodeRef nodeRef, List * @return */ String getAdminAuthority(NodeRef nodeRef) { - String authorityAdministrator = null; - if (isSharedNode(nodeRef.getId())) { - Set allSetPermissions = serviceRegistry.getPermissionService() - .getAllSetPermissions(nodeRef); - for (AccessPermission ap : allSetPermissions) { - NodeRef authorityNodeRef = authorityService.getAuthorityNodeRef(ap.getAuthority()); - if (authorityNodeRef != null) { - String groupType = (String) nodeService.getProperty(authorityNodeRef, - QName.createQName(CCConstants.CCM_PROP_GROUPEXTENSION_GROUPTYPE)); - if (CCConstants.ADMINISTRATORS_GROUP_TYPE.equals(groupType) - && ap.getPermission().equals(PermissionService.COORDINATOR)) { - authorityAdministrator = ap.getAuthority(); + return AuthenticationUtil.runAsSystem(() -> { + String authorityAdministrator = null; + if (isSharedNode(nodeRef.getId())) { + Set allSetPermissions = serviceRegistry.getPermissionService() + .getAllSetPermissions(nodeRef); + for (AccessPermission ap : allSetPermissions) { + NodeRef authorityNodeRef = authorityService.getAuthorityNodeRef(ap.getAuthority()); + if (authorityNodeRef != null) { + String groupType = (String) nodeService.getProperty(authorityNodeRef, + QName.createQName(CCConstants.CCM_PROP_GROUPEXTENSION_GROUPTYPE)); + if (CCConstants.ADMINISTRATORS_GROUP_TYPE.equals(groupType) + && ap.getPermission().equals(PermissionService.COORDINATOR)) { + authorityAdministrator = ap.getAuthority(); + } } } } - } - return authorityAdministrator; + return authorityAdministrator; + }); } private boolean containslocalPerm(List aces, String eduAuthority, String eduPermission) { @@ -725,7 +730,7 @@ public void addPermissions(String nodeId, ACE[] aces) throws Exception { } // flag to remove expired aces from acesNew - if(ace.getTo() != null && ace.getTo() <= now){ + if (ace.getTo() != null && ace.getTo() <= now) { remove = true; } @@ -824,7 +829,7 @@ public void removePermissions(String nodeId, ACE[] aces) throws Exception { if (!isGlobalAdmin && ace.getAuthority().equals(fullyAuthenticatedUser)) { String owner = ownableService.getOwner(nodeRef); - if (!fullyAuthenticatedUser.equals(owner)){ + if (!fullyAuthenticatedUser.equals(owner)) { log.warn("user should not uninvite himself"); continue; } @@ -875,6 +880,7 @@ public void setPermissions(String nodeId, String authority, String[] permissions permissionsService.setInheritParentPermissions(nodeRef, inheritPermission); } + String adminAuthority = getAdminAuthority(nodeRef); if (permissions != null) { @@ -965,7 +971,7 @@ public StringBuffer getFindUsersSearchString(String query, Map s fieldQuery.append(" OR "); } fieldQuery.append("@cm\\:").append(field.getKey()).append(":").append("\"").append(token).append("\""); - if(field.getValue() > 1) { + if (field.getValue() > 1) { fieldQuery.append(" OR "); fieldQuery.append("@cm\\:").append(field.getKey()).append(":").append("\"").append(StringUtils.strip(token, "*")).append("\"^").append(field.getValue()); } @@ -1087,8 +1093,8 @@ private List getOrganizationsOfUser() { } private void filterGuestAuthority(StringBuffer searchQuery) { - for(String guest : guestService.getAllGuestAuthorities()){ - searchQuery.append(" AND NOT @cm\\:userName:\""+ QueryParser.escape(guest)+"\""); + for (String guest : guestService.getAllGuestAuthorities()) { + searchQuery.append(" AND NOT @cm\\:userName:\"" + QueryParser.escape(guest) + "\""); } } @@ -1633,7 +1639,7 @@ public Map hasAllPermissions(String storeProtocol, String store @Override public Map hasAllPermissions(String storeProtocol, String storeId, String nodeId, String[] permissions) { - boolean guest = guestService.isGuestUser(AuthenticationUtil.getFullyAuthenticatedUser()); + boolean guest = guestService.isGuestUser(AuthenticationUtil.getFullyAuthenticatedUser()); PermissionService permissionService = serviceRegistry.getPermissionService(); Map result = new HashMap<>(); NodeRef nodeRef = new NodeRef(new StoreRef(storeProtocol, storeId), nodeId); diff --git a/Backend/services/rest/api/src/main/resources/openapi.json b/Backend/services/rest/api/src/main/resources/openapi.json index 89a076b91a..724e4ebc55 100644 --- a/Backend/services/rest/api/src/main/resources/openapi.json +++ b/Backend/services/rest/api/src/main/resources/openapi.json @@ -2720,6 +2720,9 @@ "default": { "$ref": "#/components/schemas/MdsSortDefault" }, + "defaultSearch": { + "$ref": "#/components/schemas/MdsSortDefault" + }, "id": { "type": "string" } @@ -16602,6 +16605,14 @@ "schema": { "type": "string" } + }, + { + "description": "resolve the organization(s) this group is part of? disabling will slightly improve performance and should considered for bulk calls", + "in": "query", + "name": "resolveOrganizations", + "schema": { + "type": "boolean" + } } ], "responses": { @@ -16701,6 +16712,15 @@ "schema": { "type": "string" } + }, + { + "description": "returnResult, if true the created group object will be returned.", + "in": "query", + "name": "returnResult", + "schema": { + "default": true, + "type": "boolean" + } } ], "requestBody": { diff --git a/Frontend/projects/edu-sharing-ui/src/lib/common/edu-sharing-ui-common.module.ts b/Frontend/projects/edu-sharing-ui/src/lib/common/edu-sharing-ui-common.module.ts index 1b6f933331..e569f5d86b 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/common/edu-sharing-ui-common.module.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/common/edu-sharing-ui-common.module.ts @@ -27,6 +27,7 @@ import { VCardNamePipe } from '../pipes/vcard-name.pipe'; import { SortDropdownComponent } from '../sort-dropdown/sort-dropdown.component'; import { SpinnerComponent } from '../spinner/spinner.component'; import { PropertySlugPipe } from '../pipes/property-slug.pipe'; +import { NodeLicensePipe } from '../pipes/node-license.pipe'; @NgModule({ declarations: [ @@ -43,6 +44,7 @@ import { PropertySlugPipe } from '../pipes/property-slug.pipe'; NodeIconPipe, NodeImagePipe, NodeImageSizePipe, + NodeLicensePipe, NodePersonNamePipe, NodeTitlePipe, NodeUrlComponent, diff --git a/Frontend/projects/edu-sharing-ui/src/lib/dropdown/dropdown.component.ts b/Frontend/projects/edu-sharing-ui/src/lib/dropdown/dropdown.component.ts index 8cc8ad31c4..a5ecccbb8d 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/dropdown/dropdown.component.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/dropdown/dropdown.component.ts @@ -4,6 +4,7 @@ import { OptionItem } from '../types/option-item'; import { Helper } from '../util/helper'; import { UIService } from '../services/ui.service'; import { BehaviorSubject } from 'rxjs'; +import { Node } from 'ngx-edu-sharing-api'; /** * The dropdown is one base component of the action bar (showing more actions), @@ -23,11 +24,11 @@ export class DropdownComponent implements OnChanges { options$ = new BehaviorSubject([]); /** - * The object that should be returned via the option's callback. + * The objects that should be returned via the option's callback. * * Can be null */ - @Input() callbackObject: any; + @Input() callbackObjects: Node[]; /** * Should disabled ("greyed out") options be shown or hidden? @@ -45,10 +46,10 @@ export class DropdownComponent implements OnChanges { constructor(private ui: UIService) {} ngOnChanges(changes?: SimpleChanges): void { - if (changes == null || changes?.options || changes?.callbackObject) { + if (changes == null || changes?.options || changes?.callbackObjects) { this.options$.next(this.ui.filterValidOptions(Helper.deepCopyArray(this.options))); - if (this.callbackObject) { - this.ui.updateOptionEnabledState(this.options$, this.callbackObject); + if (this.callbackObjects) { + this.ui.updateOptionEnabledState(this.options$, this.callbackObjects); } } } @@ -57,7 +58,7 @@ export class DropdownComponent implements OnChanges { if (!option.isEnabled) { return; } - setTimeout(() => option.callback(this.callbackObject)); + setTimeout(() => option.callback(null, this.callbackObjects)); } isNewGroup(i: number) { diff --git a/Frontend/projects/edu-sharing-ui/src/lib/index.ts b/Frontend/projects/edu-sharing-ui/src/lib/index.ts index b3fe0b3dea..95803928b3 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/index.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/index.ts @@ -41,6 +41,7 @@ export * from './pipes/format-date.pipe'; export * from './pipes/node-icon.pipe'; export * from './pipes/node-image-size.pipe'; export * from './pipes/node-image.pipe'; +export * from './pipes/node-license.pipe'; export * from './pipes/node-person-name.pipe'; export * from './pipes/node-title.pipe'; export * from './pipes/vcard-name.pipe'; @@ -52,6 +53,7 @@ export * from './services/accessibility.service'; export * from './services/app-container.service'; export * from './services/local-events.service'; export * from './services/node-helper.service'; +export * from './services/node-entries.service'; export * from './services/nodes-drag-drop.service'; export * from './services/options-helper-data.service'; export * from './services/repo-url.service'; diff --git a/Frontend/projects/edu-sharing-ui/src/lib/node-entries/node-entries-card-small/node-entries-card-small.component.ts b/Frontend/projects/edu-sharing-ui/src/lib/node-entries/node-entries-card-small/node-entries-card-small.component.ts index 75b41b93e7..9be29c05c3 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/node-entries/node-entries-card-small/node-entries-card-small.component.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/node-entries/node-entries-card-small/node-entries-card-small.component.ts @@ -27,10 +27,10 @@ export class NodeEntriesCardSmallComponent implements OnChanges optionsOnCard() { const options = this.entriesService.options[Target.List]; const always = options.filter((o) => o.showAlways); - if (always.some((o) => o.showCallback(this.node))) { + if (always.some((o) => o.showCallback([this.node]))) { return always; } - return options.filter((o) => o.showAsAction && o.showCallback(this.node)).slice(0, 3); + return options.filter((o) => o.showAsAction && o.showCallback([this.node])).slice(0, 3); } openContextmenu(event: MouseEvent | Event) { diff --git a/Frontend/projects/edu-sharing-ui/src/lib/node-entries/node-entries-card/node-entries-card.component.ts b/Frontend/projects/edu-sharing-ui/src/lib/node-entries/node-entries-card/node-entries-card.component.ts index a738b7a6ae..3cd4039011 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/node-entries/node-entries-card/node-entries-card.component.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/node-entries/node-entries-card/node-entries-card.component.ts @@ -64,7 +64,7 @@ export class NodeEntriesCardComponent implements OnChanges, OnIn optionsOnCard() { const options = this.entriesService.options?.[Target.List]; const always = options?.filter((o) => o.showAlways); - if (always?.some((o) => o.showCallback(this.node))) { + if (always?.some((o) => o.showCallback([this.node]))) { return always; } // we do NOT show any additional actions diff --git a/Frontend/projects/edu-sharing-ui/src/lib/node-entries/option-button/option-button.component.ts b/Frontend/projects/edu-sharing-ui/src/lib/node-entries/option-button/option-button.component.ts index 58e090e231..aec6ebc455 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/node-entries/option-button/option-button.component.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/node-entries/option-button/option-button.component.ts @@ -35,14 +35,14 @@ export class OptionButtonComponent implements OnChanges { async optionIsValid(optionItem: OptionItem, node: Node): Promise { if (optionItem.enabledCallback) { - return await optionItem.enabledCallback(node); + return await optionItem.enabledCallback([node]); } return optionItem.isEnabled; } private async optionIsShown(optionItem: OptionItem, node: Node): Promise { if (optionItem.showCallback) { - return optionItem.showCallback(node); + return optionItem.showCallback([node]); } return true; } diff --git a/Frontend/projects/edu-sharing-ui/src/lib/pipes/node-license.pipe.ts b/Frontend/projects/edu-sharing-ui/src/lib/pipes/node-license.pipe.ts new file mode 100644 index 0000000000..e226f0c039 --- /dev/null +++ b/Frontend/projects/edu-sharing-ui/src/lib/pipes/node-license.pipe.ts @@ -0,0 +1,20 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { Node, RestConstants } from 'ngx-edu-sharing-api'; +import { TranslateService } from '@ngx-translate/core'; + +export type LicenseType = 'name'; + +@Pipe({ name: 'esNodeLicense' }) +export class NodeLicensePipe implements PipeTransform { + constructor(private translate: TranslateService) {} + transform(node: Node, args: { type: LicenseType }) { + if (node.properties[RestConstants.CCM_PROP_LICENSE]?.[0]) { + if (args?.type === 'name') { + return this.translate.get( + 'LICENSE.NAMES.' + node.properties[RestConstants.CCM_PROP_LICENSE]?.[0], + ); + } + } + return null; + } +} diff --git a/Frontend/projects/edu-sharing-ui/src/lib/services/node-entries.service.ts b/Frontend/projects/edu-sharing-ui/src/lib/services/node-entries.service.ts index f6a368ce79..b55ac20e4f 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/services/node-entries.service.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/services/node-entries.service.ts @@ -1,6 +1,7 @@ import { SelectionModel } from '@angular/cdk/collections'; import { EventEmitter, Injectable, signal, WritableSignal } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; +import { Node } from 'ngx-edu-sharing-api'; import { ClickSource, FetchEvent, @@ -231,7 +232,7 @@ export class NodeEntriesService { } // Wait for the menu to reflect changed options. setTimeout(() => { - dropdown.callbackObject = node; + dropdown.callbackObjects = this.selection.selected as unknown as Node[]; dropdown.ngOnChanges(); if (dropdown.canShowDropdown()) { if (onDone) { diff --git a/Frontend/projects/edu-sharing-ui/src/lib/services/ui.service.ts b/Frontend/projects/edu-sharing-ui/src/lib/services/ui.service.ts index e2aef05671..a5e92c1f01 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/services/ui.service.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/services/ui.service.ts @@ -13,6 +13,7 @@ import { BehaviorSubject, Observable } from 'rxjs'; import { UIConstants } from '../util/ui-constants'; import { OptionItem } from '../types/option-item'; import { distinctUntilChanged, map } from 'rxjs/operators'; +import { Node } from 'ngx-edu-sharing-api'; @Injectable({ providedIn: 'root' }) export class UIService { @@ -128,13 +129,10 @@ export class UIService { * can be used by dropdown or action menus to update the state for the current element * @param options */ - async updateOptionEnabledState( - options: BehaviorSubject, - object: Node | any = null, - ) { - options.value.forEach((o) => { + async updateOptionEnabledState(options: BehaviorSubject, objects: Node[] = null) { + options.value?.forEach((o) => { o.isEnabled = !o.customEnabledCallback; - o.enabledCallback(object).then((result) => { + o.enabledCallback(objects).then((result) => { o.isEnabled = result; options.next(options.value); }); diff --git a/Frontend/projects/edu-sharing-ui/src/lib/types/option-item.ts b/Frontend/projects/edu-sharing-ui/src/lib/types/option-item.ts index d65f831845..c112b3450a 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/types/option-item.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/types/option-item.ts @@ -6,6 +6,7 @@ */ import { KeyboardShortcutCondition } from '../types/keyboard-shortcuts'; +import { Node } from 'ngx-edu-sharing-api'; export enum NodesRightMode { // rights on the current node, no matter if its a reference or origianl @@ -86,7 +87,7 @@ export class OptionItem { * Is handled by optionsHelper and may not be used otherwise * Please use @customShowCallback instead */ - public showCallback: (node?: Node | any) => Promise; + public showCallback: (nodes?: Node[]) => Promise; /** * A function called with the node as parm which should return true or false if the option should be shown for this node * Will be called by the optionsHelper @@ -97,7 +98,7 @@ export class OptionItem { * Is handled by optionsHelper and may not be used otherwise * Please use @customEnabledCallback instead */ - public enabledCallback: (node?: Node | any) => Promise; + public enabledCallback: (nodes?: Node[]) => Promise; /** * A function called with the node as param which should return true or false if the option should be enabled or not * Will be called by the optionsHelper diff --git a/Frontend/projects/edu-sharing-ui/src/lib/util/VCard.ts b/Frontend/projects/edu-sharing-ui/src/lib/util/VCard.ts index 35ddeda5d4..8617fcdc32 100644 --- a/Frontend/projects/edu-sharing-ui/src/lib/util/VCard.ts +++ b/Frontend/projects/edu-sharing-ui/src/lib/util/VCard.ts @@ -168,7 +168,7 @@ export class VCard { const string = (this.title ?? '') + ' ' + (this.givenname ?? '') + ' ' + (this.surname ?? ''); if (string.trim() === '') { - return this.org || ''; + return this.org || this.get('FN') || ''; } return string; } diff --git a/Frontend/src/app/features/dialogs/dialog-modules/share-dialog/share-dialog.component.ts b/Frontend/src/app/features/dialogs/dialog-modules/share-dialog/share-dialog.component.ts index 030cf931d5..62bb4dc960 100644 --- a/Frontend/src/app/features/dialogs/dialog-modules/share-dialog/share-dialog.component.ts +++ b/Frontend/src/app/features/dialogs/dialog-modules/share-dialog/share-dialog.component.ts @@ -78,6 +78,7 @@ export class ShareDialogComponent implements OnInit, AfterViewInit { 'ReadAll', 'Comment', 'Rate', + 'RateRead', 'Write', 'Delete', 'DeleteChildren', @@ -109,6 +110,7 @@ export class ShareDialogComponent implements OnInit, AfterViewInit { ['Comment', ['Consumer']], ['Feedback', ['Consumer']], ['Rate', ['Consumer']], + ['RateRead', ['Consumer']], ['Embed', ['Consumer']], ['Write', ['Editor']], ['DeleteChildren', ['Delete']], diff --git a/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-authority/mds-editor-widget-authority.component.html b/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-authority/mds-editor-widget-authority.component.html index ba1f51b13d..12cb680021 100644 --- a/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-authority/mds-editor-widget-authority.component.html +++ b/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-authority/mds-editor-widget-authority.component.html @@ -41,4 +41,4 @@ - + diff --git a/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-chips/mds-editor-widget-chips.component.html b/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-chips/mds-editor-widget-chips.component.html index 1a0f8fc3b4..ef3e6f20b5 100644 --- a/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-chips/mds-editor-widget-chips.component.html +++ b/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-chips/mds-editor-widget-chips.component.html @@ -122,4 +122,4 @@ - + diff --git a/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-facet-list/mds-editor-widget-facet-list.component.html b/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-facet-list/mds-editor-widget-facet-list.component.html index f7c2fbae1b..9f2da6e091 100644 --- a/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-facet-list/mds-editor-widget-facet-list.component.html +++ b/Frontend/src/app/features/mds/mds-editor/widgets/mds-editor-widget-facet-list/mds-editor-widget-facet-list.component.html @@ -30,7 +30,7 @@