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 @@