From 27d9c1090da9fa097ec757ea8aee0612d892f48d Mon Sep 17 00:00:00 2001
From: izabel <izabel>
Date: Mon, 29 Sep 2008 10:07:56 +0000
Subject: [PATCH] [LMS-594] check permissions when role assignments are created

SVN: 8491
---
 .../web/client/IGenericClientService.java     | 14 +++-
 .../client/IGenericClientServiceAsync.java    | 16 +++-
 .../client/application/ui/AddRoleDialog.java  | 20 ++++-
 .../web/client/application/ui/RolesView.java  | 16 +++-
 .../web/server/GenericClientService.java      | 42 ++++++++++-
 .../server/GenericClientServiceServlet.java   | 19 ++++-
 .../openbis/generic/server/GenericServer.java | 74 +++++++++++++++----
 .../generic/server/GenericServerLogger.java   | 25 +++++--
 .../server/dataaccess/IRoleAssignmentDAO.java |  7 +-
 .../dataaccess/db/RoleAssignmentDAO.java      | 45 ++++++-----
 .../generic/shared/IGenericServer.java        | 27 ++++++-
 11 files changed, 243 insertions(+), 62 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/IGenericClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/IGenericClientService.java
index 5f5686d90fb..7d4aef75e12 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/IGenericClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/IGenericClientService.java
@@ -84,12 +84,22 @@ public interface IGenericClientService extends RemoteService
     /**
      * Registers a new role from given role set code, group code and person code
      */
-    public void registerRole(String roleSetCode, String group, String person)
+    public void registerGroupRole(String roleSetCode, String group, String person)
             throws UserFailureException;
 
     /**
      * Deletes the role described by given role set code, group code and person code
      */
-    public void deleteRole(String roleSetCode, String group, String person)
+    public void deleteGroupRole(String roleSetCode, String group, String person)
             throws UserFailureException;
+
+    /**
+     * Registers a new role from given role set code and person code
+     */
+    public void registerInstanceRole(String roleSetCode, String person) throws UserFailureException;
+
+    /**
+     * Deletes the role described by given role set code and person code
+     */
+    public void deleteInstanceRole(String roleSetCode, String person) throws UserFailureException;
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/IGenericClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/IGenericClientServiceAsync.java
index 965d672c362..7f78348bf8c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/IGenericClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/IGenericClientServiceAsync.java
@@ -61,12 +61,20 @@ public interface IGenericClientServiceAsync
     /** @see IGenericClientService#listRoles() */
     public void listRoles(AsyncCallback<List<RoleAssignment>> asyncCallback);
 
-    /** @see IGenericClientService#registerRole(String, String, String) */
-    public void registerRole(String roleSetCode, String group, String person,
+    /** @see IGenericClientService#registerGroupRole(String, String, String) */
+    public void registerGroupRole(String roleSetCode, String group, String person,
             AsyncCallback<Void> asyncCallback);
 
-    /** @see IGenericClientService#deleteRole(String, String, String) */
-    public void deleteRole(String roleSetCode, String group, String person,
+    /** @see IGenericClientService#deleteGroupRole(String, String, String) */
+    public void deleteGroupRole(String roleSetCode, String group, String person,
+            AsyncCallback<Void> asyncCallback);
+
+    /** @see IGenericClientService#registerInstanceRole(String, String) */
+    public void registerInstanceRole(String roleSetCode, String person,
+            AsyncCallback<Void> asyncCallback);
+
+    /** @see IGenericClientService#deleteInstanceRole(String, String) */
+    public void deleteInstanceRole(String roleSetCode, String person,
             AsyncCallback<Void> asyncCallback);
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AddRoleDialog.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AddRoleDialog.java
index 3fb668ce1f9..f4c6a83bca8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AddRoleDialog.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AddRoleDialog.java
@@ -26,6 +26,7 @@ import com.extjs.gxt.ui.client.widget.form.TextField;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.StringUtils;
 
 /**
  * {@link Window} containing role registration form.
@@ -69,16 +70,27 @@ public class AddRoleDialog extends Window
                 @Override
                 public void componentSelected(ComponentEvent ce)
                 {
-                    viewContext.getService().registerRole(
-                            ((RoleListBox) roleBox.getWidget()).getValue(), group.getValue(),
-                            user.getValue(), new AbstractAsyncCallback<Void>(viewContext)
+                    final AbstractAsyncCallback<Void> roleLoadingCallback =
+                            new AbstractAsyncCallback<Void>(viewContext)
                                 {
                                     public void onSuccess(Void result)
                                     {
                                         hide();
                                         roleList.refresh();
                                     }
-                                });
+                                };
+                    if (StringUtils.isBlank(group.getValue()))
+                    {
+                        viewContext.getService().registerInstanceRole(
+                                ((RoleListBox) roleBox.getWidget()).getValue(), user.getValue(),
+                                roleLoadingCallback);
+                    } else
+                    {
+
+                        viewContext.getService().registerGroupRole(
+                                ((RoleListBox) roleBox.getWidget()).getValue(), group.getValue(),
+                                user.getValue(), roleLoadingCallback);
+                    }
                 }
             }));
         addButton(new Button("Cancel", new SelectionListener<ComponentEvent>()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/RolesView.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/RolesView.java
index 6ce77447833..46c631a744e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/RolesView.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/RolesView.java
@@ -44,6 +44,7 @@ import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.StringUtils;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.RoleAssignment;
 
 /**
@@ -128,15 +129,24 @@ public class RolesView extends LayoutContainer
                 public void componentSelected(ComponentEvent ce)
                 {
                     final RoleModel rm = grid.getSelectionModel().getSelectedItem();
-                    viewContext.getService().deleteRole((String) rm.get("role"),
-                            (String) rm.get("group"), (String) rm.get("person"),
+                    final AbstractAsyncCallback<Void> roleListRefreshCallback =
                             new AbstractAsyncCallback<Void>(viewContext)
                                 {
                                     public void onSuccess(Void result)
                                     {
                                         roleList.refresh();
                                     }
-                                });
+                                };
+                    if (StringUtils.isBlank((String) rm.get("group")))
+                    {
+                        viewContext.getService().deleteInstanceRole((String) rm.get("role"),
+                                (String) rm.get("person"), roleListRefreshCallback);
+                    } else
+                    {
+                        viewContext.getService().deleteGroupRole((String) rm.get("role"),
+                                (String) rm.get("group"), (String) rm.get("person"),
+                                roleListRefreshCallback);
+                    }
                 }
             });
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientService.java
index ef1b3da5695..86b50c28f15 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientService.java
@@ -47,6 +47,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * @author Franz-Josef Elmer
@@ -265,13 +266,29 @@ public class GenericClientService implements IGenericClientService
         }
     }
 
-    public void registerRole(String roleSetCode, String group, String person)
+    public void registerGroupRole(String roleSetCode, String group, String person)
             throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
     {
         try
         {
+            GroupIdentifier groupIdentifier =
+                    new GroupIdentifier(DatabaseInstanceIdentifier.HOME, group);
             String sessionToken = getSessionToken();
-            server.registerRole(sessionToken, translateRoleSetCode(roleSetCode), group, person);
+            server.registerGroupRole(sessionToken, translateRoleSetCode(roleSetCode),
+                    groupIdentifier, person);
+        } catch (UserFailureException e)
+        {
+            throw UserFailureExceptionTranslater.translate(e);
+        }
+    }
+
+    public void registerInstanceRole(String roleSetCode, String person)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        try
+        {
+            String sessionToken = getSessionToken();
+            server.registerInstanceRole(sessionToken, translateRoleSetCode(roleSetCode), person);
         } catch (UserFailureException e)
         {
             throw UserFailureExceptionTranslater.translate(e);
@@ -300,13 +317,30 @@ public class GenericClientService implements IGenericClientService
 
     }
 
-    public void deleteRole(String roleSetCode, String group, String person)
+    public void deleteGroupRole(String roleSetCode, String group, String person)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        try
+        {
+            GroupIdentifier groupIdentifier =
+                    new GroupIdentifier(DatabaseInstanceIdentifier.HOME, group);
+            String sessionToken = getSessionToken();
+            server.deleteGroupRole(sessionToken, translateRoleSetCode(roleSetCode),
+                    groupIdentifier, person);
+        } catch (UserFailureException e)
+        {
+            throw UserFailureExceptionTranslater.translate(e);
+        }
+
+    }
+
+    public void deleteInstanceRole(String roleSetCode, String person)
             throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
     {
         try
         {
             String sessionToken = getSessionToken();
-            server.deleteRole(sessionToken, translateRoleSetCode(roleSetCode), group, person);
+            server.deleteInstanceRole(sessionToken, translateRoleSetCode(roleSetCode), person);
         } catch (UserFailureException e)
         {
             throw UserFailureExceptionTranslater.translate(e);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientServiceServlet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientServiceServlet.java
index e00503e02e6..bb4f2cd9927 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientServiceServlet.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientServiceServlet.java
@@ -144,16 +144,27 @@ public class GenericClientServiceServlet extends GWTSpringController implements
         return service.listRoles();
     }
 
-    public void registerRole(String roleSetCode, String group, String person)
+    public void registerGroupRole(String roleSetCode, String group, String person)
             throws UserFailureException
     {
-        service.registerRole(roleSetCode, group, person);
+        service.registerGroupRole(roleSetCode, group, person);
     }
 
-    public void deleteRole(String roleSetCode, String group, String person)
+    public void deleteGroupRole(String roleSetCode, String group, String person)
             throws UserFailureException
     {
-        service.deleteRole(roleSetCode, group, person);
+        service.deleteGroupRole(roleSetCode, group, person);
+
+    }
+
+    public void registerInstanceRole(String roleSetCode, String person) throws UserFailureException
+    {
+        service.registerInstanceRole(roleSetCode, person);
+    }
+
+    public void deleteInstanceRole(String roleSetCode, String person) throws UserFailureException
+    {
+        service.deleteInstanceRole(roleSetCode, person);
 
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java
index bac7fdc18b5..f601f2f1fbd 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java
@@ -222,21 +222,31 @@ public class GenericServer implements IGenericServer, ISessionProvider,
     }
 
     @Transactional
-    public void registerRole(String sessionToken, RoleCode roleCode, String group, String person)
+    public void registerGroupRole(String sessionToken, RoleCode roleCode,
+            GroupIdentifier groupIdentifier, String person)
     {
         Session session = sessionManager.getSession(sessionToken);
 
         NewRoleAssignment newRoleAssignment = new NewRoleAssignment();
         newRoleAssignment.setUserId(person);
-        if (group == null)
-        {
-            newRoleAssignment.setDatabaseInstanceIdentifier(new DatabaseInstanceIdentifier(
-                    daoFactory.getHomeDatabaseInstance().getCode()));
-        } else
-        {
-            newRoleAssignment.setGroupIdentifier(new GroupIdentifier(
-                    DatabaseInstanceIdentifier.HOME, group));
-        }
+        newRoleAssignment.setGroupIdentifier(groupIdentifier);
+        newRoleAssignment.setRole(roleCode);
+
+        final IRoleAssignmentTable table = boFactory.createRoleAssignmentTable(session);
+        table.add(newRoleAssignment);
+        table.save();
+
+    }
+
+    @Transactional
+    public void registerInstanceRole(String sessionToken, RoleCode roleCode, String person)
+    {
+        Session session = sessionManager.getSession(sessionToken);
+
+        NewRoleAssignment newRoleAssignment = new NewRoleAssignment();
+        newRoleAssignment.setUserId(person);
+        newRoleAssignment.setDatabaseInstanceIdentifier(new DatabaseInstanceIdentifier(
+                DatabaseInstanceIdentifier.HOME));
         newRoleAssignment.setRole(roleCode);
 
         final IRoleAssignmentTable table = boFactory.createRoleAssignmentTable(session);
@@ -246,13 +256,51 @@ public class GenericServer implements IGenericServer, ISessionProvider,
     }
 
     @Transactional
-    public void deleteRole(String sessionToken, RoleCode roleCode, String group, String person)
+    public void deleteGroupRole(String sessionToken, RoleCode roleCode,
+            GroupIdentifier groupIdentifier, String person)
+    {
+
+        Session session = sessionManager.getSession(sessionToken);
+
+        RoleAssignmentPE roleAssignment =
+                daoFactory.getRoleAssignmentDAO().tryFindGroupRoleAssignment(roleCode,
+                        groupIdentifier.getGroupCode(), person);
+        if (roleAssignment == null)
+        {
+            throw new UserFailureException("Given role does not exist.");
+        }
+        if (roleAssignment.getPerson().compareTo(session.tryGetPerson()) == 0
+                && roleAssignment.getRole().compareTo(RoleCode.ADMIN) == 0)
+        {
+            boolean isInstanceAdmin = false;
+            if (session != null && session.tryGetPerson() != null
+                    && session.tryGetPerson().getRoleAssignments() != null)
+            {
+                for (RoleAssignmentPE ra : session.tryGetPerson().getRoleAssignments())
+                {
+                    if (ra.getDatabaseInstance() != null && ra.getRole().equals(RoleCode.ADMIN))
+                    {
+                        isInstanceAdmin = true;
+                    }
+                }
+            }
+            if (isInstanceAdmin == false)
+            {
+                throw new UserFailureException(
+                        "For safety reason you cannot give away your own group admin power. Ask instance admin to do that for you.");
+            }
+        }
+        daoFactory.getRoleAssignmentDAO().deleteRoleAssignment(roleAssignment);
+    }
+
+    @Transactional
+    public void deleteInstanceRole(String sessionToken, RoleCode roleCode, String person)
     {
 
         Session session = sessionManager.getSession(sessionToken);
 
         RoleAssignmentPE roleAssignment =
-                daoFactory.getRoleAssignmentDAO().tryFindRoleAssignment(roleCode, group, person);
+                daoFactory.getRoleAssignmentDAO().tryFindInstanceRoleAssignment(roleCode, person);
         if (roleAssignment == null)
         {
             throw new UserFailureException("Given role does not exist.");
@@ -262,7 +310,7 @@ public class GenericServer implements IGenericServer, ISessionProvider,
                 && roleAssignment.getDatabaseInstance() != null)
         {
             throw new UserFailureException(
-                    "For safety reason you cannot give away your own omnipotence.");
+                    "For safety reason you cannot give away your own omnipotence. Ask another instance admin to do that for you.");
         }
         daoFactory.getRoleAssignmentDAO().deleteRoleAssignment(roleAssignment);
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java
index 4451f6dd8a3..f1eecee1bab 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java
@@ -32,6 +32,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * Logger class for {@link GenericServer} which creates readable logs of method invocations.
@@ -176,17 +177,31 @@ class GenericServerLogger implements IGenericServer, ISessionProvider
         return null;
     }
 
-    public void registerRole(String sessionToken, RoleCode roleCode, String group, String person)
+    public void registerGroupRole(String sessionToken, RoleCode roleCode,
+            GroupIdentifier groupIdentifier, String person)
     {
         logTracking(sessionToken, "register_role", "ROLE(%s) GROUP(%s) PERSON(%s)", roleCode,
-                group, person);
+                groupIdentifier, person);
 
     }
 
-    public void deleteRole(String sessionToken, RoleCode roleCode, String group, String person)
+    public void registerInstanceRole(String sessionToken, RoleCode roleCode, String person)
     {
-        logTracking(sessionToken, "delete_role", "ROLE(%s) GROUP(%s) PERSON(%s)", roleCode, group,
-                person);
+        logTracking(sessionToken, "register_role", "ROLE(%s)  PERSON(%s)", roleCode, person);
+
+    }
+
+    public void deleteGroupRole(String sessionToken, RoleCode roleCode,
+            GroupIdentifier groupIdentifier, String person)
+    {
+        logTracking(sessionToken, "delete_role", "ROLE(%s) GROUP(%s) PERSON(%s)", roleCode,
+                groupIdentifier, person);
+
+    }
+
+    public void deleteInstanceRole(String sessionToken, RoleCode roleCode, String person)
+    {
+        logTracking(sessionToken, "delete_role", "ROLE(%s) PERSON(%s)", roleCode, person);
 
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IRoleAssignmentDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IRoleAssignmentDAO.java
index 8d07e7b4735..3e688f6c386 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IRoleAssignmentDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IRoleAssignmentDAO.java
@@ -58,5 +58,10 @@ public interface IRoleAssignmentDAO
     /**
      * Returns a {@link RoleAssignmentPE} described by given role, group code and person id.
      */
-    public RoleAssignmentPE tryFindRoleAssignment(RoleCode role, String group, String person);
+    public RoleAssignmentPE tryFindGroupRoleAssignment(RoleCode role, String group, String person);
+
+    /**
+     * Returns a {@link RoleAssignmentPE} described by given role and person id.
+     */
+    public RoleAssignmentPE tryFindInstanceRoleAssignment(RoleCode role, String person);
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/RoleAssignmentDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/RoleAssignmentDAO.java
index 34a5f77478c..6d4c1d7f4c8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/RoleAssignmentDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/RoleAssignmentDAO.java
@@ -18,7 +18,6 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess.db;
 
 import java.util.List;
 
-import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.hibernate.SessionFactory;
 import org.hibernate.criterion.Criterion;
@@ -108,32 +107,42 @@ public final class RoleAssignmentDAO extends AbstractDAO implements IRoleAssignm
         }
     }
 
-    public RoleAssignmentPE tryFindRoleAssignment(RoleCode role, String group, String person)
+    public RoleAssignmentPE tryFindGroupRoleAssignment(RoleCode role, String group, String person)
     {
         List<RoleAssignmentPE> roles;
-        if (StringUtils.isBlank(group) == false)
-        {
-            roles =
-                    cast(getHibernateTemplate().find(
-                            String.format("from %s r where r.person.userId = ? and group.code = ? "
-                                    + "and r.role = ?", ENTITY_CLASS.getSimpleName()), new Object[]
-                                { person, group, role }));
-        } else
+        roles =
+                cast(getHibernateTemplate().find(
+                        String.format("from %s r where r.person.userId = ? and group.code = ? "
+                                + "and r.role = ?", ENTITY_CLASS.getSimpleName()), new Object[]
+                            { person, group, role }));
+        final RoleAssignmentPE roleAssignment =
+                tryFindEntity(roles, "role_assignments", role, group, person);
+        if (operationLog.isInfoEnabled())
         {
-            roles =
-                    cast(getHibernateTemplate().find(
-                            String.format("from %s r where r.person.userId = ? "
-                                    + "and r.role = ? and r.databaseInstance = ?", ENTITY_CLASS
-                                    .getSimpleName()), new Object[]
-                                { person, role, getDatabaseInstance() }));
+            operationLog.info(String.format("FIND: group role assignment '%s'.", roleAssignment));
         }
+        return roleAssignment;
+
+    }
+
+    public RoleAssignmentPE tryFindInstanceRoleAssignment(RoleCode role, String person)
+    {
+        List<RoleAssignmentPE> roles;
+        roles =
+                cast(getHibernateTemplate().find(
+                        String.format("from %s r where r.person.userId = ? "
+                                + "and r.role = ? and r.databaseInstance = ?", ENTITY_CLASS
+                                .getSimpleName()), new Object[]
+                            { person, role, getDatabaseInstance() }));
         final RoleAssignmentPE roleAssignment =
-                tryFindEntity(roles, "role_assignments", role, group, person);
+                tryFindEntity(roles, "role_assignments", role, person);
         if (operationLog.isInfoEnabled())
         {
-            operationLog.info(String.format("FIND: role assignment '%s'.", roleAssignment));
+            operationLog
+                    .info(String.format("FIND: instance role assignment '%s'.", roleAssignment));
         }
         return roleAssignment;
 
     }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java
index 6b36a701444..b4025ca05df 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java
@@ -18,9 +18,11 @@ package ch.systemsx.cisd.openbis.generic.shared;
 
 import java.util.List;
 
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RoleSet;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.GroupIdentifierPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.GroupValidator;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
@@ -28,6 +30,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * Definition of the client-server interface.
@@ -86,15 +89,31 @@ public interface IGenericServer
     public List<RoleAssignmentPE> listRoles(String sessionToken);
 
     /**
-     * Registers a new role.
+     * Registers a new group role.
      */
     @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void registerRole(String sessionToken, RoleCode roleCode, String group, String person);
+    public void registerGroupRole(String sessionToken, RoleCode roleCode,
+            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
+            GroupIdentifier identifier, String person);
 
     /**
-     * Deletes role described by given role code, group code and user id.
+     * Registers a new instance role.
+     */
+    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
+    public void registerInstanceRole(String sessionToken, RoleCode roleCode, String person);
+
+    /**
+     * Deletes role described by given role code, group identifier and user id.
      */
     @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void deleteRole(String sessionToken, RoleCode roleCode, String group, String person);
+    public void deleteGroupRole(String sessionToken, RoleCode roleCode,
+            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
+            GroupIdentifier groupIdentifier, String person);
+
+    /**
+     * Deletes role described by given role code and user id.
+     */
+    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
+    public void deleteInstanceRole(String sessionToken, RoleCode roleCode, String person);
 
 }
-- 
GitLab