← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 14338: sharing service implemented, still needs review before use, added new property to Schema telling ...

 

------------------------------------------------------------
revno: 14338
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2014-03-21 12:01:40 +0100
message:
  sharing service implemented, still needs review before use, added new property to Schema telling if the schema describes an identifiableObject or not
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/Schema.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sharing/DefaultSharingService.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/Schema.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/Schema.java	2014-03-21 09:35:30 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/Schema.java	2014-03-21 11:01:40 +0000
@@ -34,6 +34,7 @@
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
 import com.google.common.collect.Lists;
 import org.hisp.dhis.common.DxfNamespaces;
+import org.hisp.dhis.common.IdentifiableObject;
 
 import java.util.List;
 
@@ -45,6 +46,8 @@
 {
     private Class<?> klass;
 
+    private boolean identifiableObject;
+
     private String singular;
 
     private String plural;
@@ -65,15 +68,17 @@
 
     private List<Property> properties = Lists.newArrayList();
 
-    public Schema()
+    public Schema( Class<?> klass, String singular, String plural )
     {
+        this.klass = klass;
+        this.identifiableObject = IdentifiableObject.class.isAssignableFrom( klass );
+        this.singular = singular;
+        this.plural = plural;
     }
 
     public Schema( Class<?> klass, String singular, String plural, boolean importable, boolean exportable, boolean deletable )
     {
-        this.klass = klass;
-        this.singular = singular;
-        this.plural = plural;
+        this( klass, singular, plural );
         this.importable = importable;
         this.exportable = exportable;
         this.deletable = deletable;
@@ -92,6 +97,13 @@
     }
 
     @JsonProperty
+    @JacksonXmlProperty( isAttribute = true )
+    public boolean isIdentifiableObject()
+    {
+        return identifiableObject;
+    }
+
+    @JsonProperty
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public String getSingular()
     {

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sharing/DefaultSharingService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sharing/DefaultSharingService.java	2014-03-21 10:31:50 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sharing/DefaultSharingService.java	2014-03-21 11:01:40 +0000
@@ -29,13 +29,20 @@
  */
 
 import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.dashboard.Dashboard;
+import org.hisp.dhis.schema.Schema;
 import org.hisp.dhis.schema.SchemaService;
 import org.hisp.dhis.user.User;
+import org.hisp.dhis.user.UserGroup;
+import org.hisp.dhis.user.UserGroupAccess;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.util.CollectionUtils;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+
+import static org.springframework.util.CollectionUtils.containsAny;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -50,77 +57,191 @@
     @Override
     public boolean isSupported( String type )
     {
-        return false;
+        Schema schema = schemaService.getSchemaBySingularName( type );
+        return schema != null && schema.isShareable();
     }
 
     @Override
     public boolean isSupported( Class<?> klass )
     {
-        return false;
+        Schema schema = schemaService.getSchema( klass );
+        return schema != null && schema.isShareable();
     }
 
     @Override
     public boolean canWrite( User user, IdentifiableObject object )
     {
+        Schema schema = schemaService.getSchema( object.getClass() );
+
+        if ( schema == null || !schema.isShareable() )
+        {
+            return false;
+        }
+
+        //TODO ( (object instanceof User) && canCreatePrivate( user, object ) ): review possible security breaches and best way to give update access upon user import
+        if ( haveOverrideAuthority( user )
+            || (object.getUser() == null && canCreatePublic( user, object.getClass() ) && !schema.getPrivateAuthorities().isEmpty())
+            || (user != null && user.equals( object.getUser() ))
+            //|| authorities.contains( PRIVATE_AUTHORITIES.get( object.getClass() ) )
+            || ((object instanceof User) && canCreatePrivate( user, object.getClass() ))
+            || AccessStringHelper.canWrite( object.getPublicAccess() ) )
+        {
+            return true;
+        }
+
+        for ( UserGroupAccess userGroupAccess : object.getUserGroupAccesses() )
+        {
+            if ( AccessStringHelper.canWrite( userGroupAccess.getAccess() )
+                && userGroupAccess.getUserGroup().getMembers().contains( user ) )
+            {
+                return true;
+            }
+        }
+
         return false;
     }
 
     @Override
     public boolean canRead( User user, IdentifiableObject object )
     {
+        Schema schema = schemaService.getSchema( object.getClass() );
+
+        if ( schema == null || !schema.isShareable() )
+        {
+            return false;
+        }
+
+        if ( haveOverrideAuthority( user )
+            || UserGroup.class.isAssignableFrom( object.getClass() )
+            || object.getUser() == null
+            || user.equals( object.getUser() )
+            || AccessStringHelper.canRead( object.getPublicAccess() ) )
+        {
+            return true;
+        }
+
+        for ( UserGroupAccess userGroupAccess : object.getUserGroupAccesses() )
+        {
+            if ( AccessStringHelper.canRead( userGroupAccess.getAccess() )
+                && userGroupAccess.getUserGroup().getMembers().contains( user ) )
+            {
+                return true;
+            }
+        }
+
         return false;
     }
 
     @Override
     public boolean canUpdate( User user, IdentifiableObject object )
     {
-        return false;
+        return canWrite( user, object );
     }
 
     @Override
     public boolean canDelete( User user, IdentifiableObject object )
     {
-        return false;
+        return canWrite( user, object );
     }
 
     @Override
     public boolean canManage( User user, IdentifiableObject object )
     {
+        Schema schema = schemaService.getSchema( object.getClass() );
+
+        if ( schema == null || !schema.isShareable() )
+        {
+            return false;
+        }
+
+        if ( haveOverrideAuthority( user )
+            || (object.getUser() == null && canCreatePublic( user, object.getClass() ) && !schema.getPrivateAuthorities().isEmpty())
+            || user.equals( object.getUser() )
+            || AccessStringHelper.canWrite( object.getPublicAccess() ) )
+        {
+            return true;
+        }
+
+        for ( UserGroupAccess userGroupAccess : object.getUserGroupAccesses() )
+        {
+            if ( AccessStringHelper.canWrite( userGroupAccess.getAccess() )
+                && userGroupAccess.getUserGroup().getMembers().contains( user ) )
+            {
+                return true;
+            }
+        }
+
         return false;
     }
 
     @Override
     public <T extends IdentifiableObject> boolean canCreatePublic( User user, Class<T> klass )
     {
-        return false;
+        Set<String> authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet<String>();
+
+        Schema schema = schemaService.getSchema( klass );
+
+        if ( schema == null || !schema.isShareable() )
+        {
+            return false;
+        }
+
+        return containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) || containsAny( authorities, schema.getPublicAuthorities() );
     }
 
     @Override
     public <T extends IdentifiableObject> boolean canCreatePrivate( User user, Class<T> klass )
     {
-        return false;
+        Set<String> authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet<String>();
+
+        Schema schema = schemaService.getSchema( klass );
+
+        if ( schema == null || !schema.isShareable() )
+        {
+            return false;
+        }
+
+        return containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) || containsAny( authorities, schema.getPrivateAuthorities() );
     }
 
     @Override
     public <T extends IdentifiableObject> boolean canExternalize( User user, Class<T> klass )
     {
-        return false;
+        Set<String> authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet<String>();
+
+        Schema schema = schemaService.getSchema( klass );
+
+        if ( schema == null || !schema.isShareable() )
+        {
+            return false;
+        }
+
+        return containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) || containsAny( authorities, schema.getExternalAuthorities() );
     }
 
     @Override
     public <T extends IdentifiableObject> boolean defaultPublic( Class<T> klass )
     {
-        return false;
+        // TODO this is quite nasty, should probably be added to schema
+        return !Dashboard.class.isAssignableFrom( klass );
     }
 
     @Override
+    @SuppressWarnings( "unchecked" )
     public Class<? extends IdentifiableObject> classForType( String type )
     {
+        Schema schema = schemaService.getSchemaBySingularName( type );
+
+        if ( schema != null && schema.isShareable() && schema.isIdentifiableObject() )
+        {
+            return (Class<? extends IdentifiableObject>) schema.getKlass();
+        }
+
         return null;
     }
 
     private boolean haveOverrideAuthority( User user )
     {
-        return user == null || CollectionUtils.containsAny( user.getUserCredentials().getAllAuthorities(), SHARING_OVERRIDE_AUTHORITIES );
+        return user == null || containsAny( user.getUserCredentials().getAllAuthorities(), SHARING_OVERRIDE_AUTHORITIES );
     }
 }