From acc67c0f67438b6fd91e6ec6571a1b96f4fdb3c4 Mon Sep 17 00:00:00 2001 From: Francois Prunayre Date: Fri, 24 Jun 2016 16:56:14 +0200 Subject: [PATCH] API / Transfer owner. --- code_quality/findbugs-excludes.xml | 2 +- .../org/fao/geonet/kernel/mef/MEFLib.java | 4 +- .../org/fao/geonet/api/groups/GroupsApi.java | 32 ++- .../api/records/formatters/XsltFormatter.java | 2 +- .../org/fao/geonet/api/users/UsersApi.java | 11 +- .../api/users/transfer/OwnerResponse.java | 64 +++++ .../users/transfer}/OwnershipUtils.java | 15 +- .../api/users/transfer/TransferApi.java | 260 ++++++++++++++++++ .../api/users/transfer/TransferRequest.java | 67 +++++ .../users/transfer/UserGroupsResponse.java | 85 ++++++ .../metadata/PrepareBatchNewOwner.java | 2 +- .../geonet/services/ownership/Editors.java | 2 + .../fao/geonet/services/ownership/Groups.java | 2 +- .../geonet/services/ownership/Transfer.java | 1 + .../fao/geonet/services/user/UserGroups.java | 2 +- .../metadatamanager/EditorService.js | 2 +- .../catalog/js/admin/AdminToolsController.js | 53 ++-- .../resources/catalog/locales/en-admin.json | 2 +- .../admin/tools/transferownership.html | 17 +- 19 files changed, 558 insertions(+), 67 deletions(-) create mode 100644 services/src/main/java/org/fao/geonet/api/users/transfer/OwnerResponse.java rename services/src/main/java/org/fao/geonet/{services/ownership => api/users/transfer}/OwnershipUtils.java (90%) create mode 100644 services/src/main/java/org/fao/geonet/api/users/transfer/TransferApi.java create mode 100644 services/src/main/java/org/fao/geonet/api/users/transfer/TransferRequest.java create mode 100644 services/src/main/java/org/fao/geonet/api/users/transfer/UserGroupsResponse.java diff --git a/code_quality/findbugs-excludes.xml b/code_quality/findbugs-excludes.xml index ef9953ca921..d70dbee39f5 100644 --- a/code_quality/findbugs-excludes.xml +++ b/code_quality/findbugs-excludes.xml @@ -184,7 +184,7 @@ - + diff --git a/core/src/main/java/org/fao/geonet/kernel/mef/MEFLib.java b/core/src/main/java/org/fao/geonet/kernel/mef/MEFLib.java index 0192d42063b..c80d04bcd0e 100644 --- a/core/src/main/java/org/fao/geonet/kernel/mef/MEFLib.java +++ b/core/src/main/java/org/fao/geonet/kernel/mef/MEFLib.java @@ -518,9 +518,9 @@ public String toString() { * MEF file version. * * MEF file is composed of one or more metadata record with extra information managed by - * GeoNetwork. Metadata is in XML format. An information file (info.xml) is used to transfert + * GeoNetwork. Metadata is in XML format. An information file (info.xml) is used to transfer * general informations, categories, privileges and file references information. A public and - * private directories allows data transfert (eg. thumbnails, data upload). + * private directories allows data transfer (eg. thumbnails, data upload). */ public enum Version { /** diff --git a/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java b/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java index 80f4c6bd4a0..6e2f0efed7f 100644 --- a/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java +++ b/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java @@ -185,11 +185,41 @@ public Group getGroup( if (group == null) { throw new ResourceNotFoundException(String.format("Group not found")); } - return group; + } + + + @ApiOperation( + value = "Get group users", + notes = "", + nickname = "getGroupUsers") + @RequestMapping( + value = "/{groupIdentifier}/users", + produces = MediaType.APPLICATION_JSON_VALUE, + method = RequestMethod.GET) + @ResponseStatus(value = HttpStatus.OK) + @PreAuthorize("hasRole('UserAdmin')") + @ResponseBody + public List getGroupUsers( + @ApiParam( + value = "Group identifier" + ) + @PathVariable + Integer groupIdentifier + ) throws Exception { + ApplicationContext applicationContext = ApplicationContextHolder.get(); + GroupRepository groupRepository = applicationContext.getBean(GroupRepository.class); + final Group group = groupRepository.findOne(groupIdentifier); + if (group == null) { + throw new ResourceNotFoundException(String.format("Group not found")); + } + UserRepository userRepository = applicationContext.getBean(UserRepository.class); + return userRepository.findAllUsersInUserGroups( + UserGroupSpecs.hasGroupId(groupIdentifier)); } + @ApiOperation( value = "Update a group", notes = "", diff --git a/services/src/main/java/org/fao/geonet/api/records/formatters/XsltFormatter.java b/services/src/main/java/org/fao/geonet/api/records/formatters/XsltFormatter.java index 35cb3b95ea0..7b6828f7df7 100644 --- a/services/src/main/java/org/fao/geonet/api/records/formatters/XsltFormatter.java +++ b/services/src/main/java/org/fao/geonet/api/records/formatters/XsltFormatter.java @@ -53,7 +53,7 @@ * name of the URL parameter eg.

* * @author Jesse on 10/15/2014. - * @author Francois on 06/01/2015: Add request parameters transfert to XSLT and metadata info. + * @author Francois on 06/01/2015: Add request parameters transfer to XSLT and metadata info. */ @Component public class XsltFormatter implements FormatterImpl { diff --git a/services/src/main/java/org/fao/geonet/api/users/UsersApi.java b/services/src/main/java/org/fao/geonet/api/users/UsersApi.java index ec8d79369d0..82cfcf3326a 100644 --- a/services/src/main/java/org/fao/geonet/api/users/UsersApi.java +++ b/services/src/main/java/org/fao/geonet/api/users/UsersApi.java @@ -28,6 +28,7 @@ import org.fao.geonet.ApplicationContextHolder; import org.fao.geonet.api.API; import org.fao.geonet.api.ApiUtils; +import org.fao.geonet.api.exception.ResourceNotFoundException; import org.fao.geonet.constants.Params; import org.fao.geonet.domain.*; import org.fao.geonet.exceptions.OperationNotAllowedEx; @@ -36,6 +37,7 @@ import org.fao.geonet.repository.specification.UserGroupSpecs; import org.fao.geonet.repository.specification.UserSpecs; import org.fao.geonet.util.PasswordUtil; +import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -270,11 +272,12 @@ public ResponseEntity resetUserPassword( @ApiOperation( value = "Retrieve user groups", - notes = "Retrieve the user groups.", + notes = "", nickname = "retrieveUserGroups") @RequestMapping(value = "/{userIdentifier}/groups", produces = MediaType.APPLICATION_JSON_VALUE, - method = RequestMethod.GET) + method = RequestMethod.GET + ) @ResponseStatus(value = HttpStatus.OK) @PreAuthorize("isAuthenticated()") @ResponseBody @@ -338,7 +341,7 @@ public List retrieveUserGroups( List adminList = userGroupRepository.findGroupIds(where(UserGroupSpecs.hasUserId(Integer.valueOf(myUserId))) .or(UserGroupSpecs.hasUserId(Integer.valueOf(userIdentifier)))); if (adminList.isEmpty()) { - throw new OperationNotAllowedEx("You don't have rights to do this because the user you want is not part of your group"); + throw new SecurityException("You don't have rights to do this because the user you want is not part of your group"); } } @@ -348,7 +351,7 @@ public List retrieveUserGroups( return userGroups; } else { - throw new IllegalArgumentException("You don't have rights to do get the groups for this user"); + throw new SecurityException("You don't have rights to do get the groups for this user"); } } diff --git a/services/src/main/java/org/fao/geonet/api/users/transfer/OwnerResponse.java b/services/src/main/java/org/fao/geonet/api/users/transfer/OwnerResponse.java new file mode 100644 index 00000000000..016f3c37172 --- /dev/null +++ b/services/src/main/java/org/fao/geonet/api/users/transfer/OwnerResponse.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ + +package org.fao.geonet.api.users.transfer; + +import org.fao.geonet.domain.User; + +public class OwnerResponse { + int id; + String name; + int records; + + public OwnerResponse(User u, int size) { + this.id = u.getId(); + this.name = String.format("%s %s (%s)", + u.getName(), u.getSurname(), u.getUsername() + ); + this.records = size; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getRecords() { + return records; + } + + public void setRecords(int records) { + this.records = records; + } +} diff --git a/services/src/main/java/org/fao/geonet/services/ownership/OwnershipUtils.java b/services/src/main/java/org/fao/geonet/api/users/transfer/OwnershipUtils.java similarity index 90% rename from services/src/main/java/org/fao/geonet/services/ownership/OwnershipUtils.java rename to services/src/main/java/org/fao/geonet/api/users/transfer/OwnershipUtils.java index 762f2c70721..fdca765d68a 100644 --- a/services/src/main/java/org/fao/geonet/services/ownership/OwnershipUtils.java +++ b/services/src/main/java/org/fao/geonet/api/users/transfer/OwnershipUtils.java @@ -21,7 +21,7 @@ //=== Rome - Italy. email: geonetwork@osgeo.org //============================================================================== -package org.fao.geonet.services.ownership; +package org.fao.geonet.api.users.transfer; import com.google.common.base.Function; import com.google.common.collect.Lists; @@ -29,6 +29,7 @@ import jeeves.server.UserSession; import jeeves.server.context.ServiceContext; +import org.fao.geonet.ApplicationContextHolder; import org.fao.geonet.domain.Profile; import org.fao.geonet.domain.User; import org.fao.geonet.domain.UserGroup; @@ -68,6 +69,7 @@ public static List getEditorUsers(ServiceContext context, UserSession u return getUsers(context, us, users); } + @Deprecated public static List getUsers(ServiceContext context, UserSession us, List users) throws SQLException { int id = us.getUserIdAsInt(); @@ -110,13 +112,7 @@ public Element apply(@Nonnull User input) { return newList; } - //-------------------------------------------------------------------------- - //--- - //--- Private methods - //--- - //-------------------------------------------------------------------------- - - private static Set getUserGroups(ServiceContext context, int id) throws SQLException { + protected static Set getUserGroups(ServiceContext context, int id) throws SQLException { HashSet groupIds = new HashSet(); final List users = context.getBean(UserGroupRepository.class).findAll(UserGroupSpecs.hasUserId(id)); @@ -127,6 +123,3 @@ private static Set getUserGroups(ServiceContext context, int id) throws return groupIds; } } - -//============================================================================= - diff --git a/services/src/main/java/org/fao/geonet/api/users/transfer/TransferApi.java b/services/src/main/java/org/fao/geonet/api/users/transfer/TransferApi.java new file mode 100644 index 00000000000..f00284774df --- /dev/null +++ b/services/src/main/java/org/fao/geonet/api/users/transfer/TransferApi.java @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ + +package org.fao.geonet.api.users.transfer; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import jeeves.server.UserSession; +import jeeves.server.context.ServiceContext; +import org.fao.geonet.ApplicationContextHolder; +import org.fao.geonet.api.API; +import org.fao.geonet.api.ApiUtils; +import org.fao.geonet.domain.*; +import org.fao.geonet.kernel.DataManager; +import org.fao.geonet.repository.MetadataRepository; +import org.fao.geonet.repository.OperationAllowedRepository; +import org.fao.geonet.repository.UserGroupRepository; +import org.fao.geonet.repository.UserRepository; +import org.fao.geonet.repository.specification.MetadataSpecs; +import org.springframework.context.ApplicationContext; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.sql.SQLException; +import java.util.*; + +import static org.fao.geonet.repository.specification.OperationAllowedSpecs.hasGroupId; + +@RequestMapping(value = { + "/api/users", + "/api/" + API.VERSION_0_1 + + "/users" +}) +@Api(value = "users", + tags = "users", + description = "User operations") +@Controller("usersTransfer") +public class TransferApi { + + @ApiOperation( + value = "Get owners", + notes = "Return users who actually owns one or more records.", + nickname = "getOwners") + @RequestMapping( + path = "owners", + produces = MediaType.APPLICATION_JSON_VALUE, + method = RequestMethod.GET + ) + @ResponseStatus(value = HttpStatus.OK) + @PreAuthorize("hasRole('UserAdmin')") + @ResponseBody + public List getUsers( + @ApiIgnore + HttpSession httpSession, + HttpServletRequest request + ) throws Exception { + UserSession us = ApiUtils.getUserSession(httpSession); + ApplicationContext applicationContext = ApplicationContextHolder.get(); + List users = applicationContext.getBean(UserRepository.class).findAll(); + MetadataRepository metadataRepository = applicationContext.getBean(MetadataRepository.class); + + List ownerList = new ArrayList<>(); + for (User u : users) { + List userRecords = metadataRepository.findAll( + MetadataSpecs.hasOwner(u.getId()) + ); + if (userRecords.size() > 0) { + ownerList.add( + new OwnerResponse(u, userRecords.size()) + ); + } + } + return ownerList; + } + + + @ApiOperation( + value = "Retrieve all user groups", + notes = "", + nickname = "retrieveUserGroups") + @RequestMapping( + value = "/groups", + produces = MediaType.APPLICATION_JSON_VALUE, + method = RequestMethod.GET + ) + @ResponseStatus(value = HttpStatus.OK) + @PreAuthorize("isAuthenticated()") + @ResponseBody + public List retrieveAllUserGroups( + @ApiIgnore + HttpSession httpSession + ) throws Exception { + UserSession session = ApiUtils.getUserSession(httpSession); + Profile myProfile = session.getProfile(); + + + ApplicationContext applicationContext = ApplicationContextHolder.get(); + final UserRepository userRepository = applicationContext.getBean(UserRepository.class); + final UserGroupRepository userGroupRepository = applicationContext.getBean(UserGroupRepository.class); + List list = new ArrayList<>(); + if (myProfile == Profile.Administrator || myProfile == Profile.UserAdmin) { + List allAdmin = userRepository.findAllByProfile(Profile.Administrator); + List userGroups = userGroupRepository.findAll(); + for (UserGroup ug : userGroups) { + list.add( + new UserGroupsResponse(ug.getUser(), ug.getGroup(), ug.getProfile().name()) + ); + for (User u : allAdmin) { + list.add( + new UserGroupsResponse(u, ug.getGroup(), Profile.Administrator.name()) + ); + } + } + return list; + } else { + throw new SecurityException("You don't have rights to do get the groups for this user"); + } + } + + @ApiOperation( + value = "Transfer privileges", + notes = "", + nickname = "retrieveUserGroups") + @RequestMapping( + value = "/owners", + produces = MediaType.APPLICATION_JSON_VALUE, + method = RequestMethod.PUT + ) + @PreAuthorize("hasRole('UserAdmin')") + @ResponseBody + public ResponseEntity retrieveAllUserGroups( + @RequestBody + TransferRequest transfer, + @ApiIgnore + HttpSession httpSession, + HttpServletRequest request + ) throws Exception { + ApplicationContext applicationContext = ApplicationContextHolder.get(); + ServiceContext context = ApiUtils.createServiceContext(request); + DataManager dm = applicationContext.getBean(DataManager.class); + final MetadataRepository metadataRepository = applicationContext.getBean(MetadataRepository.class); + + //--- transfer privileges (if case) + + Set sourcePriv = retrievePrivileges( + context, transfer.getSourceUser(), transfer.getSourceGroup()); + Set targetPriv = retrievePrivileges( + context, null, transfer.getTargetGroup()); + + //--- a commit just to release some resources + dm.flush(); + + int privCount = 0; + + Set metadata = new HashSet(); + + if (sourcePriv.size() > 0) { + for (String priv : sourcePriv) { + StringTokenizer st = new StringTokenizer(priv, "|"); + + int opId = Integer.parseInt(st.nextToken()); + int mdId = Integer.parseInt(st.nextToken()); + + // 2 cases could happen, 1) only the owner change + // in that case sourceGrp = targetGrp and operations + // allowed does not need to be modified. + if (transfer.getSourceGroup() != transfer.getTargetGroup()) { + // 2) the sourceGrp != targetGrp and in that + // case, all operations need to be transfered to + // the new group if not already defined. + dm.unsetOperation(context, mdId, transfer.getSourceGroup(), opId); + + if (!targetPriv.contains(priv)) { + OperationAllowedRepository repository = context.getBean(OperationAllowedRepository.class); + OperationAllowedId id = new OperationAllowedId() + .setGroupId(transfer.getTargetGroup()) + .setMetadataId(mdId) + .setOperationId(opId); + OperationAllowed operationAllowed = new OperationAllowed(id); + repository.save(operationAllowed); + } + } + + // Collect all metadata ids + metadata.add(mdId); + privCount++; + } + } + // If no privileges defined for the target group + // assign the new owner and ownerGroup for the source + // user records. + final List sourceUserRecords = + metadataRepository.findAllIdsBy(MetadataSpecs.hasOwner(transfer.getSourceUser())); + metadata.addAll(sourceUserRecords); + + // Set owner for all records to be modified. + for (Integer i : metadata) { + final Metadata metadata1 = metadataRepository.findOne(i); + metadata1.getSourceInfo() + .setGroupOwner(transfer.getTargetGroup()) + .setOwner(transfer.getTargetUser()); + metadataRepository.save(metadata1); + } + + dm.flush(); + + //--- reindex metadata + List list = new ArrayList(); + for (int mdId : metadata) { + list.add(Integer.toString(mdId)); + } + dm.indexMetadata(list); + return new ResponseEntity(HttpStatus.CREATED); + } + + private Set retrievePrivileges(ServiceContext context, Integer userId, int groupId) throws SQLException { + OperationAllowedRepository opAllowedRepo = context.getBean(OperationAllowedRepository.class); + final List opsAllowed; + if (userId == null) { + opsAllowed = opAllowedRepo.findAllById_GroupId(groupId); + } else { + opsAllowed = opAllowedRepo.findAllWithOwner(userId, com.google.common.base.Optional.of(hasGroupId(groupId))); + } + + Set result = new HashSet(); + for (OperationAllowed elem : opsAllowed) { + int opId = elem.getId().getOperationId(); + int mdId = elem.getId().getMetadataId(); + result.add(opId + "|" + mdId); + } + return result; + } +} diff --git a/services/src/main/java/org/fao/geonet/api/users/transfer/TransferRequest.java b/services/src/main/java/org/fao/geonet/api/users/transfer/TransferRequest.java new file mode 100644 index 00000000000..db6ba6b2178 --- /dev/null +++ b/services/src/main/java/org/fao/geonet/api/users/transfer/TransferRequest.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ + +package org.fao.geonet.api.users.transfer; + + +/** + * Created by francois on 24/06/16. + */ +public class TransferRequest { + private int sourceUser; + private int sourceGroup; + private int targetUser; + private int targetGroup; + + public int getSourceUser() { + return sourceUser; + } + + public void setSourceUser(int sourceUser) { + this.sourceUser = sourceUser; + } + + public int getSourceGroup() { + return sourceGroup; + } + + public void setSourceGroup(int sourceGroup) { + this.sourceGroup = sourceGroup; + } + + public int getTargetUser() { + return targetUser; + } + + public void setTargetUser(int targetUser) { + this.targetUser = targetUser; + } + + public int getTargetGroup() { + return targetGroup; + } + + public void setTargetGroup(int targetGroup) { + this.targetGroup = targetGroup; + } +} diff --git a/services/src/main/java/org/fao/geonet/api/users/transfer/UserGroupsResponse.java b/services/src/main/java/org/fao/geonet/api/users/transfer/UserGroupsResponse.java new file mode 100644 index 00000000000..5983bf9f70d --- /dev/null +++ b/services/src/main/java/org/fao/geonet/api/users/transfer/UserGroupsResponse.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ + +package org.fao.geonet.api.users.transfer; + +import org.fao.geonet.domain.Group; +import org.fao.geonet.domain.User; + +public class UserGroupsResponse { + private int userId; + private String userName; + private int groupId; + private String groupName; + private String userProfile; + + public UserGroupsResponse(User u, Group g, String profile) { + this.userId = u.getId(); + this.userName = String.format("%s %s (%s)", + u.getName(), u.getSurname(), u.getUsername() + ); + this.groupId = g.getId(); + this.groupName = g.getName(); + this.userProfile = profile; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public int getGroupId() { + return groupId; + } + + public void setGroupId(int groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getUserProfile() { + return userProfile; + } + + public void setUserProfile(String userProfile) { + this.userProfile = userProfile; + } +} diff --git a/services/src/main/java/org/fao/geonet/services/metadata/PrepareBatchNewOwner.java b/services/src/main/java/org/fao/geonet/services/metadata/PrepareBatchNewOwner.java index b9f8bda2478..d6ee9d9ecca 100644 --- a/services/src/main/java/org/fao/geonet/services/metadata/PrepareBatchNewOwner.java +++ b/services/src/main/java/org/fao/geonet/services/metadata/PrepareBatchNewOwner.java @@ -28,7 +28,7 @@ import jeeves.server.UserSession; import jeeves.server.context.ServiceContext; -import org.fao.geonet.services.ownership.OwnershipUtils; +import org.fao.geonet.api.users.transfer.OwnershipUtils; import org.jdom.Element; import java.nio.file.Path; diff --git a/services/src/main/java/org/fao/geonet/services/ownership/Editors.java b/services/src/main/java/org/fao/geonet/services/ownership/Editors.java index 8c3cbbeda05..59931ab07e4 100644 --- a/services/src/main/java/org/fao/geonet/services/ownership/Editors.java +++ b/services/src/main/java/org/fao/geonet/services/ownership/Editors.java @@ -28,6 +28,7 @@ import jeeves.server.UserSession; import jeeves.server.context.ServiceContext; +import org.fao.geonet.api.users.transfer.OwnershipUtils; import org.jdom.Element; import java.nio.file.Path; @@ -35,6 +36,7 @@ //============================================================================= +@Deprecated public class Editors implements Service { //-------------------------------------------------------------------------- //--- diff --git a/services/src/main/java/org/fao/geonet/services/ownership/Groups.java b/services/src/main/java/org/fao/geonet/services/ownership/Groups.java index abc72f7a870..3d0de76dcd7 100644 --- a/services/src/main/java/org/fao/geonet/services/ownership/Groups.java +++ b/services/src/main/java/org/fao/geonet/services/ownership/Groups.java @@ -54,7 +54,7 @@ import static org.springframework.data.jpa.domain.Specifications.where; //============================================================================= - +@Deprecated public class Groups implements Service { public void init(Path appPath, ServiceConfig params) throws Exception { } diff --git a/services/src/main/java/org/fao/geonet/services/ownership/Transfer.java b/services/src/main/java/org/fao/geonet/services/ownership/Transfer.java index 8e5dc0f9d90..9c061b5a9a9 100644 --- a/services/src/main/java/org/fao/geonet/services/ownership/Transfer.java +++ b/services/src/main/java/org/fao/geonet/services/ownership/Transfer.java @@ -50,6 +50,7 @@ /** * */ +@Deprecated public class Transfer extends NotInReadOnlyModeService { /** * diff --git a/services/src/main/java/org/fao/geonet/services/user/UserGroups.java b/services/src/main/java/org/fao/geonet/services/user/UserGroups.java index dc82ffc9591..a0103b44bf1 100644 --- a/services/src/main/java/org/fao/geonet/services/user/UserGroups.java +++ b/services/src/main/java/org/fao/geonet/services/user/UserGroups.java @@ -54,7 +54,7 @@ /** * Retrieves the groups for a particular user */ - +@Deprecated public class UserGroups implements Service { //-------------------------------------------------------------------------- //--- diff --git a/web-ui/src/main/resources/catalog/components/metadatamanager/EditorService.js b/web-ui/src/main/resources/catalog/components/metadatamanager/EditorService.js index c791c4cc1f4..a22633a1b4d 100644 --- a/web-ui/src/main/resources/catalog/components/metadatamanager/EditorService.js +++ b/web-ui/src/main/resources/catalog/components/metadatamanager/EditorService.js @@ -464,7 +464,7 @@ var switchWithElementCtrl = $(switchWithElement .find(findExp).get(0)).children(); - // For each existing up/down control transfert + // For each existing up/down control transfer // the hidden class between the two elements. angular.forEach(switchWithElementCtrl, function(ctrl, idx) { var ctrl2 = currentElementCtrl[idx]; diff --git a/web-ui/src/main/resources/catalog/js/admin/AdminToolsController.js b/web-ui/src/main/resources/catalog/js/admin/AdminToolsController.js index c5a0b7d87de..3434c44bdfb 100644 --- a/web-ui/src/main/resources/catalog/js/admin/AdminToolsController.js +++ b/web-ui/src/main/resources/catalog/js/admin/AdminToolsController.js @@ -184,39 +184,33 @@ }; function loadEditors() { - $http.get('admin.ownership.editors?_content_type=json') + $http.get('../api/users/owners') .success(function(data) { $scope.editors = data; }); + $http.get('../api/users/groups') + .success(function(data) { + var uniqueUserGroups = {}; + angular.forEach(data, function(g) { + var key = g.groupId + '-' + g.userId; + if (!uniqueUserGroups[key]) { + uniqueUserGroups[key] = g; + } + }); + $scope.userGroups = uniqueUserGroups; + }); } $scope.selectUser = function(id) { $scope.editorSelectedId = id; - $http.get('admin.usergroups.list?_content_type=json&id=' + id) + $http.get('../api/users/' + id + '/groups') .success(function(data) { var uniqueGroup = {}; - angular.forEach(data, function(value) { - if (!uniqueGroup[value.id]) { - uniqueGroup[value.id] = value; + angular.forEach(data, function(g) { + if (!uniqueGroup[g.group.id]) { + uniqueGroup[g.group.id] = g.group; } }); $scope.editorGroups = uniqueGroup; - }).error(function(data) { - }); - - $http.get('admin.ownership.groups?_content_type=json&id=' + id) - .success(function(data) { - // If user does not have group and only one - // target group, a simple object is returned - // and it should be a target group ? FIXME - if (!data.group && !data.targetGroup) { - data.group = data; - data.targetGroup = data; - } - // Make all group and targetGroup arrays. - $scope.groupinfo = { - group: [].concat(data.group), - targetGroup: [].concat(data.targetGroup) - }; }); }; $scope.transfertList = {}; @@ -224,17 +218,12 @@ $scope.tranferOwnership = function(sourceGroup) { var params = $scope.transfertList[sourceGroup]; - // check params.targetGroup.id and params.targetEditor defined - - var xml = '' + $scope.editorSelectedId + - '' + sourceGroup + - '' + params.targetEditor + - '' + params.targetGroup.id + - ''; - params.running = true; - $http.post('admin.ownership.transfer?_content_type=json', xml, { - headers: {'Content-type': 'application/xml'} + $http.put('../api/users/owners', { + sourceUser: parseInt($scope.editorSelectedId), + sourceGroup: parseInt(sourceGroup), + targetUser: params.targetGroup.userId, + targetGroup: params.targetGroup.groupId }).success(function(data) { $rootScope.$broadcast('StatusUpdated', { msg: $translate('transfertPrivilegesFinished', diff --git a/web-ui/src/main/resources/catalog/locales/en-admin.json b/web-ui/src/main/resources/catalog/locales/en-admin.json index 607238139bd..8bee5c8bc46 100644 --- a/web-ui/src/main/resources/catalog/locales/en-admin.json +++ b/web-ui/src/main/resources/catalog/locales/en-admin.json @@ -873,7 +873,7 @@ "Free file handles": "Sufficient free file handles", "Harvesting Errors": "No Harvesting Errors", "targetEditor": "Target editor", - "targetGroup": "Target group", + "targetGroup": "Target group & editor", "testCSW": "CSW test", "testFormatter": "Test formatter", "testProcess": "Test", diff --git a/web-ui/src/main/resources/catalog/templates/admin/tools/transferownership.html b/web-ui/src/main/resources/catalog/templates/admin/tools/transferownership.html index b8e9d521c09..c648ed82081 100644 --- a/web-ui/src/main/resources/catalog/templates/admin/tools/transferownership.html +++ b/web-ui/src/main/resources/catalog/templates/admin/tools/transferownership.html @@ -4,31 +4,28 @@ - - + -
sourceGroup targetGrouptargetEditor
{{g.label[lang]|empty:g.name}}