RolesSourceProvider to enable activities by cdm roles and protecting bulkeditors...
authorAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Wed, 19 Feb 2014 14:52:32 +0000 (14:52 +0000)
committerAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Wed, 19 Feb 2014 14:52:32 +0000 (14:52 +0000)
.gitattributes
eu.etaxonomy.taxeditor.cdmlib/META-INF/MANIFEST.MF
eu.etaxonomy.taxeditor.store/META-INF/MANIFEST.MF
eu.etaxonomy.taxeditor.store/plugin.xml
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/PermissionPropertyTester.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/RolesSourceProvider.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStore.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/LoginManager.java

index 73c2c268a335b6597526721c0a435574c9b2c09c..78ec840337a2937e6b32824da98e20cb6b9ebc40 100644 (file)
@@ -1268,6 +1268,7 @@ eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/wiz
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/wizard/VocabularyTermWizardPage.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/PermissionPropertyTester.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/RequiredPermissions.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/wizard/VocabularyTermWizardPage.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/PermissionPropertyTester.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/RequiredPermissions.java -text
+eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/RolesSourceProvider.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStore.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStoreConnector.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/ContextManager.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStore.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStoreConnector.java -text
 eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/ContextManager.java -text
index 5f8e6447febb90c9ef67eab62f93e32c72658563..abacc9ae796dcde83cb00097b5c0f731ea2a2aa1 100644 (file)
@@ -346,6 +346,7 @@ Export-Package: com.google.api,
  org.springframework.orm.hibernate4,
  org.springframework.security.access,
  org.springframework.security.authentication,
  org.springframework.orm.hibernate4,
  org.springframework.security.access,
  org.springframework.security.authentication,
+ org.springframework.security.authentication.event,
  org.springframework.security.core,
  org.springframework.security.core.context,
  org.springframework.security.core.userdetails,
  org.springframework.security.core,
  org.springframework.security.core.context,
  org.springframework.security.core.userdetails,
index c3b5a4e33d389a3f1c9269e4f71599e9f582b4a0..812b7272748fe8abf12c0727c10198043e524590 100644 (file)
@@ -46,6 +46,7 @@ Export-Package: eu.etaxonomy.cdm,
  eu.etaxonomy.taxeditor.ui.section.supplemental,
  eu.etaxonomy.taxeditor.ui.section.taxon,
  eu.etaxonomy.taxeditor.ui.selection,
  eu.etaxonomy.taxeditor.ui.section.supplemental,
  eu.etaxonomy.taxeditor.ui.section.taxon,
  eu.etaxonomy.taxeditor.ui.selection,
+ eu.etaxonomy.taxeditor.utility,
  eu.etaxonomy.taxeditor.view,
  eu.etaxonomy.taxeditor.view.datasource,
  eu.etaxonomy.taxeditor.view.datasource.handler,
  eu.etaxonomy.taxeditor.view,
  eu.etaxonomy.taxeditor.view.datasource,
  eu.etaxonomy.taxeditor.view.datasource.handler,
index 03fd6d030704ae36747ee6e75745b112b6bad46d..3eeaba994bdfd8eec0d2d23cd438303f34010df5 100644 (file)
       </definition>
       <definition
             id="hasROLE_USER_MANAGER">
       </definition>
       <definition
             id="hasROLE_USER_MANAGER">
-            <test
-                  args="ROLE_USER_MANAGER"
-                  property="eu.etaxonomy.taxeditor.security.permissionTester.hasRole">
-            </test>
+            <with
+               variable="eu.etaxonomy.taxeditor.security.userRoles">
+            <iterate
+                  ifEmpty="false"
+                  operator="or">
+               <or>
+                  <equals
+                        value="ROLE_ADMIN">
+                  </equals>
+                  <equals
+                        value="ROLE_USER_MANAGER">
+                  </equals>
+               </or>
+            </iterate>
+         </with>
+      </definition>
+      <definition
+            id="hasROLE_PROJECT_MANAGER">
+         <with
+               variable="eu.etaxonomy.taxeditor.security.userRoles">
+            <iterate
+                  ifEmpty="false"
+                  operator="or">
+               <or>
+                  <equals
+                        value="ROLE_ADMIN">
+                  </equals>
+                  <equals
+                        value="ROLE_PROJECT_MANAGER">
+                  </equals>
+               </or>
+            </iterate>
+         </with>
       </definition>
 </extension>
 <extension
       </definition>
 </extension>
 <extension
          activityId="eu.etaxonomy.taxeditor.store.activityUserManagement"
          pattern="eu\.etaxonomy\.taxeditor\..*/.*.UserManagement">
    </activityPatternBinding>
          activityId="eu.etaxonomy.taxeditor.store.activityUserManagement"
          pattern="eu\.etaxonomy\.taxeditor\..*/.*.UserManagement">
    </activityPatternBinding>
+   <activityPatternBinding
+         activityId="eu.etaxonomy.taxeditor.store.activityUserManagement"
+         pattern="eu\.etaxonomy\.taxeditor\..*/bulkeditor\.input\.group">
+   </activityPatternBinding>
+   <activity
+         description="ROLE_PROJECT_MANAGER dependent ui contributions"
+         id="eu.etaxonomy.taxeditor.store.activityProjectManagement"
+         name="ProjectManagement">
+      <enabledWhen>
+         <reference
+               definitionId="hasROLE_PROJECT_MANAGER">
+         </reference>
+      </enabledWhen>
+   </activity>
+   <activityPatternBinding
+         activityId="eu.etaxonomy.taxeditor.store.activityProjectManagement"
+         pattern="eu\.etaxonomy\.taxeditor\..*/eu\.etaxonomy\.taxeditor\..*\.definedTerm.*">
+   </activityPatternBinding>
+   <activityPatternBinding
+         activityId="eu.etaxonomy.taxeditor.store.activityProjectManagement"
+         pattern="eu.etaxonomy.taxeditor.bulkeditor/bulkeditor.menus.openmenu"
+         isEqualityPattern="true">
+   </activityPatternBinding>
+</extension>
+<extension
+      point="org.eclipse.ui.services">
+   <sourceProvider
+         provider="eu.etaxonomy.taxeditor.security.RolesSourceProvider">
+      <variable
+            name="eu.etaxonomy.taxeditor.security.userRoles"
+            priorityLevel="workbench">
+      </variable>
+   </sourceProvider>
 </extension>
        
 </plugin>
 </extension>
        
 </plugin>
index e9adcf3073f97ee49c54c39085fb7c5258b2b713..ca9a014dcfc46fde753c814077675ddbefa4ff53 100644 (file)
@@ -1,23 +1,24 @@
 package eu.etaxonomy.taxeditor.security;
 
 package eu.etaxonomy.taxeditor.security;
 
-import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.EnumSet;
-import java.util.Iterator;
 import java.util.List;
 
 import java.util.List;
 
-import javax.management.relation.Role;
-
-import org.apache.commons.lang.StringUtils;
 import org.eclipse.core.expressions.PropertyTester;
 import org.eclipse.jface.viewers.IStructuredSelection;
 
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
 import org.eclipse.core.expressions.PropertyTester;
 import org.eclipse.jface.viewers.IStructuredSelection;
 
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
+import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 
 import eu.etaxonomy.taxeditor.store.CdmStore;
 
+/**
+ * Checks if the currently authenticated user for {@link CdmAuthority} assignments.
+ * 
+ * @author andreas
+ *
+ */
 public class PermissionPropertyTester extends PropertyTester {
        
 public class PermissionPropertyTester extends PropertyTester {
        
-       private static final String HAS_ROLES = "hasRoles";
        private static final String HAS_PERMISSIONS = "hasPermissions";
        
        private static final String CREATE = CRUD.CREATE.toString();
        private static final String HAS_PERMISSIONS = "hasPermissions";
        
        private static final String CREATE = CRUD.CREATE.toString();
@@ -29,29 +30,13 @@ public class PermissionPropertyTester extends PropertyTester {
        public boolean test(Object receiver, String property, Object[] args,
                        Object expectedValue) {
                
        public boolean test(Object receiver, String property, Object[] args,
                        Object expectedValue) {
                
-               
                if(property.equals(HAS_PERMISSIONS)){
                if(property.equals(HAS_PERMISSIONS)){
-                       
                        return checkHasPermission(receiver, args);
                }
                        return checkHasPermission(receiver, args);
                }
-               
-               if(property.equals(HAS_ROLES)){
-                       return checkHasRoles(property, args);
-               }
                        
                return false;
        }
 
                        
                return false;
        }
 
-       private boolean checkHasRoles(String property, Object[] args) {
-                       List<Role> roles = new ArrayList<Role>();
-                       for(int i = 0; i < args.length; i++){
-                               roles.add((Role)args[i]);
-                       }
-//                     return CdmStore.currentAuthentiationHasOneOfRoles(roles.get(0)); // FIXME
-                       return false;
-                       
-       }
-
        private boolean checkHasPermission(Object receiver, Object[] args) {
                EnumSet<CRUD> crudSet = crudSetFromArgs(args);
 
        private boolean checkHasPermission(Object receiver, Object[] args) {
                EnumSet<CRUD> crudSet = crudSetFromArgs(args);
 
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/RolesSourceProvider.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/security/RolesSourceProvider.java
new file mode 100644 (file)
index 0000000..abb44e7
--- /dev/null
@@ -0,0 +1,111 @@
+package eu.etaxonomy.taxeditor.security;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Observable;
+import java.util.Observer;
+
+import org.eclipse.ui.AbstractSourceProvider;
+import org.eclipse.ui.ISources;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+
+import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.store.LoginManager;
+
+/**
+ * Provides the Roles assigned to the currently authenticated principal as the
+ * variable {@code eu.etaxonomy.taxeditor.security.userRoles}
+ * 
+ * @author a.kohlbecker
+ * 
+ */
+public class RolesSourceProvider extends AbstractSourceProvider implements Observer {
+
+       public final static String RIGHTS_VARIABLE = "eu.etaxonomy.taxeditor.security.userRoles";
+       private final static String[] PROVIDED_SOURCE_NAMES = new String[] { RIGHTS_VARIABLE };
+
+       private final static Map<String, List<String>> stateMap = new HashMap<String, List<String>>();
+
+       public RolesSourceProvider() {
+               super();
+               initialize();
+       }
+
+       private void initialize() {
+               CdmStore.getLoginManager().addObserver(this);
+       }
+
+       @Override
+       public void dispose() {
+               CdmStore.getLoginManager().deleteObserver(this);
+       }
+
+       @Override
+       public Map getCurrentState() {
+
+               // SecurityContextHolder.getContext().
+               List<Role> roles = getCurrentAuthenticationsRoles();
+               List<String> rolesStr = new ArrayList<String>(roles.size());
+               for(Role r : roles){
+                       rolesStr.add(r.getAuthority());
+               }
+
+               stateMap.put(RIGHTS_VARIABLE, rolesStr);
+               return stateMap;
+       }
+
+       /*
+        * TODO refactor into User once Role is a model class
+        */
+       private List<Role> getCurrentAuthenticationsRoles() {
+
+               List<Role> roles = new ArrayList<Role>();
+               Authentication authentication = CdmStore.getCurrentAuthentiation();
+               if (authentication == null) {
+                       return roles;
+               }
+
+               Collection<? extends GrantedAuthority> authorities = authentication
+                               .getAuthorities();
+               if (authorities == null) {
+                       return roles;
+               }
+
+               Role role = null;
+               for (GrantedAuthority ga : authorities) {
+                       try {
+                               // check if it is a valid role
+                               role = Role.fromString(ga.getAuthority());
+                               if (role != null) {
+                                       roles.add(role);
+                               }
+                       } catch (Exception e) {
+                               /* IGNORE */
+                       }
+               }
+               return roles;
+
+       }
+
+       public String[] getProvidedSourceNames() {
+               return PROVIDED_SOURCE_NAMES;
+       }
+
+       @Override
+       public void update(Observable o, Object arg) {
+               if(o instanceof LoginManager){
+                       /*
+                        * This triggers an update of the variable state, and will update also
+                        * all listeners to the evaluation service. So that every menu point,
+                        * which is also expression controlled, gets updated too.
+                        */
+                       fireSourceChanged(ISources.WORKBENCH, getCurrentState());
+               }
+       }
+
+}
index 42f14e5ce1ea0473dbf9b4473d30ce5edec6ed7c..83c558e1ab0f1444346b8413e487c504a6fb4459 100644 (file)
@@ -21,6 +21,7 @@ import org.springframework.core.io.ClassPathResource;
 import org.springframework.core.io.Resource;
 import org.springframework.security.access.PermissionEvaluator;
 import org.springframework.security.authentication.ProviderManager;
 import org.springframework.core.io.Resource;
 import org.springframework.security.access.PermissionEvaluator;
 import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 
@@ -348,13 +349,16 @@ public class CdmStore {
         * @return
         */
        public static boolean currentAuthentiationHasPermission(Class<? extends CdmBase> targetType, EnumSet<CRUD> permission){
         * @return
         */
        public static boolean currentAuthentiationHasPermission(Class<? extends CdmBase> targetType, EnumSet<CRUD> permission){
-               SecurityContext context = SecurityContextHolder.getContext();
-               return getPermissionEvaluator().hasPermission(context.getAuthentication(), null, targetType.getName(), permission);
+               return getPermissionEvaluator().hasPermission(getCurrentAuthentiation(), null, targetType.getName(), permission);
        }
        
        public static boolean currentAuthentiationHasOneOfRoles(Role ... roles){
        }
        
        public static boolean currentAuthentiationHasOneOfRoles(Role ... roles){
+               return getPermissionEvaluator().hasOneOfRoles(getCurrentAuthentiation(), roles);
+       }
+       
+       public static Authentication getCurrentAuthentiation() {
                SecurityContext context = SecurityContextHolder.getContext();
                SecurityContext context = SecurityContextHolder.getContext();
-               return getPermissionEvaluator().hasOneOfRoles(context.getAuthentication(), roles);
+               return context.getAuthentication();
        }
        
        /*
        }
        
        /*
index beb18fbc3289985b09fb7f512e40d07d99b61dfc..35642d41386ec948907cbe87bfc4512917022865 100644 (file)
@@ -52,6 +52,7 @@ public class LoginManager extends Observable implements IConversationEnabled, IC
         * <p>authenticate</p>
         *
         * @param token a {@link org.springframework.security.authentication.UsernamePasswordAuthenticationToken} object.
         * <p>authenticate</p>
         *
         * @param token a {@link org.springframework.security.authentication.UsernamePasswordAuthenticationToken} object.
+        * @return true if the login attempt was successful even if the authentication has changed or not
         */
        public boolean authenticate(String username, String password){
 
         */
        public boolean authenticate(String username, String password){
 
@@ -67,6 +68,8 @@ public class LoginManager extends Observable implements IConversationEnabled, IC
                        
                        SecurityContextHolder.clearContext();
                        
                        
                        SecurityContextHolder.clearContext();
                        
+                       Authentication lastAuthentication = CdmStore.getCurrentAuthentiation();
+                       
                        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);                        
                        Authentication authentication = CdmStore.getAuthenticationManager().authenticate(token);
                        
                        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);                        
                        Authentication authentication = CdmStore.getAuthenticationManager().authenticate(token);
                        
@@ -89,8 +92,10 @@ public class LoginManager extends Observable implements IConversationEnabled, IC
                
                        SecurityContextHolder.getContext().setAuthentication(authentication);                   
 
                
                        SecurityContextHolder.getContext().setAuthentication(authentication);                   
 
-                       this.setChanged();
-                       this.notifyObservers();
+                       if(!authentication.equals(lastAuthentication)){
+                               this.setChanged();
+                               this.notifyObservers();
+                       }
                        return true;
                }
                catch(BadCredentialsException e){
                        return true;
                }
                catch(BadCredentialsException e){