=== modified 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 2013-03-15 17:37:07 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Access.java 2013-08-13 07:18:45 +0000 @@ -39,6 +39,8 @@ { private boolean manage; + private boolean externalize; + private boolean write; private boolean read; @@ -64,6 +66,18 @@ } @JsonProperty + @JacksonXmlProperty( localName = "manage", 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() { === 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 2013-08-12 08:56:50 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java 2013-08-13 07:18:45 +0000 @@ -90,6 +90,11 @@ protected Date lastUpdated; /** + * This object is available as external read-only + */ + protected boolean externalAccess; + + /** * Access string for public access. */ protected String publicAccess; @@ -121,14 +126,14 @@ public BaseIdentifiableObject() { } - + public BaseIdentifiableObject( int id, String uid, String name ) { this.id = id; this.uid = uid; this.name = name; } - + public BaseIdentifiableObject( String uid, String code, String name ) { this.uid = uid; @@ -256,6 +261,20 @@ this.publicAccess = publicAccess; } + @Override + @JsonProperty + @JsonView({ DetailedView.class, ExportView.class }) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) + public boolean getExternalAccess() + { + return externalAccess; + } + + public void setExternalAccess( Boolean externalAccess ) + { + this.externalAccess = externalAccess == null ? false : externalAccess; + } + /* @Override @JsonProperty @@ -446,12 +465,12 @@ { return "[IdentifiableObject: " + "id='" + id + - "', uid='" + uid + - "', code='" + code + - "', name='" + name + - "', created='" + created + - "', lastUpdated='" + lastUpdated + - "', class='" + getClass().getSimpleName() + + "', uid='" + uid + + "', code='" + code + + "', name='" + name + + "', created='" + created + + "', lastUpdated='" + lastUpdated + + "', class='" + getClass().getSimpleName() + "']"; } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/CodeGenerator.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/CodeGenerator.java 2013-01-28 18:38:14 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/CodeGenerator.java 2013-08-13 07:18:45 +0000 @@ -87,7 +87,7 @@ * @param code the code to validate. * @return true if the code is valid. */ - public boolean isValidCode( String code ) + public static boolean isValidCode( String code ) { return code != null && CODE_PATTERN.matcher( code ).matches(); } === 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 2013-03-15 17:37:07 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObject.java 2013-08-13 07:18:45 +0000 @@ -49,9 +49,7 @@ String getName(); - boolean haveUniqueNames(); - - boolean isAutoGenerated(); + String getDisplayName(); String getCode(); @@ -59,13 +57,17 @@ Date getLastUpdated(); + boolean haveUniqueNames(); + + boolean isAutoGenerated(); + String getPublicAccess(); + boolean getExternalAccess(); + User getUser(); Set getUserGroupAccesses(); - String getDisplayName(); - Access getAccess(); } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java 2013-08-06 10:26:03 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java 2013-08-13 07:18:45 +0000 @@ -47,6 +47,8 @@ T get( Class clazz, String uid ); + boolean exists( Class clazz, String uid ); + T getByCode( Class clazz, String code ); T getByName( Class clazz, String name ); === modified 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 2013-07-19 09:29:54 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/SharingUtils.java 2013-08-13 07:18:45 +0000 @@ -57,6 +57,8 @@ */ 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>(); @@ -65,13 +67,18 @@ public static final List SHARING_OVERRIDE_AUTHORITIES = Arrays.asList( "ALL", "F_METADATA_IMPORT" ); - private static void addType( Class clazz, String name, String publicAuth, String privateAuth ) + 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 ); @@ -85,20 +92,21 @@ static { - addType( Document.class, "document", "F_DOCUMENT_PUBLIC_ADD", "F_DOCUMENT_PRIVATE_ADD" ); - addType( Report.class, "report", "F_REPORT_PUBLIC_ADD", "F_REPORT_PRIVATE_ADD" ); - addType( DataSet.class, "dataSet", "F_DATASET_PUBLIC_ADD", "F_DATASET_PRIVATE_ADD" ); - addType( DataDictionary.class, "dataDictionary", "F_DATADICTIONARY_PUBLIC_ADD", "F_DATADICTIONARY_PRIVATE_ADD" ); - addType( Indicator.class, "indicator", "F_INDICATOR_PUBLIC_ADD", "F_INDICATOR_PRIVATE_ADD" ); - addType( IndicatorGroup.class, "indicatorGroup", "F_INDICATORGROUP_PUBLIC_ADD", "F_INDICATORGROUP_PRIVATE_ADD" ); - addType( IndicatorGroupSet.class, "indicatorGroupSet", "F_INDICATORGROUPSET_PUBLIC_ADD", "F_INDICATORGROUPSET_PRIVATE_ADD" ); - addType( Program.class, "program", "F_PROGRAM_PUBLIC_ADD", "F_PROGRAM_PRIVATE_ADD" ); - addType( UserGroup.class, "userGroup", "F_USERGROUP_PUBLIC_ADD", null ); - addType( ReportTable.class, "reportTable", "F_REPORTTABLE_PUBLIC_ADD", null ); - addType( org.hisp.dhis.mapping.Map.class, "map", "F_MAP_PUBLIC_ADD", null ); - addType( Chart.class, "chart", "F_CHART_PUBLIC_ADD", null ); - addType( PatientTabularReport.class, "patientTabularReport", "F_PATIENT_TABULAR_REPORT_PUBLIC_ADD", null ); - addType( PatientAggregateReport.class, "patientAggregateReport", "F_PATIENT_TABULAR_REPORT_PUBLIC_ADD", null ); + 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( 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( PatientTabularReport.class, "patientTabularReport", null, "F_PATIENT_TABULAR_REPORT_PUBLIC_ADD", null ); + addType( PatientAggregateReport.class, "patientAggregateReport", null, "F_PATIENT_TABULAR_REPORT_PUBLIC_ADD", null ); + + addType( org.hisp.dhis.mapping.Map.class, "map", "F_MAP_EXTERNAL_ADD", "F_MAP_PUBLIC_ADD", null ); + addType( Chart.class, "chart", "F_CHART_PUBLIC_ADD", "F_CHART_PUBLIC_ADD", null ); + addType( ReportTable.class, "reportTable", "F_REPORTTABLE_OPEN_ADD", "F_REPORTTABLE_PUBLIC_ADD", null ); } public static boolean isSupported( String type ) @@ -277,7 +285,7 @@ } /** - * Can user read this object + * Can user manage (make public) this object *

* 1. Does user have SHARING_OVERRIDE_AUTHORITY authority? * 2. Can user write to this object? @@ -308,6 +316,20 @@ 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 ) + { + return (object.getClass().isAssignableFrom( org.hisp.dhis.mapping.Map.class ) || + object.getClass().isAssignableFrom( ReportTable.class ) || + object.getClass().isAssignableFrom( Chart.class )) && sharingOverrideAuthority( user ); + } + private static boolean sharingOverrideAuthority( User user ) { return user == null || CollectionUtils.containsAny( user.getUserCredentials().getAllAuthorities(), SHARING_OVERRIDE_AUTHORITIES ); === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java 2013-08-06 10:26:03 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java 2013-08-13 07:18:45 +0000 @@ -125,7 +125,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public T get( Class clazz, String uid ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -139,7 +139,13 @@ } @Override - @SuppressWarnings( "unchecked" ) + public boolean exists( Class clazz, String uid ) + { + return get( clazz, uid ) != null; + } + + @Override + @SuppressWarnings("unchecked") public T getByCode( Class clazz, String code ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -153,7 +159,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public T getByName( Class clazz, String name ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -214,7 +220,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public Collection getAll( Class clazz ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -228,7 +234,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public Collection getAllSorted( Class clazz ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -242,7 +248,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public List getByUid( Class clazz, Collection uids ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -256,7 +262,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public Collection getLikeName( Class clazz, String name ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -270,7 +276,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public Collection getLikeShortName( Class clazz, String shortName ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -284,7 +290,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public List getBetween( Class clazz, int first, int max ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -298,7 +304,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public List getBetweenByName( Class clazz, String name, int first, int max ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -312,7 +318,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public Collection getByLastUpdated( Class clazz, Date lastUpdated ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -326,7 +332,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public Collection getByLastUpdatedSorted( Class clazz, Date lastUpdated ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -360,7 +366,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public Map getIdMap( Class clazz, IdentifiableProperty property ) { Map map = new HashMap(); @@ -410,7 +416,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public Map getIdMap( Class clazz, NameableProperty property ) { Map map = new HashMap(); @@ -434,7 +440,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public T getObject( Class clazz, IdentifiableProperty property, String id ) { GenericIdentifiableObjectStore store = (GenericIdentifiableObjectStore) getIdentifiableObjectStore( clazz ); @@ -507,7 +513,7 @@ } @Override - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") public T getNoAcl( Class clazz, String uid ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/security.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/security.xml 2012-12-14 13:46:47 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/security.xml 2013-08-13 07:18:45 +0000 @@ -1,8 +1,6 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> @@ -22,12 +20,4 @@ - - - - - - - - === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/mapping/hibernate/Map.hbm.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/mapping/hibernate/Map.hbm.xml 2013-03-13 15:03:10 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/mapping/hibernate/Map.hbm.xml 2013-08-13 07:18:45 +0000 @@ -37,6 +37,8 @@ + + === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml' --- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml 2013-08-09 14:10:43 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml 2013-08-13 07:18:45 +0000 @@ -146,6 +146,8 @@ + + === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml' --- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml 2013-08-09 14:10:43 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml 2013-08-13 07:18:45 +0000 @@ -79,7 +79,7 @@ - + @@ -135,29 +135,31 @@ - + - + - + - + - + - + - + - + - + + foreign-key="fk_reporttable_legendsetid" /> + + === 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 2013-08-06 09:40:40 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java 2013-08-13 07:18:45 +0000 @@ -324,6 +324,7 @@ { Access access = new Access(); access.setManage( SharingUtils.canManage( currentUserService.getCurrentUser(), object ) ); + access.setExternalize( SharingUtils.canExternalize( currentUserService.getCurrentUser(), object ) ); access.setWrite( SharingUtils.canWrite( currentUserService.getCurrentUser(), object ) ); access.setRead( SharingUtils.canRead( currentUserService.getCurrentUser(), object ) ); access.setUpdate( SharingUtils.canUpdate( currentUserService.getCurrentUser(), object ) ); === 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 2013-03-22 09:55:41 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/SharingController.java 2013-08-13 07:18:45 +0000 @@ -61,7 +61,7 @@ * @author Morten Olav Hansen */ @Controller -@RequestMapping(value = SharingController.RESOURCE_PATH, method = RequestMethod.GET) +@RequestMapping( value = SharingController.RESOURCE_PATH, method = RequestMethod.GET ) public class SharingController { private static final Log log = LogFactory.getLog( SharingController.class ); @@ -83,7 +83,7 @@ @Autowired private UserGroupAccessService userGroupAccessService; - @RequestMapping(value = "", produces = { "application/json", "text/*" }) + @RequestMapping( value = "", produces = { "application/json", "text/*" } ) public void getSharing( @RequestParam String type, @RequestParam String id, HttpServletResponse response ) throws IOException { if ( !SharingUtils.isSupported( type ) ) @@ -108,9 +108,11 @@ Sharing sharing = new Sharing(); sharing.getMeta().setAllowPublicAccess( SharingUtils.canCreatePublic( currentUserService.getCurrentUser(), object ) ); + sharing.getMeta().setAllowExternalAccess( SharingUtils.canExternalize( currentUserService.getCurrentUser(), object ) ); sharing.getObject().setId( object.getUid() ); sharing.getObject().setName( object.getDisplayName() ); + sharing.getObject().setExternalAccess( object.getExternalAccess() ); if ( object.getPublicAccess() == null ) { @@ -151,7 +153,7 @@ JacksonUtils.toJson( response.getOutputStream(), sharing ); } - @RequestMapping(value = "", method = { RequestMethod.POST, RequestMethod.PUT }, consumes = "application/json") + @RequestMapping( value = "", method = { RequestMethod.POST, RequestMethod.PUT }, consumes = "application/json" ) public void setSharing( @RequestParam String type, @RequestParam String id, HttpServletResponse response, HttpServletRequest request ) throws IOException { BaseIdentifiableObject object = (BaseIdentifiableObject) manager.get( SharingUtils.classForType( type ), id ); @@ -169,8 +171,13 @@ Sharing sharing = JacksonUtils.fromJson( request.getInputStream(), Sharing.class ); + // Ignore externalAccess if user is not allowed to make objects external + if ( SharingUtils.canExternalize( currentUserService.getCurrentUser(), object ) ) + { + object.setExternalAccess( sharing.getObject().hasExternalAccess() ); + } + // Ignore publicAccess if user is not allowed to make objects public - if ( SharingUtils.canCreatePublic( currentUserService.getCurrentUser(), object ) ) { object.setPublicAccess( sharing.getObject().getPublicAccess() ); @@ -215,6 +222,7 @@ builder.append( " update sharing on " ).append( object.getClass().getName() ); builder.append( ", uid: " ).append( object.getUid() ).append( ", name: " ).append( object.getName() ); builder.append( ", publicAccess: " ).append( object.getPublicAccess() ); + builder.append( ", externalAccess: " ).append( object.getExternalAccess() ); if ( !object.getUserGroupAccesses().isEmpty() ) { @@ -234,7 +242,7 @@ ContextUtils.okResponse( response, "Access control set" ); } - @RequestMapping(value = "/search", produces = { "application/json", "text/*" }) + @RequestMapping( value = "/search", produces = { "application/json", "text/*" } ) public void searchUserGroups( @RequestParam String key, HttpServletResponse response ) throws IOException { SharingUserGroups sharingUserGroups = new SharingUserGroups(); === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/Meta.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/Meta.java 2013-01-18 15:54:53 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/Meta.java 2013-08-13 07:18:45 +0000 @@ -37,6 +37,9 @@ @JsonProperty private boolean allowPublicAccess; + @JsonProperty + private boolean allowExternalAccess; + public Meta() { } @@ -50,4 +53,14 @@ { this.allowPublicAccess = allowPublicAccess; } + + public boolean isAllowExternalAccess() + { + return allowExternalAccess; + } + + public void setAllowExternalAccess( boolean allowExternalAccess ) + { + this.allowExternalAccess = allowExternalAccess; + } } === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingObject.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingObject.java 2013-01-18 12:58:45 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingObject.java 2013-08-13 07:18:45 +0000 @@ -47,6 +47,9 @@ private String publicAccess; @JsonProperty + private boolean externalAccess; + + @JsonProperty private SharingUser user = new SharingUser(); @JsonProperty @@ -86,6 +89,16 @@ this.publicAccess = publicAccess; } + public boolean hasExternalAccess() + { + return externalAccess; + } + + public void setExternalAccess( boolean externalAccess ) + { + this.externalAccess = externalAccess; + } + public SharingUser getUser() { return user; === modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.sharing.js' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.sharing.js 2013-05-02 13:55:39 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.sharing.js 2013-08-13 07:18:45 +0000 @@ -109,6 +109,18 @@ return $( '#sharingPublicAccess' ).val(); } +function setExternalAccess(access) { + if(access) { + $('#sharingExternalAccess').attr('checked', true); + } else { + $('#sharingExternalAccess').removeAttr('checked'); + } +} + +function getExternalAccess() { + return $('#sharingExternalAccess').is(':checked'); +} + function getUserGroupAccesses() { var v = []; @@ -131,14 +143,20 @@ function showSharingDialog( type, uid ) { loadSharingSettings( type, uid ).done( function ( data ) { setPublicAccess( data.object.publicAccess ); + setExternalAccess( data.object.externalAccess ); setUserGroupAccesses( data.object.userGroupAccesses ); $( '#sharingName' ).text( data.object.name ); + if ( !data.meta.allowExternalAccess ) { + $( '#sharingExternalAccess' ).attr( 'disabled', true ); + } + if ( !data.meta.allowPublicAccess ) { $( '#sharingPublicAccess' ).attr( 'disabled', true ); } + $( '.removeUserGroupAccess' ).unbind( 'click' ); $( document ).on( 'click', '.removeUserGroupAccess', removeUserGroupAccess ); $( '#addUserGroupAccess' ).unbind( 'click' ).bind( 'click', addUserGroupAccessSelectedItem ); @@ -200,6 +218,7 @@ var me = $( this ); data.object.publicAccess = getPublicAccess(); + data.object.externalAccess = getExternalAccess(); data.object.userGroupAccesses = getUserGroupAccesses(); saveSharingSettings( type, uid, data ).done( function () { === modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/macros.vm' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/macros.vm 2013-07-18 05:21:15 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/macros.vm 2013-08-13 07:18:45 +0000 @@ -335,17 +335,24 @@ - - - - - + + + + + + + + + +
$i18n.getString( "public_access" ) - -
$i18n.getString( "external_access" ) + +
$i18n.getString( "public_access" ) + +
=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/GhostAutomaticAccessProvider.java' --- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/GhostAutomaticAccessProvider.java 2011-12-26 10:07:59 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/GhostAutomaticAccessProvider.java 2013-08-13 07:18:45 +0000 @@ -30,13 +30,14 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; /** * This access provider will put an Authentication object with all GrantedAuthorities * in the SecurityContext in any case. This means that any user will be authenticated - * and the login effectively bypassed. - * + * and the login effectively bypassed. + * * @author Torgeir Lorange Ostby * @version $Id: GhostAutomaticAccessProvider.java 3160 2007-03-24 20:15:06Z torgeilo $ */ @@ -54,7 +55,7 @@ String username = "ghost_admin"; String password = ""; - UserDetails user = new org.springframework.security.core.userdetails.User( username, password, true, true, true, true, + UserDetails user = new User( username, password, true, true, true, true, getGrantedAuthorities() ); authentication = new UsernamePasswordAuthenticationToken( user, user.getPassword(), user.getAuthorities() ); === modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/vote/ActionAccessVoter.java' --- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/vote/ActionAccessVoter.java 2013-01-17 13:32:15 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/vote/ActionAccessVoter.java 2013-08-13 07:18:45 +0000 @@ -1,7 +1,7 @@ package org.hisp.dhis.security.vote; /* - * Copyright (c) 2004-2012, University of Oslo + * Copyright (c) 2004-2013, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without === added file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/vote/ExternalAccessVoter.java' --- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/vote/ExternalAccessVoter.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/vote/ExternalAccessVoter.java 2013-08-13 07:18:45 +0000 @@ -0,0 +1,122 @@ +package org.hisp.dhis.security.vote; + +/* + * Copyright (c) 2004-2013, 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 org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hisp.dhis.chart.Chart; +import org.hisp.dhis.common.CodeGenerator; +import org.hisp.dhis.common.IdentifiableObject; +import org.hisp.dhis.common.IdentifiableObjectManager; +import org.hisp.dhis.reporttable.ReportTable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.AccessDecisionVoter; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.FilterInvocation; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * Allows certain type/uid combinations to be externally accessed (no login required). + * + * @author Morten Olav Hansen + */ +public class ExternalAccessVoter implements AccessDecisionVoter +{ + private static final Log LOG = LogFactory.getLog( ExternalAccessVoter.class ); + + // this should probably be moved somewhere else, but leaving it here for now + private static final Map> externalClasses = new HashMap>(); + + static + { + externalClasses.put( "charts", Chart.class ); + externalClasses.put( "maps", org.hisp.dhis.mapping.Map.class ); + externalClasses.put( "reportTables", ReportTable.class ); + } + + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + @Autowired + private IdentifiableObjectManager manager; + + // ------------------------------------------------------------------------- + // AccessDecisionVoter Implementation + // ------------------------------------------------------------------------- + + @Override + public boolean supports( ConfigAttribute attribute ) + { + return false; + } + + @Override + public boolean supports( Class clazz ) + { + return clazz.isAssignableFrom( FilterInvocation.class ); + } + + @Override + public int vote( Authentication authentication, FilterInvocation filterInvocation, Collection attributes ) + { + if ( authentication.getPrincipal().equals( "anonymousUser" ) && authentication.isAuthenticated() && + filterInvocation.getRequest().getMethod().equals( RequestMethod.GET.name() ) ) + { + String requestUrl = filterInvocation.getRequestUrl(); + String[] urlSplit = requestUrl.split( "/" ); + String type = urlSplit[2]; + + if ( urlSplit[1].equals( "api" ) && externalClasses.get( type ) != null ) + { + String uid = urlSplit[3]; + + if ( CodeGenerator.isValidCode( uid ) ) + { + IdentifiableObject identifiableObject = manager.get( externalClasses.get( type ), uid ); + + if ( identifiableObject != null && identifiableObject.getExternalAccess() ) + { + LOG.debug( "ACCESS_GRANTED [" + filterInvocation.toString() + "]" ); + + return ACCESS_GRANTED; + } + } + } + } + + LOG.debug( "ACCESS_ABSTAIN [" + filterInvocation.toString() + "]: No supported attributes." ); + + return ACCESS_ABSTAIN; + } +} === modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml' --- dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml 2013-04-03 15:09:54 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml 2013-08-13 07:18:45 +0000 @@ -68,6 +68,16 @@ + + + + + + + + + + @@ -83,12 +93,17 @@ + + + + + @@ -113,6 +128,14 @@ + + + + + + + + @@ -123,9 +146,6 @@ - - - === modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/resources/i18n_global.properties' --- dhis-2/dhis-web/dhis-web-commons/src/main/resources/i18n_global.properties 2013-07-26 13:53:21 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/resources/i18n_global.properties 2013-08-13 07:18:45 +0000 @@ -644,7 +644,8 @@ #-- Sharing ------------------------------------------------------------------# -public_access=Public access +public_access=Public access (with login) +external_access=External access (without login) user_group_access=Us ajax_login_failed=Login failed, check your username and password and try againer group access group_name=Group name