commit fa4763c17759b7979bc106c5706a8ea297f09343
Author: Andreas Kohlbecker <a.kohlbecker@bgbm.org>
Date:   Mon Jan 14 16:51:49 2019 +0100

    ref #7972 FirstdataInserter adding ROLE_REMOTING to the editor groups

diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/permission/Role.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/permission/Role.java
index fe020e8f4d..8641f9a884 100644
--- a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/permission/Role.java
+++ b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/permission/Role.java
@@ -2,7 +2,6 @@ package eu.etaxonomy.cdm.persistence.hibernate.permission;
 
 import java.util.UUID;
 
-import org.springframework.security.access.vote.RoleVoter;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.util.Assert;
 
@@ -32,6 +31,7 @@ public class Role implements GrantedAuthority, IGrantedAuthorityConverter {
     public final static Role ROLE_PROJECT_MANAGER = new Role(UUID.fromString("9eabd2c6-0590-4a1e-95f5-99cc58b63aa7"), "ROLE_PROJECT_MANAGER");
     public final static Role ROLE_USER_MANAGER = new Role(UUID.fromString("9eabd2c6-0590-4a1e-95f5-99cc58b63aa7"), "ROLE_USER_MANAGER");
     public final static Role ROLE_PUBLISH = new Role(UUID.fromString("9ffa7879-cc67-4592-a14a-b251cccde1a7"), "ROLE_PUBLISH");
+    public final static Role ROLE_REMOTING = new Role(UUID.fromString("be004bf6-0498-48e3-9f06-ff93fc9cdc9a"), "ROLE_REMOTING");
 
     private final UUID uuid;
 
diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/application/FirstDataInserter.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/application/FirstDataInserter.java
index 5f42ab6f18..361b3d23fc 100644
--- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/application/FirstDataInserter.java
+++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/application/FirstDataInserter.java
@@ -181,6 +181,7 @@ public class FirstDataInserter extends AbstractDataInserter {
             logger.info("inserting first data");
             checkAdminUser();
             checkDefaultGroups();
+            assureRole_REMOTING_forEditors();
             checkMetadata();
             firstDataInserted = true;
 
@@ -286,6 +287,29 @@ public class FirstDataInserter extends AbstractDataInserter {
         return admin;
     }
 
+    /**
+     * Assures the {@link Role#ROLE_REMOTING} exists.
+     * <p>
+     * If the role is missing in the db it will be created and added to the Groups <code>Editor</code> and <code>EditorExtendedCreate</code>.
+     * <p>
+     * The role will however not be added to the editor groups in case the role exist but is missing from one of these groups. This allows removal
+     * of the role from the editor groups to withdraw the remote editing permission from editors in general for a project.
+     * <p>
+     * see https://dev.e-taxonomy.eu/redmine/issues/7972
+     */
+    private void assureRole_REMOTING_forEditors(){
+
+        if(!roleExists(Role.ROLE_REMOTING)){
+            GrantedAuthorityImpl roleRemoting = assureRole(Role.ROLE_REMOTING);
+            Group groupEditor = groupService.load(Group.GROUP_EDITOR_UUID);
+            groupEditor.addGrantedAuthority(roleRemoting);
+            groupService.saveOrUpdate(groupEditor);
+            Group groupEditorExtendedCreate = groupService.load(Group.GROUP_EDITOR_EXTENDED_CREATE_UUID);
+            groupEditorExtendedCreate.addGrantedAuthority(roleRemoting);
+            groupService.saveOrUpdate(groupEditorExtendedCreate);
+        }
+    }
+
     private void checkAdminRole(User admin) {
         Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
 
@@ -301,7 +325,7 @@ public class FirstDataInserter extends AbstractDataInserter {
         }
 
         if(!hasRoleAdmin){
-            authorities.add(getRoleAdmin());
+            authorities.add(assureRole(Role.ROLE_ADMIN));
             admin.setGrantedAuthorities(authorities);
             progressMonitor.subTask("Creating Admins Role");
             userService.saveOrUpdate(admin);
@@ -312,12 +336,17 @@ public class FirstDataInserter extends AbstractDataInserter {
     /**
      * @return
      */
-    private GrantedAuthorityImpl getRoleAdmin() {
-        GrantedAuthorityImpl role_admin = grantedAuthorityService.find(Role.ROLE_ADMIN.getUuid());
-        if(role_admin == null){
-            role_admin = Role.ROLE_ADMIN.asNewGrantedAuthority();
+    private GrantedAuthorityImpl assureRole(Role role) {
+        GrantedAuthorityImpl roleLoaded = grantedAuthorityService.find(role.getUuid());
+        if(roleLoaded == null){
+            roleLoaded = grantedAuthorityService.save(role.asNewGrantedAuthority());
         }
-        return role_admin;
+        return roleLoaded;
+    }
+
+    private boolean roleExists(Role role) {
+        GrantedAuthorityImpl roleLoaded = grantedAuthorityService.find(role.getUuid());
+        return roleLoaded != null;
     }
 
     private void createMetadata(){
