=== removed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Access.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Access.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Access.java 1970-01-01 00:00:00 +0000 @@ -1,128 +0,0 @@ -package org.hisp.dhis.common; - -/* - * Copyright (c) 2004-2014, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; - -/** - * @author Morten Olav Hansen - */ -@JacksonXmlRootElement( localName = "access", namespace = DxfNamespaces.DXF_2_0 ) -public class Access -{ - private boolean manage; - - private boolean externalize; - - private boolean write; - - private boolean read; - - private boolean update; - - private boolean delete; - - public Access() - { - } - - @JsonProperty - @JacksonXmlProperty( localName = "manage", namespace = DxfNamespaces.DXF_2_0 ) - public boolean isManage() - { - return manage; - } - - public void setManage( boolean manage ) - { - this.manage = manage; - } - - @JsonProperty - @JacksonXmlProperty( localName = "externalize", namespace = DxfNamespaces.DXF_2_0 ) - public boolean isExternalize() - { - return externalize; - } - - public void setExternalize( boolean externalize ) - { - this.externalize = externalize; - } - - @JsonProperty - @JacksonXmlProperty( localName = "write", namespace = DxfNamespaces.DXF_2_0 ) - public boolean isWrite() - { - return write; - } - - public void setWrite( boolean write ) - { - this.write = write; - } - - @JsonProperty - @JacksonXmlProperty( localName = "read", namespace = DxfNamespaces.DXF_2_0 ) - public boolean isRead() - { - return read; - } - - public void setRead( boolean read ) - { - this.read = read; - } - - @JsonProperty - @JacksonXmlProperty( localName = "update", namespace = DxfNamespaces.DXF_2_0 ) - public boolean isUpdate() - { - return update; - } - - public void setUpdate( boolean update ) - { - this.update = update; - } - - @JsonProperty - @JacksonXmlProperty( localName = "delete", namespace = DxfNamespaces.DXF_2_0 ) - public boolean isDelete() - { - return delete; - } - - public void setDelete( boolean delete ) - { - this.delete = delete; - } -} === removed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/AccessStringHelper.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/AccessStringHelper.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/AccessStringHelper.java 1970-01-01 00:00:00 +0000 @@ -1,129 +0,0 @@ -package org.hisp.dhis.common; - -/* - * Copyright (c) 2004-2014, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Currently only the two first positions in the access string are used - rw. - * - * @author Morten Olav Hansen - */ -public class AccessStringHelper -{ - public static final String DEFAULT_ACCESS = "--------"; - - public static enum Permission - { - READ( 'r', 0 ), WRITE( 'w', 1 ); - - private char value; - - private int position; - - private Permission( char value, int position ) - { - this.value = value; - this.position = position; - } - - public char getValue() - { - return value; - } - - public int getPosition() - { - return position; - } - } - - private char[] access = DEFAULT_ACCESS.toCharArray(); - - public AccessStringHelper() - { - } - - public AccessStringHelper( char[] access ) - { - this.access = access; - } - - public AccessStringHelper( String access ) - { - this.access = access.toCharArray(); - } - - public static AccessStringHelper newInstance() - { - return new AccessStringHelper(); - } - - public static AccessStringHelper newInstance( char[] access ) - { - return new AccessStringHelper( access ); - } - - public AccessStringHelper enable( Permission permission ) - { - access[permission.getPosition()] = permission.getValue(); - - return this; - } - - public AccessStringHelper disable( Permission permission ) - { - access[permission.getPosition()] = '-'; - - return this; - } - - public String build() - { - return new String( access ); - } - - public String toString() - { - return build(); - } - - public static boolean canRead( String access ) - { - return isEnabled( access, Permission.READ ); - } - - public static boolean canWrite( String access ) - { - return isEnabled( access, Permission.WRITE ); - } - - public static boolean isEnabled( String access, Permission permission ) - { - return access != null && access.charAt( permission.getPosition() ) == permission.getValue(); - } -} === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java 2014-03-21 09:41:08 +0000 @@ -40,6 +40,7 @@ import org.hisp.dhis.common.view.SharingBasicView; import org.hisp.dhis.common.view.SharingDetailedView; import org.hisp.dhis.common.view.SharingExportView; +import org.hisp.dhis.sharing.Access; import org.hisp.dhis.user.User; import org.hisp.dhis.user.UserGroupAccess; === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObject.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObject.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObject.java 2014-03-21 09:41:08 +0000 @@ -28,6 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.hisp.dhis.sharing.Access; import org.hisp.dhis.user.User; import org.hisp.dhis.user.UserGroupAccess; === removed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/SharingUtils.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/SharingUtils.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/SharingUtils.java 1970-01-01 00:00:00 +0000 @@ -1,373 +0,0 @@ -package org.hisp.dhis.common; - -/* - * Copyright (c) 2004-2014, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.hisp.dhis.chart.Chart; -import org.hisp.dhis.dashboard.Dashboard; -import org.hisp.dhis.datadictionary.DataDictionary; -import org.hisp.dhis.dataelement.CategoryOptionGroup; -import org.hisp.dhis.dataelement.CategoryOptionGroupSet; -import org.hisp.dhis.dataelement.DataElement; -import org.hisp.dhis.dataelement.DataElementCategory; -import org.hisp.dhis.dataelement.DataElementCategoryCombo; -import org.hisp.dhis.dataelement.DataElementCategoryOption; -import org.hisp.dhis.dataset.DataSet; -import org.hisp.dhis.document.Document; -import org.hisp.dhis.indicator.Indicator; -import org.hisp.dhis.indicator.IndicatorGroup; -import org.hisp.dhis.indicator.IndicatorGroupSet; -import org.hisp.dhis.interpretation.Interpretation; -import org.hisp.dhis.organisationunit.OrganisationUnitGroup; -import org.hisp.dhis.program.Program; -import org.hisp.dhis.report.Report; -import org.hisp.dhis.reporttable.ReportTable; -import org.hisp.dhis.user.User; -import org.hisp.dhis.user.UserGroup; -import org.hisp.dhis.user.UserGroupAccess; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; - -/** - * @author Morten Olav Hansen - */ -public final class SharingUtils -{ - public static Map, String> EXTERNAL_AUTHORITIES = new HashMap, String>(); - - public static Map, String> PUBLIC_AUTHORITIES = new HashMap, String>(); - - public static Map, String> PRIVATE_AUTHORITIES = new HashMap, String>(); - - public static final Map> SUPPORTED_TYPES = new HashMap>(); - - public static final List SHARING_OVERRIDE_AUTHORITIES = Arrays.asList( "ALL", "F_METADATA_IMPORT" ); - - private static void addType( Class clazz, String name, String externalAuth, String publicAuth, String privateAuth ) - { - Assert.notNull( clazz ); - Assert.hasLength( name ); - - SUPPORTED_TYPES.put( name, clazz ); - - if ( externalAuth != null ) - { - EXTERNAL_AUTHORITIES.put( clazz, externalAuth ); - } - - if ( publicAuth != null ) - { - PUBLIC_AUTHORITIES.put( clazz, publicAuth ); - } - - if ( privateAuth != null ) - { - PRIVATE_AUTHORITIES.put( clazz, privateAuth ); - } - } - - static - { - addType( Document.class, "document", null, "F_DOCUMENT_PUBLIC_ADD", "F_DOCUMENT_PRIVATE_ADD" ); - addType( Report.class, "report", null, "F_REPORT_PUBLIC_ADD", "F_REPORT_PRIVATE_ADD" ); - addType( DataSet.class, "dataSet", null, "F_DATASET_PUBLIC_ADD", "F_DATASET_PRIVATE_ADD" ); - addType( DataDictionary.class, "dataDictionary", null, "F_DATADICTIONARY_PUBLIC_ADD", "F_DATADICTIONARY_PRIVATE_ADD" ); - addType( DataElement.class, "dataElement", null, "F_DATAELEMENT_PUBLIC_ADD", "F_DATAELEMENT_PRIVATE_ADD" ); - addType( DataElementCategory.class, "category", null, "F_CATEGORY_PUBLIC_ADD", "F_CATEGORY_PRIVATE_ADD" ); - addType( DataElementCategoryOption.class, "categoryOption", null, "F_CATEGORY_OPTION_PUBLIC_ADD", "F_CATEGORY_OPTION_PRIVATE_ADD" ); - addType( CategoryOptionGroup.class, "categoryOptionGroup", null, "F_CATEGORY_OPTION_GROUP_PUBLIC_ADD", "F_CATEGORY_OPTION_GROUP_PRIVATE_ADD" ); - addType( CategoryOptionGroupSet.class, "categoryOptionGroupSet", null, "F_CATEGORY_OPTION_GROUP_SET_PUBLIC_ADD", "F_CATEGORY_OPTION_GROUP_SET_PRIVATE_ADD" ); - addType( DataElementCategoryCombo.class, "categoryCombo", null, "F_CATEGORY_COMBO_PUBLIC_ADD", "F_CATEGORY_COMBO_PRIVATE_ADD" ); - addType( OrganisationUnitGroup.class, "organisationUnitGroup", null, "F_ORGUNITGROUP_PUBLIC_ADD", "F_ORGUNITGROUP_PRIVATE_ADD" ); - addType( Indicator.class, "indicator", null, "F_INDICATOR_PUBLIC_ADD", "F_INDICATOR_PRIVATE_ADD" ); - addType( IndicatorGroup.class, "indicatorGroup", null, "F_INDICATORGROUP_PUBLIC_ADD", "F_INDICATORGROUP_PRIVATE_ADD" ); - addType( IndicatorGroupSet.class, "indicatorGroupSet", null, "F_INDICATORGROUPSET_PUBLIC_ADD", "F_INDICATORGROUPSET_PRIVATE_ADD" ); - addType( Program.class, "program", null, "F_PROGRAM_PUBLIC_ADD", "F_PROGRAM_PRIVATE_ADD" ); - addType( UserGroup.class, "userGroup", null, "F_USERGROUP_PUBLIC_ADD", null ); - - addType( org.hisp.dhis.mapping.Map.class, "map", "F_MAP_EXTERNAL", "F_MAP_PUBLIC_ADD", null ); - addType( Chart.class, "chart", "F_CHART_EXTERNAL", "F_CHART_PUBLIC_ADD", null ); - addType( ReportTable.class, "reportTable", "F_REPORTTABLE_EXTERNAL", "F_REPORTTABLE_PUBLIC_ADD", null ); - addType( Report.class, "report", "F_REPORT_EXTERNAL", "F_REPORT_PUBLIC_ADD", "F_REPORT_PRIVATE_ADD" ); - addType( Document.class, "document", "F_DOCUMENT_EXTERNAL", "F_DOCUMENT_PUBLIC_ADD", "F_DOCUMENT_PRIVATE_ADD" ); - - addType( Dashboard.class, "dashboard", null, "F_DASHBOARD_PUBLIC_ADD", null ); - addType( Interpretation.class, "interpretation", null, null, null ); - } - - public static boolean isSupported( String type ) - { - return SUPPORTED_TYPES.containsKey( type ); - } - - public static boolean isSupported( IdentifiableObject object ) - { - return isSupported( object.getClass() ); - } - - public static boolean isSupported( Class clazz ) - { - return SUPPORTED_TYPES.containsValue( clazz ); - } - - public static Class classForType( String type ) - { - return SUPPORTED_TYPES.get( type ); - } - - /** - * Checks if a user can create a public instance of a certain object. - *

- * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? - * 2. Does user have the authority to create public instances of that object - * - * @param user User to check against - * @param clazz Class to check - * @return Result of test - */ - public static boolean canCreatePublic( User user, Class clazz ) - { - Set authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet(); - return CollectionUtils.containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) || authorities.contains( PUBLIC_AUTHORITIES.get( clazz ) ); - } - - public static boolean defaultPublic( Class clazz ) - { - return !Dashboard.class.isAssignableFrom( clazz ); - } - - public static boolean canCreatePublic( User user, IdentifiableObject identifiableObject ) - { - return canCreatePublic( user, identifiableObject.getClass() ); - } - - public static boolean canCreatePublic( User user, String type ) - { - return canCreatePublic( user, SUPPORTED_TYPES.get( type ) ); - } - - /** - * Checks if a user can create a private instance of a certain object. - *

- * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? - * 2. Does user have the authority to create private instances of that object - * - * @param user User to check against - * @param clazz Class to check - * @return Result of test - */ - public static boolean canCreatePrivate( User user, Class clazz ) - { - Set authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet(); - return CollectionUtils.containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) - || PRIVATE_AUTHORITIES.get( clazz ) == null - || authorities.contains( PRIVATE_AUTHORITIES.get( clazz ) ); - } - - public static boolean canCreatePrivate( User user, IdentifiableObject identifiableObject ) - { - return canCreatePrivate( user, identifiableObject.getClass() ); - } - - public static boolean canCreatePrivate( User user, String type ) - { - return canCreatePrivate( user, SUPPORTED_TYPES.get( type ) ); - } - - /** - * Can user write to this object (create) - *

- * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? - * 2. Is the user for the object null? - * 3. Is the user of the object equal to current user? - * 4. Is the object public write? - * 5. Does any of the userGroupAccesses contain public write and the current user is in that group - * - * @param user User to check against - * @param object Object to check - * @return Result of test - */ - public static boolean canWrite( User user, IdentifiableObject object ) - { - //TODO ( (object instanceof User) && canCreatePrivate( user, object ) ): review possible security breaches and best way to give update access upon user import - if ( sharingOverrideAuthority( user ) - || (object.getUser() == null && canCreatePublic( user, object ) && PRIVATE_AUTHORITIES.get( object.getClass() ) != null) - || (user != null && user.equals( object.getUser() )) - //|| authorities.contains( PRIVATE_AUTHORITIES.get( object.getClass() ) ) - || ((object instanceof User) && canCreatePrivate( user, object )) - || 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; - } - - /** - * Can user read this object - *

- * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? - * 2. Is the user for the object null? - * 3. Is the user of the object equal to current user? - * 4. Is the object public read? - * 5. Does any of the userGroupAccesses contain public read and the current user is in that group - * - * @param user User to check against - * @param object Object to check - * @return Result of test - */ - public static boolean canRead( User user, IdentifiableObject object ) - { - if ( sharingOverrideAuthority( 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; - } - - /** - * Can user update this object - *

- * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? - * 2. Can user write to this object? - * - * @param user User to check against - * @param object Object to check - * @return Result of test - */ - public static boolean canUpdate( User user, IdentifiableObject object ) - { - return canWrite( user, object ); - } - - /** - * Can user delete this object - *

- * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? - * 2. Can user write to this object? - * - * @param user User to check against - * @param object Object to check - * @return Result of test - */ - public static boolean canDelete( User user, IdentifiableObject object ) - { - return canWrite( user, object ); - } - - /** - * Can user manage (make public) this object - *

- * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? - * 2. Can user write to this object? - * - * @param user User to check against - * @param object Object to check - * @return Result of test - */ - public static boolean canManage( User user, IdentifiableObject object ) - { - if ( sharingOverrideAuthority( user ) - || (object.getUser() == null && canCreatePublic( user, object ) && PRIVATE_AUTHORITIES.get( object.getClass() ) != null) - || 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; - } - - /** - * Can user make this object external? (read with no login) - * - * @param user User to check against - * @param object Object to check - * @return Result of test - */ - public static boolean canExternalize( User user, T object ) - { - if ( user == null ) - { - return false; - } - - Set authorities = user.getUserCredentials().getAllAuthorities(); - - return EXTERNAL_AUTHORITIES.get( object.getClass() ) != null && - (sharingOverrideAuthority( user ) || authorities.contains( EXTERNAL_AUTHORITIES.get( object.getClass() ) )); - } - - private static boolean sharingOverrideAuthority( User user ) - { - return user == null || CollectionUtils.containsAny( user.getUserCredentials().getAllAuthorities(), SHARING_OVERRIDE_AUTHORITIES ); - } - - private SharingUtils() - { - } -} === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/interpretation/Interpretation.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/interpretation/Interpretation.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/interpretation/Interpretation.java 2014-03-21 09:41:08 +0000 @@ -35,7 +35,7 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import org.hisp.dhis.chart.Chart; -import org.hisp.dhis.common.AccessStringHelper; +import org.hisp.dhis.sharing.AccessStringHelper; import org.hisp.dhis.common.BaseIdentifiableObject; import org.hisp.dhis.common.DxfNamespaces; import org.hisp.dhis.common.IdentifiableObject; === added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing' === added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/Access.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/Access.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/Access.java 2014-03-21 09:41:08 +0000 @@ -0,0 +1,129 @@ +package org.hisp.dhis.sharing; + +/* + * Copyright (c) 2004-2014, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import org.hisp.dhis.common.DxfNamespaces; + +/** + * @author Morten Olav Hansen + */ +@JacksonXmlRootElement( localName = "access", namespace = DxfNamespaces.DXF_2_0 ) +public class Access +{ + private boolean manage; + + private boolean externalize; + + private boolean write; + + private boolean read; + + private boolean update; + + private boolean delete; + + public Access() + { + } + + @JsonProperty + @JacksonXmlProperty( localName = "manage", namespace = DxfNamespaces.DXF_2_0 ) + public boolean isManage() + { + return manage; + } + + public void setManage( boolean manage ) + { + this.manage = manage; + } + + @JsonProperty + @JacksonXmlProperty( localName = "externalize", namespace = DxfNamespaces.DXF_2_0 ) + public boolean isExternalize() + { + return externalize; + } + + public void setExternalize( boolean externalize ) + { + this.externalize = externalize; + } + + @JsonProperty + @JacksonXmlProperty( localName = "write", namespace = DxfNamespaces.DXF_2_0 ) + public boolean isWrite() + { + return write; + } + + public void setWrite( boolean write ) + { + this.write = write; + } + + @JsonProperty + @JacksonXmlProperty( localName = "read", namespace = DxfNamespaces.DXF_2_0 ) + public boolean isRead() + { + return read; + } + + public void setRead( boolean read ) + { + this.read = read; + } + + @JsonProperty + @JacksonXmlProperty( localName = "update", namespace = DxfNamespaces.DXF_2_0 ) + public boolean isUpdate() + { + return update; + } + + public void setUpdate( boolean update ) + { + this.update = update; + } + + @JsonProperty + @JacksonXmlProperty( localName = "delete", namespace = DxfNamespaces.DXF_2_0 ) + public boolean isDelete() + { + return delete; + } + + public void setDelete( boolean delete ) + { + this.delete = delete; + } +} === added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/AccessStringHelper.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/AccessStringHelper.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/AccessStringHelper.java 2014-03-21 09:41:08 +0000 @@ -0,0 +1,129 @@ +package org.hisp.dhis.sharing; + +/* + * Copyright (c) 2004-2014, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Currently only the two first positions in the access string are used - rw. + * + * @author Morten Olav Hansen + */ +public class AccessStringHelper +{ + public static final String DEFAULT_ACCESS = "--------"; + + public static enum Permission + { + READ( 'r', 0 ), WRITE( 'w', 1 ); + + private char value; + + private int position; + + private Permission( char value, int position ) + { + this.value = value; + this.position = position; + } + + public char getValue() + { + return value; + } + + public int getPosition() + { + return position; + } + } + + private char[] access = DEFAULT_ACCESS.toCharArray(); + + public AccessStringHelper() + { + } + + public AccessStringHelper( char[] access ) + { + this.access = access; + } + + public AccessStringHelper( String access ) + { + this.access = access.toCharArray(); + } + + public static AccessStringHelper newInstance() + { + return new AccessStringHelper(); + } + + public static AccessStringHelper newInstance( char[] access ) + { + return new AccessStringHelper( access ); + } + + public AccessStringHelper enable( Permission permission ) + { + access[permission.getPosition()] = permission.getValue(); + + return this; + } + + public AccessStringHelper disable( Permission permission ) + { + access[permission.getPosition()] = '-'; + + return this; + } + + public String build() + { + return new String( access ); + } + + public String toString() + { + return build(); + } + + public static boolean canRead( String access ) + { + return isEnabled( access, Permission.READ ); + } + + public static boolean canWrite( String access ) + { + return isEnabled( access, Permission.WRITE ); + } + + public static boolean isEnabled( String access, Permission permission ) + { + return access != null && access.charAt( permission.getPosition() ) == permission.getValue(); + } +} === added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/SharingUtils.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/SharingUtils.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sharing/SharingUtils.java 2014-03-21 09:41:08 +0000 @@ -0,0 +1,374 @@ +package org.hisp.dhis.sharing; + +/* + * Copyright (c) 2004-2014, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.hisp.dhis.chart.Chart; +import org.hisp.dhis.common.IdentifiableObject; +import org.hisp.dhis.dashboard.Dashboard; +import org.hisp.dhis.datadictionary.DataDictionary; +import org.hisp.dhis.dataelement.CategoryOptionGroup; +import org.hisp.dhis.dataelement.CategoryOptionGroupSet; +import org.hisp.dhis.dataelement.DataElement; +import org.hisp.dhis.dataelement.DataElementCategory; +import org.hisp.dhis.dataelement.DataElementCategoryCombo; +import org.hisp.dhis.dataelement.DataElementCategoryOption; +import org.hisp.dhis.dataset.DataSet; +import org.hisp.dhis.document.Document; +import org.hisp.dhis.indicator.Indicator; +import org.hisp.dhis.indicator.IndicatorGroup; +import org.hisp.dhis.indicator.IndicatorGroupSet; +import org.hisp.dhis.interpretation.Interpretation; +import org.hisp.dhis.organisationunit.OrganisationUnitGroup; +import org.hisp.dhis.program.Program; +import org.hisp.dhis.report.Report; +import org.hisp.dhis.reporttable.ReportTable; +import org.hisp.dhis.user.User; +import org.hisp.dhis.user.UserGroup; +import org.hisp.dhis.user.UserGroupAccess; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; + +/** + * @author Morten Olav Hansen + */ +public final class SharingUtils +{ + public static Map, String> EXTERNAL_AUTHORITIES = new HashMap, String>(); + + public static Map, String> PUBLIC_AUTHORITIES = new HashMap, String>(); + + public static Map, String> PRIVATE_AUTHORITIES = new HashMap, String>(); + + public static final Map> SUPPORTED_TYPES = new HashMap>(); + + public static final List SHARING_OVERRIDE_AUTHORITIES = Arrays.asList( "ALL", "F_METADATA_IMPORT" ); + + private static void addType( Class clazz, String name, String externalAuth, String publicAuth, String privateAuth ) + { + Assert.notNull( clazz ); + Assert.hasLength( name ); + + SUPPORTED_TYPES.put( name, clazz ); + + if ( externalAuth != null ) + { + EXTERNAL_AUTHORITIES.put( clazz, externalAuth ); + } + + if ( publicAuth != null ) + { + PUBLIC_AUTHORITIES.put( clazz, publicAuth ); + } + + if ( privateAuth != null ) + { + PRIVATE_AUTHORITIES.put( clazz, privateAuth ); + } + } + + static + { + addType( Document.class, "document", null, "F_DOCUMENT_PUBLIC_ADD", "F_DOCUMENT_PRIVATE_ADD" ); + addType( Report.class, "report", null, "F_REPORT_PUBLIC_ADD", "F_REPORT_PRIVATE_ADD" ); + addType( DataSet.class, "dataSet", null, "F_DATASET_PUBLIC_ADD", "F_DATASET_PRIVATE_ADD" ); + addType( DataDictionary.class, "dataDictionary", null, "F_DATADICTIONARY_PUBLIC_ADD", "F_DATADICTIONARY_PRIVATE_ADD" ); + addType( DataElement.class, "dataElement", null, "F_DATAELEMENT_PUBLIC_ADD", "F_DATAELEMENT_PRIVATE_ADD" ); + addType( DataElementCategory.class, "category", null, "F_CATEGORY_PUBLIC_ADD", "F_CATEGORY_PRIVATE_ADD" ); + addType( DataElementCategoryOption.class, "categoryOption", null, "F_CATEGORY_OPTION_PUBLIC_ADD", "F_CATEGORY_OPTION_PRIVATE_ADD" ); + addType( CategoryOptionGroup.class, "categoryOptionGroup", null, "F_CATEGORY_OPTION_GROUP_PUBLIC_ADD", "F_CATEGORY_OPTION_GROUP_PRIVATE_ADD" ); + addType( CategoryOptionGroupSet.class, "categoryOptionGroupSet", null, "F_CATEGORY_OPTION_GROUP_SET_PUBLIC_ADD", "F_CATEGORY_OPTION_GROUP_SET_PRIVATE_ADD" ); + addType( DataElementCategoryCombo.class, "categoryCombo", null, "F_CATEGORY_COMBO_PUBLIC_ADD", "F_CATEGORY_COMBO_PRIVATE_ADD" ); + addType( OrganisationUnitGroup.class, "organisationUnitGroup", null, "F_ORGUNITGROUP_PUBLIC_ADD", "F_ORGUNITGROUP_PRIVATE_ADD" ); + addType( Indicator.class, "indicator", null, "F_INDICATOR_PUBLIC_ADD", "F_INDICATOR_PRIVATE_ADD" ); + addType( IndicatorGroup.class, "indicatorGroup", null, "F_INDICATORGROUP_PUBLIC_ADD", "F_INDICATORGROUP_PRIVATE_ADD" ); + addType( IndicatorGroupSet.class, "indicatorGroupSet", null, "F_INDICATORGROUPSET_PUBLIC_ADD", "F_INDICATORGROUPSET_PRIVATE_ADD" ); + addType( Program.class, "program", null, "F_PROGRAM_PUBLIC_ADD", "F_PROGRAM_PRIVATE_ADD" ); + addType( UserGroup.class, "userGroup", null, "F_USERGROUP_PUBLIC_ADD", null ); + + addType( org.hisp.dhis.mapping.Map.class, "map", "F_MAP_EXTERNAL", "F_MAP_PUBLIC_ADD", null ); + addType( Chart.class, "chart", "F_CHART_EXTERNAL", "F_CHART_PUBLIC_ADD", null ); + addType( ReportTable.class, "reportTable", "F_REPORTTABLE_EXTERNAL", "F_REPORTTABLE_PUBLIC_ADD", null ); + addType( Report.class, "report", "F_REPORT_EXTERNAL", "F_REPORT_PUBLIC_ADD", "F_REPORT_PRIVATE_ADD" ); + addType( Document.class, "document", "F_DOCUMENT_EXTERNAL", "F_DOCUMENT_PUBLIC_ADD", "F_DOCUMENT_PRIVATE_ADD" ); + + addType( Dashboard.class, "dashboard", null, "F_DASHBOARD_PUBLIC_ADD", null ); + addType( Interpretation.class, "interpretation", null, null, null ); + } + + public static boolean isSupported( String type ) + { + return SUPPORTED_TYPES.containsKey( type ); + } + + public static boolean isSupported( IdentifiableObject object ) + { + return isSupported( object.getClass() ); + } + + public static boolean isSupported( Class clazz ) + { + return SUPPORTED_TYPES.containsValue( clazz ); + } + + public static Class classForType( String type ) + { + return SUPPORTED_TYPES.get( type ); + } + + /** + * Checks if a user can create a public instance of a certain object. + *

+ * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? + * 2. Does user have the authority to create public instances of that object + * + * @param user User to check against + * @param clazz Class to check + * @return Result of test + */ + public static boolean canCreatePublic( User user, Class clazz ) + { + Set authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet(); + return CollectionUtils.containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) || authorities.contains( PUBLIC_AUTHORITIES.get( clazz ) ); + } + + public static boolean defaultPublic( Class clazz ) + { + return !Dashboard.class.isAssignableFrom( clazz ); + } + + public static boolean canCreatePublic( User user, IdentifiableObject identifiableObject ) + { + return canCreatePublic( user, identifiableObject.getClass() ); + } + + public static boolean canCreatePublic( User user, String type ) + { + return canCreatePublic( user, SUPPORTED_TYPES.get( type ) ); + } + + /** + * Checks if a user can create a private instance of a certain object. + *

+ * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? + * 2. Does user have the authority to create private instances of that object + * + * @param user User to check against + * @param clazz Class to check + * @return Result of test + */ + public static boolean canCreatePrivate( User user, Class clazz ) + { + Set authorities = user != null ? user.getUserCredentials().getAllAuthorities() : new HashSet(); + return CollectionUtils.containsAny( authorities, SHARING_OVERRIDE_AUTHORITIES ) + || PRIVATE_AUTHORITIES.get( clazz ) == null + || authorities.contains( PRIVATE_AUTHORITIES.get( clazz ) ); + } + + public static boolean canCreatePrivate( User user, IdentifiableObject identifiableObject ) + { + return canCreatePrivate( user, identifiableObject.getClass() ); + } + + public static boolean canCreatePrivate( User user, String type ) + { + return canCreatePrivate( user, SUPPORTED_TYPES.get( type ) ); + } + + /** + * Can user write to this object (create) + *

+ * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? + * 2. Is the user for the object null? + * 3. Is the user of the object equal to current user? + * 4. Is the object public write? + * 5. Does any of the userGroupAccesses contain public write and the current user is in that group + * + * @param user User to check against + * @param object Object to check + * @return Result of test + */ + public static boolean canWrite( User user, IdentifiableObject object ) + { + //TODO ( (object instanceof User) && canCreatePrivate( user, object ) ): review possible security breaches and best way to give update access upon user import + if ( sharingOverrideAuthority( user ) + || (object.getUser() == null && canCreatePublic( user, object ) && PRIVATE_AUTHORITIES.get( object.getClass() ) != null) + || (user != null && user.equals( object.getUser() )) + //|| authorities.contains( PRIVATE_AUTHORITIES.get( object.getClass() ) ) + || ((object instanceof User) && canCreatePrivate( user, object )) + || 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; + } + + /** + * Can user read this object + *

+ * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? + * 2. Is the user for the object null? + * 3. Is the user of the object equal to current user? + * 4. Is the object public read? + * 5. Does any of the userGroupAccesses contain public read and the current user is in that group + * + * @param user User to check against + * @param object Object to check + * @return Result of test + */ + public static boolean canRead( User user, IdentifiableObject object ) + { + if ( sharingOverrideAuthority( 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; + } + + /** + * Can user update this object + *

+ * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? + * 2. Can user write to this object? + * + * @param user User to check against + * @param object Object to check + * @return Result of test + */ + public static boolean canUpdate( User user, IdentifiableObject object ) + { + return canWrite( user, object ); + } + + /** + * Can user delete this object + *

+ * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? + * 2. Can user write to this object? + * + * @param user User to check against + * @param object Object to check + * @return Result of test + */ + public static boolean canDelete( User user, IdentifiableObject object ) + { + return canWrite( user, object ); + } + + /** + * Can user manage (make public) this object + *

+ * 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? + * 2. Can user write to this object? + * + * @param user User to check against + * @param object Object to check + * @return Result of test + */ + public static boolean canManage( User user, IdentifiableObject object ) + { + if ( sharingOverrideAuthority( user ) + || (object.getUser() == null && canCreatePublic( user, object ) && PRIVATE_AUTHORITIES.get( object.getClass() ) != null) + || 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; + } + + /** + * Can user make this object external? (read with no login) + * + * @param user User to check against + * @param object Object to check + * @return Result of test + */ + public static boolean canExternalize( User user, T object ) + { + if ( user == null ) + { + return false; + } + + Set authorities = user.getUserCredentials().getAllAuthorities(); + + return EXTERNAL_AUTHORITIES.get( object.getClass() ) != null && + (sharingOverrideAuthority( user ) || authorities.contains( EXTERNAL_AUTHORITIES.get( object.getClass() ) )); + } + + private static boolean sharingOverrideAuthority( User user ) + { + return user == null || CollectionUtils.containsAny( user.getUserCredentials().getAllAuthorities(), SHARING_OVERRIDE_AUTHORITIES ); + } + + private SharingUtils() + { + } +} === modified file 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/common/AccessStringHelperTest.java' --- dhis-2/dhis-api/src/test/java/org/hisp/dhis/common/AccessStringHelperTest.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-api/src/test/java/org/hisp/dhis/common/AccessStringHelperTest.java 2014-03-21 09:41:08 +0000 @@ -28,6 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.hisp.dhis.sharing.AccessStringHelper; import org.junit.Assert; import org.junit.Test; === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java 2014-03-21 09:41:08 +0000 @@ -72,6 +72,7 @@ import org.hisp.dhis.period.PeriodType; import org.hisp.dhis.period.RelativePeriodEnum; import org.hisp.dhis.period.RelativePeriods; +import org.hisp.dhis.sharing.SharingUtils; import org.hisp.dhis.system.util.UniqueArrayList; import org.hisp.dhis.user.CurrentUserService; import org.hisp.dhis.user.User; === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/DefaultSecurityService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/DefaultSecurityService.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/DefaultSecurityService.java 2014-03-21 09:41:08 +0000 @@ -32,7 +32,7 @@ import org.apache.commons.logging.LogFactory; import org.hisp.dhis.common.CodeGenerator; import org.hisp.dhis.common.IdentifiableObject; -import org.hisp.dhis.common.SharingUtils; +import org.hisp.dhis.sharing.SharingUtils; import org.hisp.dhis.message.MessageSender; import org.hisp.dhis.period.Cal; import org.hisp.dhis.setting.SystemSettingManager; === modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java 2014-03-21 09:41:08 +0000 @@ -48,7 +48,7 @@ import org.hisp.dhis.common.BaseIdentifiableObject; import org.hisp.dhis.common.IdentifiableObject; import org.hisp.dhis.common.NameableObject; -import org.hisp.dhis.common.SharingUtils; +import org.hisp.dhis.sharing.SharingUtils; import org.hisp.dhis.dataelement.DataElementOperand; import org.hisp.dhis.dataelement.DataElementOperandService; import org.hisp.dhis.dataentryform.DataEntryForm; === modified file 'dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/hibernate/HibernateGenericStore.java' --- dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/hibernate/HibernateGenericStore.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/hibernate/HibernateGenericStore.java 2014-03-21 09:41:08 +0000 @@ -36,12 +36,12 @@ import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Criterion; -import org.hisp.dhis.common.AccessStringHelper; +import org.hisp.dhis.sharing.AccessStringHelper; import org.hisp.dhis.common.AuditLogUtil; import org.hisp.dhis.common.BaseIdentifiableObject; import org.hisp.dhis.common.GenericStore; import org.hisp.dhis.common.IdentifiableObject; -import org.hisp.dhis.common.SharingUtils; +import org.hisp.dhis.sharing.SharingUtils; import org.hisp.dhis.dashboard.Dashboard; import org.hisp.dhis.hibernate.exception.CreateAccessDeniedException; import org.hisp.dhis.hibernate.exception.DeleteAccessDeniedException; === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java 2014-03-21 09:41:08 +0000 @@ -32,13 +32,13 @@ import org.hisp.dhis.api.controller.exception.NotFoundException; import org.hisp.dhis.api.controller.exception.NotFoundForQueryException; import org.hisp.dhis.api.utils.WebUtils; -import org.hisp.dhis.common.Access; +import org.hisp.dhis.sharing.Access; import org.hisp.dhis.common.BaseIdentifiableObject; import org.hisp.dhis.common.IdentifiableObject; import org.hisp.dhis.common.IdentifiableObjectManager; import org.hisp.dhis.common.Pager; import org.hisp.dhis.common.PagerUtils; -import org.hisp.dhis.common.SharingUtils; +import org.hisp.dhis.sharing.SharingUtils; import org.hisp.dhis.dxf2.filter.FilterService; import org.hisp.dhis.dxf2.metadata.ExchangeClasses; import org.hisp.dhis.dxf2.utils.JacksonUtils; === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/SharingController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/SharingController.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/SharingController.java 2014-03-21 09:41:08 +0000 @@ -34,11 +34,11 @@ import org.hisp.dhis.api.webdomain.sharing.Sharing; import org.hisp.dhis.api.webdomain.sharing.SharingUserGroupAccess; import org.hisp.dhis.api.webdomain.sharing.SharingUserGroups; -import org.hisp.dhis.common.AccessStringHelper; +import org.hisp.dhis.sharing.AccessStringHelper; import org.hisp.dhis.common.BaseIdentifiableObject; import org.hisp.dhis.common.IdentifiableObject; import org.hisp.dhis.common.IdentifiableObjectManager; -import org.hisp.dhis.common.SharingUtils; +import org.hisp.dhis.sharing.SharingUtils; import org.hisp.dhis.dxf2.utils.JacksonUtils; import org.hisp.dhis.security.SecurityService; import org.hisp.dhis.user.CurrentUserService; === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetMetaDataAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetMetaDataAction.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetMetaDataAction.java 2014-03-21 09:41:08 +0000 @@ -37,7 +37,7 @@ import java.util.Set; import org.hisp.dhis.common.ListMap; -import org.hisp.dhis.common.SharingUtils; +import org.hisp.dhis.sharing.SharingUtils; import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator; import org.hisp.dhis.dataelement.DataElement; import org.hisp.dhis.dataelement.DataElementCategory;