← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 14836: Analytics, created new bean AnalyticsSecurityManager, moved over some methods from QueryPlanner

 

------------------------------------------------------------
revno: 14836
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2014-04-14 10:42:46 +0200
message:
  Analytics, created new bean AnalyticsSecurityManager, moved over some methods from QueryPlanner
added:
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsSecurityManager.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/security/
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/security/DefaultAnalyticsSecurityManager.java
modified:
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/QueryPlanner.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryPlanner.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventQueryPlanner.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/beans.xml


--
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
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsSecurityManager.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsSecurityManager.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsSecurityManager.java	2014-04-14 08:42:46 +0000
@@ -0,0 +1,25 @@
+package org.hisp.dhis.analytics;
+
+import org.hisp.dhis.common.IllegalQueryException;
+
+public interface AnalyticsSecurityManager
+{    
+    /**
+     * Decides whether the current user has privileges to execute the given query.
+     * 
+     * @param params the data query params.
+     * @throws IllegalQueryException if the current user does not have privileges
+     *         to execute the given query.
+     */
+    void decideAccess( DataQueryParams params );
+    
+    /**
+     * Applies dimension constraints to the given params. Dimension constraints
+     * with all accessible dimension items will be added as filters to this query.
+     * If current user has no dimension constraints, no action is taken. If the 
+     * constraint dimensions are already specified with accessible items in the 
+     * query, no action is taken. If the current user does not have accessible 
+     * items in any dimension constraint, an IllegalQueryException is thrown.
+     */
+    void applyDimensionConstraints( DataQueryParams params );
+}

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2014-04-10 21:12:18 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2014-04-14 08:42:46 +0000
@@ -175,6 +175,11 @@
      * Organisation units which were explicitly part of the original request.
      */
     private List<OrganisationUnit> organisationUnits = new ArrayList<OrganisationUnit>();
+
+    /**
+     * Mapping of organisation unit sub-hierarchy roots and lowest available data approval levels.
+     */
+    private Map<OrganisationUnit, Integer> approvalLevels = new HashMap<OrganisationUnit, Integer>();
     
     // -------------------------------------------------------------------------
     // Constructors
@@ -202,6 +207,7 @@
         params.dataPeriodType = this.dataPeriodType;
         params.skipPartitioning = this.skipPartitioning;
         params.organisationUnits = new ArrayList<OrganisationUnit>( this.organisationUnits );
+        params.approvalLevels = new HashMap<OrganisationUnit, Integer>( this.approvalLevels );
         
         return params;
     }
@@ -864,6 +870,14 @@
         return filterItems;
     }
     
+    /**
+     * Indicates whether this params specifies data approval levels.
+     */
+    public boolean isDataApproval()
+    {
+        return approvalLevels != null && !approvalLevels.isEmpty();
+    }
+    
     // -------------------------------------------------------------------------
     // Static methods
     // -------------------------------------------------------------------------
@@ -1130,6 +1144,16 @@
         this.skipPartitioning = skipPartitioning;
     }
 
+    public Map<OrganisationUnit, Integer> getApprovalLevels()
+    {
+        return approvalLevels;
+    }
+
+    public void setApprovalLevels( Map<OrganisationUnit, Integer> approvalLevels )
+    {
+        this.approvalLevels = approvalLevels;
+    }
+
     // -------------------------------------------------------------------------
     // Get and set helpers for dimensions or filter
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/QueryPlanner.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/QueryPlanner.java	2014-04-11 07:50:58 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/QueryPlanner.java	2014-04-14 08:42:46 +0000
@@ -111,23 +111,4 @@
      * names respectively.
      */
     List<DataQueryParams> groupByPeriodType( DataQueryParams params );
-    
-    /**
-     * Decides whether the current user has privileges to execute the given query.
-     * 
-     * @param params the data query params.
-     * @throws IllegalQueryException if the current user does not have privileges
-     *         to execute the given query.
-     */
-    void decideAccess( DataQueryParams params );
-    
-    /**
-     * Applies dimension constraints to the given params. Dimension constraints
-     * with all accessible dimension items will be added as filters to this query.
-     * If current user has no dimension constraints, no action is taken. If the 
-     * constraint dimensions are already specified with accessible items in the 
-     * query, no action is taken. If the current user does not have accessible 
-     * items in any dimension constraint, an IllegalQueryException is thrown.
-     */
-    void applyDimensionConstraints( DataQueryParams params );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2014-04-11 07:50:58 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2014-04-14 08:42:46 +0000
@@ -82,6 +82,7 @@
 import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.analytics.AggregationType;
 import org.hisp.dhis.analytics.AnalyticsManager;
+import org.hisp.dhis.analytics.AnalyticsSecurityManager;
 import org.hisp.dhis.analytics.AnalyticsService;
 import org.hisp.dhis.analytics.DataQueryGroups;
 import org.hisp.dhis.analytics.DataQueryParams;
@@ -159,6 +160,9 @@
     private AnalyticsManager analyticsManager;
     
     @Autowired
+    private AnalyticsSecurityManager securityManager;
+    
+    @Autowired
     private QueryPlanner queryPlanner;
     
     @Autowired
@@ -203,9 +207,9 @@
     @Override
     public Grid getAggregatedDataValues( DataQueryParams params )
     {
-        queryPlanner.decideAccess( params );
+        securityManager.decideAccess( params );
         
-        queryPlanner.applyDimensionConstraints( params );
+        securityManager.applyDimensionConstraints( params );
         
         queryPlanner.validate( params );
         

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2014-04-11 07:50:58 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2014-04-14 08:42:46 +0000
@@ -47,7 +47,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -58,7 +57,6 @@
 import org.hisp.dhis.analytics.QueryPlanner;
 import org.hisp.dhis.analytics.table.PartitionUtils;
 import org.hisp.dhis.common.BaseDimensionalObject;
-import org.hisp.dhis.common.DimensionService;
 import org.hisp.dhis.common.DimensionType;
 import org.hisp.dhis.common.DimensionalObject;
 import org.hisp.dhis.common.IllegalQueryException;
@@ -71,8 +69,6 @@
 import org.hisp.dhis.period.PeriodType;
 import org.hisp.dhis.system.util.MathUtils;
 import org.hisp.dhis.system.util.PaginatedList;
-import org.hisp.dhis.user.CurrentUserService;
-import org.hisp.dhis.user.User;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -88,12 +84,6 @@
     @Autowired
     private OrganisationUnitService organisationUnitService;
     
-    @Autowired
-    private DimensionService dimensionService;
-    
-    @Autowired
-    private CurrentUserService currentUserService;
-    
     // -------------------------------------------------------------------------
     // DefaultQueryPlanner implementation
     // -------------------------------------------------------------------------
@@ -295,129 +285,6 @@
     // Dimension constraints methods
     // -------------------------------------------------------------------------
     
-    public void decideAccess( DataQueryParams params )
-    {
-        // ---------------------------------------------------------------------
-        // Check current user data view access to org units
-        // ---------------------------------------------------------------------
-        
-        User user = currentUserService.getCurrentUser();
-        
-        List<NameableObject> queryOrgUnits = params.getDimensionOrFilter( DimensionalObject.ORGUNIT_DIM_ID );
-        
-        if ( queryOrgUnits == null || user == null || !user.hasDataViewOrganisationUnit() )
-        {
-            return;
-        }
-        
-        Set<OrganisationUnit> viewOrgUnits = user.getDataViewOrganisationUnits();
-        
-        for ( NameableObject object : queryOrgUnits )
-        {
-            OrganisationUnit queryOrgUnit = (OrganisationUnit) object;
-            
-            if ( !queryOrgUnit.isEqualOrChildOf( viewOrgUnits ) )
-            {
-                throw new IllegalQueryException( "Org unit is not viewable for current user: " + queryOrgUnit.getUid() );
-            }
-        }
-    }
-    
-    public void applyDimensionConstraints( DataQueryParams params )
-    {
-        applyOrganisationUnitConstraint( params );
-        applyUserConstraints( params );
-    }
-
-    private void applyOrganisationUnitConstraint( DataQueryParams params )
-    {
-        User user = currentUserService.getCurrentUser();
-
-        // ---------------------------------------------------------------------
-        // Check if current user has data view organisation units
-        // ---------------------------------------------------------------------
-
-        if ( params == null || user == null || !user.hasDataViewOrganisationUnit() )
-        {
-            return;
-        }
-
-        // ---------------------------------------------------------------------
-        // Check if request already has organisation units specified
-        // ---------------------------------------------------------------------
-
-        if ( params.hasDimensionOrFilterWithItems( DimensionalObject.ORGUNIT_DIM_ID ) )
-        {
-            return;
-        }
-        
-        // -----------------------------------------------------------------
-        // Apply constraint as filter, and remove potential all-dimension
-        // -----------------------------------------------------------------
-
-        params.removeDimensionOrFilter( DimensionalObject.ORGUNIT_DIM_ID );
-
-        List<OrganisationUnit> orgUnits = new ArrayList<OrganisationUnit>( user.getDataViewOrganisationUnits() );
-
-        DimensionalObject constraint = new BaseDimensionalObject( DimensionalObject.ORGUNIT_DIM_ID, DimensionType.ORGANISATIONUNIT, orgUnits );
-        
-        params.getFilters().add( constraint );
-
-        log.info( "User: " + user.getUsername() + " constrained by data view organisation units" );        
-    }
-    
-    private void applyUserConstraints( DataQueryParams params )
-    {
-        User user = currentUserService.getCurrentUser();
-
-        // ---------------------------------------------------------------------
-        // Check if current user has dimension constraints
-        // ---------------------------------------------------------------------
-
-        if ( params == null || user == null || user.getUserCredentials() == null || !user.getUserCredentials().hasDimensionConstraints() )
-        {
-            return;
-        }
-                
-        Set<DimensionalObject> dimensionConstraints = user.getUserCredentials().getDimensionConstraints();
-        
-        for ( DimensionalObject dimension : dimensionConstraints )
-        {
-            // -----------------------------------------------------------------
-            // Check if constraint already is specified with items
-            // -----------------------------------------------------------------
-
-            if ( params.hasDimensionOrFilterWithItems( dimension.getUid() ) )
-            {
-                continue;
-            }
-
-            List<NameableObject> canReadItems = dimensionService.getCanReadDimensionItems( dimension.getDimension() );
-
-            // -----------------------------------------------------------------
-            // Check if current user has access to any items from constraint
-            // -----------------------------------------------------------------
-
-            if ( canReadItems == null || canReadItems.isEmpty() )
-            {
-                throw new IllegalQueryException( "Current user is constrained by a dimension but has access to no associated dimension items: " + dimension.getDimension() );
-            }
-
-            // -----------------------------------------------------------------
-            // Apply constraint as filter, and remove potential all-dimension
-            // -----------------------------------------------------------------
-
-            params.removeDimensionOrFilter( dimension.getDimension() );
-            
-            DimensionalObject constraint = new BaseDimensionalObject( dimension.getDimension(), 
-                dimension.getDimensionType(), null, dimension.getDisplayName(), canReadItems );
-            
-            params.getFilters().add( constraint );
-
-            log.info( "User: " + user.getUsername() + " constrained by dimension: " + constraint.getDimension() );
-        }        
-    }
-    
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryPlanner.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryPlanner.java	2014-04-11 07:58:35 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryPlanner.java	2014-04-14 08:42:46 +0000
@@ -30,7 +30,6 @@
 
 import java.util.List;
 
-import org.hisp.dhis.analytics.DataQueryParams;
 import org.hisp.dhis.common.IllegalQueryException;
 
 /**
@@ -56,13 +55,4 @@
      * @param params the query params.
      */
     EventQueryParams planEventQuery( EventQueryParams params );
-
-    /**
-     * Decides whether the current user has privileges to execute the given query.
-     * 
-     * @param params the data query params.
-     * @throws IllegalQueryException if the current user does not have privileges
-     *         to execute the given query.
-     */
-    void decideAccess( DataQueryParams params );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java	2014-04-11 07:58:35 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java	2014-04-14 08:42:46 +0000
@@ -44,6 +44,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.hisp.dhis.analytics.AnalyticsSecurityManager;
 import org.hisp.dhis.analytics.AnalyticsService;
 import org.hisp.dhis.analytics.SortOrder;
 import org.hisp.dhis.analytics.event.EventAnalyticsManager;
@@ -114,6 +115,9 @@
     private EventAnalyticsManager analyticsManager;
 
     @Autowired
+    private AnalyticsSecurityManager securityManager;
+    
+    @Autowired
     private EventQueryPlanner queryPlanner;
 
     @Autowired
@@ -128,7 +132,7 @@
 
     public Grid getAggregatedEventData( EventQueryParams params )
     {
-        queryPlanner.decideAccess( params );
+        securityManager.decideAccess( params );
         
         queryPlanner.validate( params );
         
@@ -194,7 +198,7 @@
 
     public Grid getEvents( EventQueryParams params )
     {
-        queryPlanner.decideAccess( params );
+        securityManager.decideAccess( params );
         
         queryPlanner.validate( params );
 

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventQueryPlanner.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventQueryPlanner.java	2014-04-11 07:58:35 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventQueryPlanner.java	2014-04-14 08:42:46 +0000
@@ -169,11 +169,6 @@
         return params;
     }
     
-    public void decideAccess( DataQueryParams params )
-    {
-        queryPlanner.decideAccess( params );
-    }
-
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------

=== added directory 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/security'
=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/security/DefaultAnalyticsSecurityManager.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/security/DefaultAnalyticsSecurityManager.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/security/DefaultAnalyticsSecurityManager.java	2014-04-14 08:42:46 +0000
@@ -0,0 +1,157 @@
+package org.hisp.dhis.analytics.security;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.analytics.AnalyticsSecurityManager;
+import org.hisp.dhis.analytics.DataQueryParams;
+import org.hisp.dhis.common.BaseDimensionalObject;
+import org.hisp.dhis.common.DimensionService;
+import org.hisp.dhis.common.DimensionType;
+import org.hisp.dhis.common.DimensionalObject;
+import org.hisp.dhis.common.IllegalQueryException;
+import org.hisp.dhis.common.NameableObject;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.user.CurrentUserService;
+import org.hisp.dhis.user.User;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultAnalyticsSecurityManager
+    implements AnalyticsSecurityManager
+{
+    private static final Log log = LogFactory.getLog( DefaultAnalyticsSecurityManager.class );
+    
+    @Autowired
+    private CurrentUserService currentUserService;
+    
+    @Autowired
+    private DimensionService dimensionService;
+
+    public void decideAccess( DataQueryParams params )
+    {
+        // ---------------------------------------------------------------------
+        // Check current user data view access to org units
+        // ---------------------------------------------------------------------
+        
+        User user = currentUserService.getCurrentUser();
+        
+        List<NameableObject> queryOrgUnits = params.getDimensionOrFilter( DimensionalObject.ORGUNIT_DIM_ID );
+        
+        if ( queryOrgUnits == null || user == null || !user.hasDataViewOrganisationUnit() )
+        {
+            return;
+        }
+        
+        Set<OrganisationUnit> viewOrgUnits = user.getDataViewOrganisationUnits();
+        
+        for ( NameableObject object : queryOrgUnits )
+        {
+            OrganisationUnit queryOrgUnit = (OrganisationUnit) object;
+            
+            if ( !queryOrgUnit.isEqualOrChildOf( viewOrgUnits ) )
+            {
+                throw new IllegalQueryException( "Org unit is not viewable for current user: " + queryOrgUnit.getUid() );
+            }
+        }
+    }
+    
+    public void applyDimensionConstraints( DataQueryParams params )
+    {
+        applyOrganisationUnitConstraint( params );
+        applyUserConstraints( params );
+    }
+
+    private void applyOrganisationUnitConstraint( DataQueryParams params )
+    {
+        User user = currentUserService.getCurrentUser();
+
+        // ---------------------------------------------------------------------
+        // Check if current user has data view organisation units
+        // ---------------------------------------------------------------------
+
+        if ( params == null || user == null || !user.hasDataViewOrganisationUnit() )
+        {
+            return;
+        }
+
+        // ---------------------------------------------------------------------
+        // Check if request already has organisation units specified
+        // ---------------------------------------------------------------------
+
+        if ( params.hasDimensionOrFilterWithItems( DimensionalObject.ORGUNIT_DIM_ID ) )
+        {
+            return;
+        }
+        
+        // -----------------------------------------------------------------
+        // Apply constraint as filter, and remove potential all-dimension
+        // -----------------------------------------------------------------
+
+        params.removeDimensionOrFilter( DimensionalObject.ORGUNIT_DIM_ID );
+
+        List<OrganisationUnit> orgUnits = new ArrayList<OrganisationUnit>( user.getDataViewOrganisationUnits() );
+
+        DimensionalObject constraint = new BaseDimensionalObject( DimensionalObject.ORGUNIT_DIM_ID, DimensionType.ORGANISATIONUNIT, orgUnits );
+        
+        params.getFilters().add( constraint );
+
+        log.info( "User: " + user.getUsername() + " constrained by data view organisation units" );        
+    }
+    
+    private void applyUserConstraints( DataQueryParams params )
+    {
+        User user = currentUserService.getCurrentUser();
+
+        // ---------------------------------------------------------------------
+        // Check if current user has dimension constraints
+        // ---------------------------------------------------------------------
+
+        if ( params == null || user == null || user.getUserCredentials() == null || !user.getUserCredentials().hasDimensionConstraints() )
+        {
+            return;
+        }
+                
+        Set<DimensionalObject> dimensionConstraints = user.getUserCredentials().getDimensionConstraints();
+        
+        for ( DimensionalObject dimension : dimensionConstraints )
+        {
+            // -----------------------------------------------------------------
+            // Check if constraint already is specified with items
+            // -----------------------------------------------------------------
+
+            if ( params.hasDimensionOrFilterWithItems( dimension.getUid() ) )
+            {
+                continue;
+            }
+
+            List<NameableObject> canReadItems = dimensionService.getCanReadDimensionItems( dimension.getDimension() );
+
+            // -----------------------------------------------------------------
+            // Check if current user has access to any items from constraint
+            // -----------------------------------------------------------------
+
+            if ( canReadItems == null || canReadItems.isEmpty() )
+            {
+                throw new IllegalQueryException( "Current user is constrained by a dimension but has access to no associated dimension items: " + dimension.getDimension() );
+            }
+
+            // -----------------------------------------------------------------
+            // Apply constraint as filter, and remove potential all-dimension
+            // -----------------------------------------------------------------
+
+            params.removeDimensionOrFilter( dimension.getDimension() );
+            
+            DimensionalObject constraint = new BaseDimensionalObject( dimension.getDimension(), 
+                dimension.getDimensionType(), null, dimension.getDisplayName(), canReadItems );
+            
+            params.getFilters().add( constraint );
+
+            log.info( "User: " + user.getUsername() + " constrained by dimension: " + constraint.getDimension() );
+        }        
+    }
+    
+
+}

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/beans.xml	2014-03-26 18:14:37 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/resources/META-INF/dhis/beans.xml	2014-04-14 08:42:46 +0000
@@ -42,6 +42,8 @@
   
   <bean id="org.hisp.dhis.analytics.QueryPlanner" class="org.hisp.dhis.analytics.data.DefaultQueryPlanner" />
 
+  <bean id="org.hisp.dhis.analytics.AnalyticsSecurityManager" class="org.hisp.dhis.analytics.security.DefaultAnalyticsSecurityManager" />
+
   <!-- Event analytics -->
 
   <bean id="org.hisp.dhis.analytics.event.EventAnalyticsManager" class="org.hisp.dhis.analytics.event.data.JdbcEventAnalyticsManager"/>