=== 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 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 @@ -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 boolean canCreatePublic( User user, Class klass ) { - return false; + Set authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet(); + + Schema schema = schemaService.getSchema( klass ); + + if ( schema == null || !schema.isShareable() ) + { + return false; + } + + return containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) || containsAny( authorities, schema.getPublicAuthorities() ); } @Override public boolean canCreatePrivate( User user, Class klass ) { - return false; + Set authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet(); + + Schema schema = schemaService.getSchema( klass ); + + if ( schema == null || !schema.isShareable() ) + { + return false; + } + + return containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) || containsAny( authorities, schema.getPrivateAuthorities() ); } @Override public boolean canExternalize( User user, Class klass ) { - return false; + Set authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet(); + + Schema schema = schemaService.getSchema( klass ); + + if ( schema == null || !schema.isShareable() ) + { + return false; + } + + return containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) || containsAny( authorities, schema.getExternalAuthorities() ); } @Override public boolean defaultPublic( Class klass ) { - return false; + // TODO this is quite nasty, should probably be added to schema + return !Dashboard.class.isAssignableFrom( klass ); } @Override + @SuppressWarnings( "unchecked" ) public Class classForType( String type ) { + Schema schema = schemaService.getSchemaBySingularName( type ); + + if ( schema != null && schema.isShareable() && schema.isIdentifiableObject() ) + { + return (Class) 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 ); } }