← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 9429: sharing, wip

 

------------------------------------------------------------
revno: 9429
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2013-01-03 13:43:44 +0100
message:
  sharing, wip
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupAccessService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupAccessService.java
  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/webdomain/sharing/
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/Sharing.java
  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/SharingUser.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingUserGroupAccess.java
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.sharing.js
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/AccessHelper.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GenericIdentifiableObjectStore.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/document/Document.java
  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/SecurityService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupService.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/document/hibernate/Document.hbm.xml
  dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/hibernate/HibernateGenericStore.java
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm
  dhis-2/dhis-web/dhis-web-commons/pom.xml
  dhis-2/dhis-web/dhis-web-commons/src/main/resources/dhis-web-commons.xml
  dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/document/action/SaveDocumentAction.java


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

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/AccessHelper.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/AccessHelper.java	2012-12-27 21:07:09 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/AccessHelper.java	2013-01-03 12:43:44 +0000
@@ -32,9 +32,9 @@
  */
 public class AccessHelper
 {
-    public final String DEFAULT_ACCESS = "--------";
+    public static final String DEFAULT_ACCESS = "--------";
 
-    public enum Permission
+    public static enum Permission
     {
         READ( 'r', 0 ), WRITE( 'w', 1 );
 
@@ -103,4 +103,19 @@
     {
         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.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	2012-12-27 21:07:09 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java	2013-01-03 12:43:44 +0000
@@ -338,8 +338,10 @@
 
         if ( user == null && publicAccess == null && userGroupAccesses.isEmpty() )
         {
-            publicAccess = AccessHelper.newInstance().enable( AccessHelper.Permission.READ )
-                .enable( AccessHelper.Permission.WRITE ).build();
+            publicAccess = AccessHelper.newInstance()
+                .enable( AccessHelper.Permission.READ )
+                .enable( AccessHelper.Permission.WRITE )
+                .build();
         }
 
         Date date = new Date();

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GenericIdentifiableObjectStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GenericIdentifiableObjectStore.java	2012-12-13 11:53:32 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GenericIdentifiableObjectStore.java	2013-01-03 12:43:44 +0000
@@ -27,12 +27,13 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import org.hisp.dhis.user.User;
+import org.hisp.dhis.user.UserGroup;
+
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
-import org.hisp.dhis.user.User;
-
 /**
  * @author Lars Helge Overland
  */
@@ -57,53 +58,53 @@
 
     /**
      * Retrieves the object with the given code.
-     * 
+     *
      * @param name the code.
      * @return the object with the given code.
      */
     T getByCode( String code );
-    
+
     /**
      * Retrieves the objects determined by the given first result and max result.
-     * 
+     *
      * @param first the first result object to return.
-     * @param max the max number of result objects to return. 
+     * @param max   the max number of result objects to return.
      * @return collection of objects.
      */
     Collection<T> getBetween( int first, int max );
 
     /**
      * Retrieves the objects determined by the given first result and max result.
-     * The returned list is ordered by the last updated property descending. 
-     * 
+     * The returned list is ordered by the last updated property descending.
+     *
      * @param first the first result object to return.
-     * @param max the max number of result objects to return. 
+     * @param max   the max number of result objects to return.
      * @return collection of objects.
      */
     List<T> getBetweenOrderderByLastUpdated( int first, int max );
-    
+
     /**
      * Retrieves the objects determined by the given first result and max result
      * which name is like the given name.
-     * 
-     * @param the name which result object names must be like.
+     *
+     * @param the   name which result object names must be like.
      * @param first the first result object to return.
-     * @param max the max number of result objects to return. 
+     * @param max   the max number of result objects to return.
      * @return collection of objects.
-     */    
+     */
     Collection<T> getBetweenByName( String name, int first, int max );
-    
+
     /**
      * Gets the count of objects which name is like the given name.
-     * 
+     *
      * @param name the name which result object names must be like.
      * @return the count of objects.
      */
     int getCountByName( String name );
-    
+
     /**
      * Retrieves a list of objects referenced by the given collection of uids.
-     * 
+     *
      * @param uids a collection of uids.
      * @return a list of objects.
      */
@@ -141,19 +142,19 @@
      * @return the number of objects equal or newer than given date.
      */
     long getCountByLastUpdated( Date lastUpdated );
-    
+
     /**
      * Retrieves objects associated with the given user.
-     * 
+     *
      * @param user the user.
-     * @param a list of objects.
+     * @param a    list of objects.
      */
     Collection<T> getByUser( User user );
-    
+
     /**
      * Retrieves objects which are accessible to the given user, which includes
      * public objects and objects owned by this user.
-     * 
+     *
      * @param user the user.
      * @return a list of objects.
      */
@@ -161,47 +162,47 @@
 
     /**
      * Retrieves objects which are accessible to the given user, which includes
-     * public objects and objects owned by this user, that are equal to or newer 
+     * public objects and objects owned by this user, that are equal to or newer
      * than given date.
-     * 
-     * @param user the user.
+     *
+     * @param user        the user.
      * @param lastUpdated the Date to compare with.
      * @return a list of objects.
      */
     List<T> getAccessibleByLastUpdated( User user, Date lastUpdated );
-    
+
     /**
      * Retrieves objects which are accessible to the given user, which includes
      * public objects and objects owned by this user, which name is like the
      * given name.
-     * 
+     *
      * @param user the user.
      * @param name the name.
      * @return a list of objects.
      */
     List<T> getAccessibleLikeName( User user, String name );
-    
+
     /**
      * Retrieves objects which are accessible to the given user, which includes
-     * public objects and objects owned by this user, limited by the given offset 
+     * public objects and objects owned by this user, limited by the given offset
      * and max result.
-     * 
-     * @param user the user.
+     *
+     * @param user  the user.
      * @param first the first result object to return.
-     * @param max the max number of result objects to return. 
+     * @param max   the max number of result objects to return.
      * @return a list of objects.
      */
     List<T> getAccessibleBetween( User user, int first, int max );
-    
+
     /**
      * Retrieves objects which are accessible to the given user, which includes
      * public objects and objects owned by this user, which name is like the
      * given name, limited by the given offset and max result.
-     * 
-     * @param user the user.
-     * @param name the name.
+     *
+     * @param user  the user.
+     * @param name  the name.
      * @param first the first result object to return.
-     * @param max the max number of result objects to return. 
+     * @param max   the max number of result objects to return.
      * @return a list of objects.
      */
     List<T> getAccessibleBetweenLikeName( User user, String name, int first, int max );

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/document/Document.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/document/Document.java	2012-04-11 04:56:20 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/document/Document.java	2013-01-03 12:43:44 +0000
@@ -1,15 +1,5 @@
 package org.hisp.dhis.document;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
-import org.hisp.dhis.common.BaseIdentifiableObject;
-import org.hisp.dhis.common.Dxf2Namespace;
-import org.hisp.dhis.common.IdentifiableObject;
-import org.hisp.dhis.common.view.DetailedView;
-import org.hisp.dhis.common.view.ExportView;
-
 /*
  * Copyright (c) 2004-2012, University of Oslo
  * All rights reserved.
@@ -37,6 +27,16 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonView;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import org.hisp.dhis.common.BaseIdentifiableObject;
+import org.hisp.dhis.common.Dxf2Namespace;
+import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.common.view.DetailedView;
+import org.hisp.dhis.common.view.ExportView;
+
 /**
  * @author Lars Helge Overland
  */

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupAccessService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupAccessService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupAccessService.java	2013-01-03 12:43:44 +0000
@@ -0,0 +1,43 @@
+package org.hisp.dhis.user;
+
+/*
+ * Copyright (c) 2004-2012, 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.Collection;
+
+public interface UserGroupAccessService
+{
+    String ID = UserGroupAccessService.class.getName();
+
+    void addUserGroupAccess( UserGroupAccess userGroupAccess );
+
+    void updateUserGroupAccess( UserGroupAccess userGroupAccess );
+
+    void deleteUserGroupAccess( UserGroupAccess userGroupAccess );
+
+    Collection<UserGroupAccess> getAllUserGroupAccesses();
+}

=== 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	2012-12-27 14:07:54 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/DefaultSecurityService.java	2013-01-03 12:43:44 +0000
@@ -29,6 +29,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.common.AccessHelper;
 import org.hisp.dhis.common.CodeGenerator;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.message.MessageSender;
@@ -36,10 +37,13 @@
 import org.hisp.dhis.setting.SystemSettingManager;
 import org.hisp.dhis.system.util.ValidationUtils;
 import org.hisp.dhis.system.velocity.VelocityManager;
+import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.User;
 import org.hisp.dhis.user.UserAuthorityGroup;
 import org.hisp.dhis.user.UserCredentials;
+import org.hisp.dhis.user.UserGroupAccess;
 import org.hisp.dhis.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 
 import java.util.Arrays;
 import java.util.Calendar;
@@ -94,6 +98,9 @@
         this.systemSettingManager = systemSettingManager;
     }
 
+    @Autowired
+    private CurrentUserService currentUserService;
+
     // -------------------------------------------------------------------------
     // SecurityService implementation
     // -------------------------------------------------------------------------
@@ -231,14 +238,59 @@
     }
 
     @Override
-    public boolean isWritable( IdentifiableObject identifiableObject )
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isReadable( IdentifiableObject identifiableObject )
-    {
-        return false;
+    public boolean canRead( IdentifiableObject identifiableObject )
+    {
+        if ( isCurrentUser( identifiableObject.getUser() ) || AccessHelper.canRead( identifiableObject.getPublicAccess() ) )
+        {
+            return true;
+        }
+
+        for ( UserGroupAccess userGroupAccess : identifiableObject.getUserGroupAccesses() )
+        {
+            if ( AccessHelper.canRead( userGroupAccess.getAccess() )
+                && userGroupAccess.getUserGroup().getMembers().contains( currentUserService.getCurrentUser() ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean canWrite( IdentifiableObject identifiableObject )
+    {
+        if ( isCurrentUser( identifiableObject.getUser() ) || AccessHelper.canWrite( identifiableObject.getPublicAccess() ) )
+        {
+            return true;
+        }
+
+        for ( UserGroupAccess userGroupAccess : identifiableObject.getUserGroupAccesses() )
+        {
+            if ( AccessHelper.canWrite( userGroupAccess.getAccess() )
+                && userGroupAccess.getUserGroup().getMembers().contains( currentUserService.getCurrentUser() ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean canUpdate( IdentifiableObject identifiableObject )
+    {
+        return canWrite( identifiableObject );
+    }
+
+    @Override
+    public boolean canDelete( IdentifiableObject identifiableObject )
+    {
+        return isCurrentUser( identifiableObject.getUser() );
+    }
+
+    public boolean isCurrentUser( User user )
+    {
+        return currentUserService.getCurrentUser() == user;
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/SecurityService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/SecurityService.java	2012-12-27 14:07:54 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/SecurityService.java	2013-01-03 12:43:44 +0000
@@ -87,18 +87,34 @@
     boolean verifyToken( String username, String token );
 
     /**
+     * Checks whether current user has read access to object.
+     *
+     * @param identifiableObject Object to check for read access.
+     * @return true of false depending on outcome of readable check
+     */
+    boolean canRead( IdentifiableObject identifiableObject );
+
+    /**
      * Checks whether current user has write access to object.
      *
      * @param identifiableObject Object to check for write access.
      * @return true of false depending on outcome of writable check
      */
-    boolean isWritable( IdentifiableObject identifiableObject );
-
-    /**
-     * Checks whether current user has read access to object.
-     *
-     * @param identifiableObject Object to check for read access.
-     * @return true of false depending on outcome of readable check
-     */
-    boolean isReadable( IdentifiableObject identifiableObject );
+    boolean canWrite( IdentifiableObject identifiableObject );
+
+    /**
+     * Checks whether current user has read access to object.
+     *
+     * @param identifiableObject Object to check for read access.
+     * @return true of false depending on outcome of readable check
+     */
+    boolean canUpdate( IdentifiableObject identifiableObject );
+
+    /**
+     * Checks whether current user has read access to object.
+     *
+     * @param identifiableObject Object to check for read access.
+     * @return true of false depending on outcome of readable check
+     */
+    boolean canDelete( IdentifiableObject identifiableObject );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java	2013-01-01 19:53:04 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java	2013-01-03 12:43:44 +0000
@@ -38,6 +38,7 @@
 import org.amplecode.quick.StatementManager;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.common.AccessHelper;
 import org.hisp.dhis.system.startup.AbstractStartupRoutine;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -129,9 +130,9 @@
         executeSql( "ALTER TABLE dataelement DROP COLUMN alternativename" );
         executeSql( "ALTER TABLE indicator DROP COLUMN alternativename" );
         executeSql( "ALTER TABLE orgunitgroup DROP COLUMN image" );
-        
+
         executeSql( "DROP INDEX datamart_crosstab" );
-        
+
         // remove relative period type
         executeSql( "DELETE FROM period WHERE periodtypeid=(select periodtypeid from periodtype where name in ( 'Survey', 'OnChange', 'Relative' ))" );
         executeSql( "DELETE FROM periodtype WHERE name in ( 'Survey', 'OnChange', 'Relative' )" );
@@ -154,12 +155,12 @@
         //TODO executeSql( "ALTER TABLE datavalue ALTER COLUMN storedby TYPE character varying(100)" );
 
         executeSql( "ALTER TABLE maplegend DROP CONSTRAINT maplegend_name_key" );
-        
+
         executeSql( "UPDATE mapview SET layer = 'thematic1' WHERE layer IS NULL" );
-        
+
         executeSql( "DELETE FROM systemsetting WHERE name = 'longitude'" );
         executeSql( "DELETE FROM systemsetting WHERE name = 'latitude'" );
-        
+
         executeSql( "ALTER TABLE maplayer DROP CONSTRAINT maplayer_mapsource_key" );
         executeSql( "ALTER TABLE maplayer DROP COLUMN mapsource" );
         executeSql( "ALTER TABLE maplayer DROP COLUMN mapsourcetype" );
@@ -171,11 +172,11 @@
         executeSql( "ALTER TABLE indicator DROP CONSTRAINT fk_indicator_extendeddataelementid" );
         executeSql( "ALTER TABLE indicator DROP COLUMN extendeddataelementid" );
         executeSql( "DROP TABLE extendeddataelement" );
-        
+
         executeSql( "ALTER TABLE organisationunit DROP COLUMN hasPatients" );
-        
+
         executeSql( "update dataelement set texttype='text' where valuetype='string' and texttype is null" );
-        
+
         // ---------------------------------------------------------------------
         // Update tables for dimensional model
         // ---------------------------------------------------------------------
@@ -208,9 +209,9 @@
         // categoryoptioncombos_categoryoptions
         executeSql( "alter table categoryoptioncombos_categoryoptions drop column sort_order" );
         executeSql( "alter table categoryoptioncombos_categoryoptions add constraint categoryoptioncombos_categoryoptions_pkey primary key(categoryoptioncomboid, categoryoptionid)" );
-        
+
         // dataelementcategoryoption
-        executeSql( "ALTER TABLE dataelementcategoryoption DROP CONSTRAINT fk_dataelement_categoryid" );        
+        executeSql( "ALTER TABLE dataelementcategoryoption DROP CONSTRAINT fk_dataelement_categoryid" );
         executeSql( "ALTER TABLE dataelementcategoryoption DROP CONSTRAINT dataelementcategoryoption_shortname_key" );
 
         // minmaxdataelement query index
@@ -218,18 +219,18 @@
 
         // add mandatory boolean field to patientattribute
         executeSql( "ALTER TABLE patientattribute ADD mandatory bool" );
-        
+
         if ( executeSql( "ALTER TABLE patientattribute ADD groupby bool" ) >= 0 )
         {
             executeSql( "UPDATE patientattribute SET groupby=false" );
         }
-        
+
         // update periodType field to ValidationRule
         executeSql( "UPDATE validationrule SET periodtypeid = (SELECT periodtypeid FROM periodtype WHERE name='Monthly') WHERE periodtypeid is null" );
 
         // update dataelement.domainTypes of which values is null
         executeSql( "UPDATE dataelement SET domaintype='aggregate' WHERE domaintype is null" );
-        
+
         // set varchar to text
         executeSql( "ALTER TABLE dataelement ALTER description TYPE text" );
         executeSql( "ALTER TABLE indicator ALTER description TYPE text" );
@@ -260,11 +261,11 @@
         executeSql( "UPDATE indicatortype SET indicatornumber=false WHERE indicatornumber is null" );
 
         // program
-        
+
         executeSql( "ALTER TABLE programinstance ALTER COLUMN patientid DROP NOT NULL" );
 
         // migrate charts from dimension to category, series, filter
-        
+
         executeSql( "UPDATE chart SET series='PERIOD', category='DATA', filter='ORGANISATIONUNIT' WHERE dimension='indicator'" );
         executeSql( "UPDATE chart SET series='DATA', category='ORGANISATIONUNIT', filter='PERIOD' WHERE dimension='organisationUnit'" );
         executeSql( "UPDATE chart SET series='PERIOD', category='DATA', filter='ORGANISATIONUNIT' WHERE dimension='dataElement_period'" );
@@ -295,19 +296,19 @@
         executeSql( "ALTER TABLE chart DROP COLUMN monthsLastYear" );
         executeSql( "ALTER TABLE chart DROP COLUMN quartersLastYear" );
         executeSql( "ALTER TABLE chart DROP COLUMN last6BiMonths" );
-        
+
         executeSql( "ALTER TABLE chart DROP CONSTRAINT chart_title_key" );
         executeSql( "ALTER TABLE chart DROP CONSTRAINT chart_name_key" );
-        
+
         executeSql( "ALTER TABLE chart DROP COLUMN domainaxixlabel" );
-        
+
         executeSql( "ALTER TABLE chart ALTER hideLegend DROP NOT NULL" );
         executeSql( "ALTER TABLE chart ALTER regression DROP NOT NULL" );
         executeSql( "ALTER TABLE chart ALTER hideSubtitle DROP NOT NULL" );
-        executeSql( "ALTER TABLE chart ALTER userOrganisationUnit DROP NOT NULL" );        
-        
+        executeSql( "ALTER TABLE chart ALTER userOrganisationUnit DROP NOT NULL" );
+
         // remove outdated relative periods
-        
+
         executeSql( "ALTER TABLE reporttable DROP COLUMN last6months" );
         executeSql( "ALTER TABLE reporttable DROP COLUMN last9months" );
         executeSql( "ALTER TABLE reporttable DROP COLUMN sofarthisyear" );
@@ -331,7 +332,7 @@
         executeSql( "ALTER TABLE chart DROP COLUMN individualquartersthisyear" );
 
         // remove source
-        
+
         executeSql( "ALTER TABLE datasetsource DROP CONSTRAINT fk766ae2938fd8026a" );
         executeSql( "ALTER TABLE datasetlocksource DROP CONSTRAINT fk582fdf7e8fd8026a" );
         executeSql( "ALTER TABLE completedatasetregistration DROP CONSTRAINT fk_datasetcompleteregistration_sourceid" );
@@ -339,7 +340,7 @@
         executeSql( "ALTER TABLE datavalue DROP CONSTRAINT fk_datavalue_sourceid" );
         executeSql( "ALTER TABLE datavaluearchive DROP CONSTRAINT fk_datavaluearchive_sourceid" );
         executeSql( "ALTER TABLE organisationunit DROP CONSTRAINT fke509dd5ef1c932ed" );
-        executeSql( "DROP TABLE source CASCADE" );        
+        executeSql( "DROP TABLE source CASCADE" );
 
         // message
 
@@ -353,13 +354,13 @@
         executeSql( "DROP TABLE message_usermessages" );
 
         // create code unique constraints
-        
+
         executeSql( "ALTER TABLE dataelement ADD CONSTRAINT dataelement_code_key UNIQUE(code)" );
         executeSql( "ALTER TABLE indicator ADD CONSTRAINT indicator_code_key UNIQUE(code)" );
         executeSql( "ALTER TABLE organisationunit ADD CONSTRAINT organisationunit_code_key UNIQUE(code)" );
-        
+
         // remove uuid
-        
+
         executeSql( "ALTER TABLE attribute DROP COLUMN uuid" );
         executeSql( "ALTER TABLE categorycombo DROP COLUMN uuid" );
         executeSql( "ALTER TABLE categoryoptioncombo DROP COLUMN uuid" );
@@ -384,9 +385,9 @@
         executeSql( "ALTER TABLE report DROP COLUMN uuid" );
         executeSql( "ALTER TABLE validationrule DROP COLUMN uuid" );
         executeSql( "ALTER TABLE validationrulegroup DROP COLUMN uuid" );
-        
+
         // replace null with false for boolean fields
-        
+
         executeSql( "update dataset set fieldcombinationrequired = false where fieldcombinationrequired is null" );
         executeSql( "update chart set hidelegend = false where hidelegend is null" );
         executeSql( "update chart set regression = false where regression is null" );
@@ -452,32 +453,40 @@
         executeSql( "update dataentryform set format = 1 where format is null" );
         
         // report, reporttable, chart groups
-        
+
         executeSql( "DROP TABLE reportgroupmembers" );
         executeSql( "DROP TABLE reportgroup" );
         executeSql( "DROP TABLE reporttablegroupmembers" );
         executeSql( "DROP TABLE reporttablegroup" );
         executeSql( "DROP TABLE chartgroupmembers" );
         executeSql( "DROP TABLE chartgroup" );
-        
+
         executeSql( "ALTER TABLE patientdatavaluearchive DROP COLUMN categoryoptioncomboid" );
         executeSql( "delete from usersetting where name='currentStyle' and value like '%blue/blue.css'" );
         executeSql( "delete from systemsetting where name='currentStyle' and value like '%blue/blue.css'" );
-        
+
         executeSql( "update dataentryform set style='regular' where style is null" );
 
         executeSql( "UPDATE dataset SET skipaggregation = false WHERE skipaggregation IS NULL" );
         executeSql( "UPDATE dataset SET skipoffline = false WHERE skipoffline IS NULL" );
 
         executeSql( "UPDATE categorycombo SET skiptotal = false WHERE skiptotal IS NULL" );
-        
+
         // short names
-        
+
         executeSql( "ALTER TABLE dataelement ALTER COLUMN shortname TYPE character varying(50)" );
         executeSql( "ALTER TABLE indicator ALTER COLUMN shortname TYPE character varying(50)" );
         executeSql( "ALTER TABLE dataset ALTER COLUMN shortname TYPE character varying(50)" );
         executeSql( "ALTER TABLE organisationunit ALTER COLUMN shortname TYPE character varying(50)" );
-        
+
+        // set default access properties
+        String publicString = AccessHelper.newInstance()
+            .enable( AccessHelper.Permission.READ )
+            .enable( AccessHelper.Permission.WRITE )
+            .build();
+
+        // executeSql( "UPDATE document SET publicaccess = '" + publicString + "' WHERE userid IS NULL AND publicaccess IS NULL" );
+
         log.info( "Tables updated" );
     }
 

=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupAccessService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupAccessService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupAccessService.java	2013-01-03 12:43:44 +0000
@@ -0,0 +1,76 @@
+package org.hisp.dhis.user;
+
+/*
+ * Copyright (c) 2004-2012, 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.hisp.dhis.common.GenericStore;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Collection;
+
+@Transactional
+public class DefaultUserGroupAccessService implements UserGroupAccessService
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    private GenericStore<UserGroupAccess> userGroupAccessStore;
+
+    public void setUserGroupAccessStore( GenericStore<UserGroupAccess> userGroupAccessStore )
+    {
+        this.userGroupAccessStore = userGroupAccessStore;
+    }
+
+    // -------------------------------------------------------------------------
+    // UserGroupAccess
+    // -------------------------------------------------------------------------
+
+    @Override
+    public void addUserGroupAccess( UserGroupAccess userGroupAccess )
+    {
+        userGroupAccessStore.saveOrUpdate( userGroupAccess );
+    }
+
+    @Override
+    public void updateUserGroupAccess( UserGroupAccess userGroupAccess )
+    {
+        userGroupAccessStore.update( userGroupAccess );
+    }
+
+    @Override
+    public void deleteUserGroupAccess( UserGroupAccess userGroupAccess )
+    {
+        userGroupAccessStore.delete( userGroupAccess );
+    }
+
+    @Override
+    public Collection<UserGroupAccess> getAllUserGroupAccesses()
+    {
+        return userGroupAccessStore.getAll();
+    }
+}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupService.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupService.java	2013-01-03 12:43:44 +0000
@@ -116,5 +116,4 @@
     {
         return userGroupStore.getBetweenByName( name, first, max );
     }
-
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2012-12-14 13:46:47 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2013-01-03 12:43:44 +0000
@@ -219,6 +219,11 @@
     <property name="sessionFactory" ref="sessionFactory" />
   </bean>
 
+  <bean id="org.hisp.dhis.user.UserGroupAccessStore" class="org.hisp.dhis.hibernate.HibernateGenericStore">
+    <property name="clazz" value="org.hisp.dhis.user.UserGroupAccess" />
+    <property name="sessionFactory" ref="sessionFactory" />
+  </bean>
+
   <bean id="org.hisp.dhis.validation.ValidationCriteriaStore" class="org.hisp.dhis.hibernate.HibernateGenericStore">
     <property name="clazz" value="org.hisp.dhis.validation.ValidationCriteria" />
     <property name="sessionFactory" ref="sessionFactory" />
@@ -493,6 +498,10 @@
     <property name="userGroupStore" ref="org.hisp.dhis.user.UserGroupStore" />
   </bean>
 
+  <bean id="org.hisp.dhis.user.UserGroupAccessService" class="org.hisp.dhis.user.DefaultUserGroupAccessService">
+    <property name="userGroupAccessStore" ref="org.hisp.dhis.user.UserGroupAccessStore" />
+  </bean>
+
   <bean id="org.hisp.dhis.validation.ValidationCriteriaService" class="org.hisp.dhis.validation.DefaultValidationCriteriaService">
     <property name="validationCriteriaStore" ref="org.hisp.dhis.validation.ValidationCriteriaStore" />
   </bean>

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/document/hibernate/Document.hbm.xml'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/document/hibernate/Document.hbm.xml	2011-12-10 23:03:56 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/document/hibernate/Document.hbm.xml	2013-01-03 12:43:44 +0000
@@ -1,9 +1,9 @@
 <?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC
-    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
-    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd";
-    [<!ENTITY identifiableProperties SYSTEM "classpath://org/hisp/dhis/common/identifiableProperties.hbm">]
-    >
+  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+  "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd";
+  [<!ENTITY identifiableProperties SYSTEM "classpath://org/hisp/dhis/common/identifiableProperties.hbm">]
+  >
 
 <hibernate-mapping>
   <class name="org.hisp.dhis.document.Document" table="document">
@@ -21,5 +21,16 @@
 
     <property name="contentType" />
 
+    <!-- Access properties -->
+    <many-to-one name="user" class="org.hisp.dhis.user.User" column="userid" foreign-key="fk_document_userid" />
+
+    <property name="publicAccess" length="8" />
+
+    <set name="userGroupAccesses" table="documentusergroupaccesses">
+      <cache usage="read-write" />
+      <key column="documentid" />
+      <many-to-many class="org.hisp.dhis.user.UserGroupAccess" column="usergroupaccessid" unique="true" />
+    </set>
+
   </class>
-</hibernate-mapping>
\ No newline at end of file
+</hibernate-mapping>

=== 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	2012-12-28 10:49:37 +0000
+++ dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/hibernate/HibernateGenericStore.java	2013-01-03 12:43:44 +0000
@@ -52,7 +52,6 @@
 
 /**
  * @author Lars Helge Overland
- * @version $Id$
  */
 public class HibernateGenericStore<T>
     implements GenericNameableObjectStore<T>
@@ -230,8 +229,8 @@
     @SuppressWarnings("unchecked")
     public final T get( int id )
     {
+        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
         T object = (T) sessionFactory.getCurrentSession().get( getClazz(), id );
-        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
 
         return object;
     }
@@ -240,8 +239,8 @@
     @SuppressWarnings("unchecked")
     public final T load( int id )
     {
+        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
         T object = (T) sessionFactory.getCurrentSession().load( getClazz(), id );
-        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
 
         return object;
     }
@@ -249,8 +248,8 @@
     @Override
     public final T getByUid( String uid )
     {
+        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
         T object = getObject( Restrictions.eq( "uid", uid ) );
-        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
 
         return object;
     }
@@ -258,8 +257,8 @@
     @Override
     public final T getByName( String name )
     {
+        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
         T object = getObject( Restrictions.eq( "name", name ) );
-        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
 
         return object;
     }
@@ -267,8 +266,8 @@
     @Override
     public final T getByShortName( String shortName )
     {
+        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
         T object = getObject( Restrictions.eq( "shortName", shortName ) );
-        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
 
         return object;
     }
@@ -276,8 +275,8 @@
     @Override
     public final T getByCode( String code )
     {
+        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
         T object = getObject( Restrictions.eq( "code", code ) );
-        // AuditLogUtil.infoWrapper( log, currentUserService.getCurrentUsername(), object, AuditLogUtil.ACTION_READ );
 
         return object;
     }

=== added 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	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/SharingController.java	2013-01-03 12:43:44 +0000
@@ -0,0 +1,189 @@
+package org.hisp.dhis.api.controller;
+
+/*
+ * Copyright (c) 2004-2012, 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.hisp.dhis.api.utils.ContextUtils;
+import org.hisp.dhis.api.webdomain.sharing.Sharing;
+import org.hisp.dhis.api.webdomain.sharing.SharingUserGroupAccess;
+import org.hisp.dhis.common.BaseIdentifiableObject;
+import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.common.IdentifiableObjectManager;
+import org.hisp.dhis.document.Document;
+import org.hisp.dhis.dxf2.utils.JacksonUtils;
+import org.hisp.dhis.security.SecurityService;
+import org.hisp.dhis.user.CurrentUserService;
+import org.hisp.dhis.user.UserGroup;
+import org.hisp.dhis.user.UserGroupAccess;
+import org.hisp.dhis.user.UserGroupAccessService;
+import org.hisp.dhis.user.UserGroupService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+@Controller
+@RequestMapping( value = SharingController.RESOURCE_PATH, method = RequestMethod.GET )
+public class SharingController
+{
+    public static final String RESOURCE_PATH = "/sharing";
+
+    public static final Map<String, Class<? extends IdentifiableObject>> TYPE_MAP = new HashMap<String, Class<? extends IdentifiableObject>>();
+
+    static
+    {
+        TYPE_MAP.put( "document", Document.class );
+    }
+
+    @Autowired
+    private CurrentUserService currentUserService;
+
+    @Autowired
+    private IdentifiableObjectManager manager;
+
+    @Autowired
+    private UserGroupService userGroupService;
+
+    @Autowired
+    private SecurityService securityService;
+
+    @Autowired
+    private UserGroupAccessService userGroupAccessService;
+
+    @RequestMapping( value = "", produces = { "application/json", "text/*" } )
+    public void getSharing( @RequestParam String type, @RequestParam String id, HttpServletResponse response ) throws IOException
+    {
+        if ( !TYPE_MAP.containsKey( type ) )
+        {
+            ContextUtils.notFoundResponse( response, "Type " + type + " is not supported." );
+            return;
+        }
+
+        IdentifiableObject object = manager.get( TYPE_MAP.get( type ), id );
+
+        if ( object == null )
+        {
+            ContextUtils.notFoundResponse( response, "Object of type " + type + " with ID " + id + " was not found." );
+            return;
+        }
+
+        if ( !securityService.canRead( object ) )
+        {
+            throw new AccessDeniedException( "You do not have read access to this object." );
+        }
+
+        Sharing sharing = new Sharing();
+
+        sharing.getObject().setId( object.getUid() );
+        sharing.getObject().setClazz( TYPE_MAP.get( type ).getName() );
+        sharing.getObject().setName( object.getDisplayName() );
+        sharing.getObject().setPublicAccess( object.getPublicAccess() );
+
+        if ( object.getUser() != null )
+        {
+            sharing.getObject().getUser().setId( object.getUser().getUid() );
+            sharing.getObject().getUser().setName( object.getUser().getDisplayName() );
+        }
+
+        for ( UserGroupAccess userGroupAccess : object.getUserGroupAccesses() )
+        {
+            SharingUserGroupAccess sharingUserGroupAccess = new SharingUserGroupAccess();
+            sharingUserGroupAccess.setId( userGroupAccess.getUserGroup().getUid() );
+            sharingUserGroupAccess.setAccess( userGroupAccess.getAccess() );
+
+            sharing.getObject().getUserGroupAccesses().add( sharingUserGroupAccess );
+        }
+
+        for ( UserGroup userGroup : userGroupService.getAllUserGroups() )
+        {
+            sharing.getUserGroups().put( userGroup.getUid(), userGroup.getDisplayName() );
+        }
+
+        JacksonUtils.toJson( response.getOutputStream(), sharing );
+    }
+
+    @RequestMapping( value = "", method = RequestMethod.POST, consumes = "application/json" )
+    public void setSharing( @RequestParam String type, @RequestParam String id, HttpServletResponse response, HttpServletRequest request ) throws IOException
+    {
+        BaseIdentifiableObject object = (BaseIdentifiableObject) manager.get( TYPE_MAP.get( type ), id );
+
+        if ( object == null )
+        {
+            ContextUtils.notFoundResponse( response, "Object of type " + type + " with ID " + id + " was not found." );
+            return;
+        }
+
+        if ( !securityService.canWrite( object ) )
+        {
+            throw new AccessDeniedException( "You do not have write access to this object." );
+        }
+
+        Sharing sharing = JacksonUtils.fromJson( request.getInputStream(), Sharing.class );
+
+        object.setPublicAccess( sharing.getObject().getPublicAccess() );
+
+        Iterator<UserGroupAccess> iterator = object.getUserGroupAccesses().iterator();
+
+        while ( iterator.hasNext() )
+        {
+            UserGroupAccess userGroupAccess = iterator.next();
+            iterator.remove();
+
+            userGroupAccessService.deleteUserGroupAccess( userGroupAccess );
+        }
+
+        for ( SharingUserGroupAccess sharingUserGroupAccess : sharing.getObject().getUserGroupAccesses() )
+        {
+            UserGroupAccess userGroupAccess = new UserGroupAccess();
+            userGroupAccess.setAccess( sharingUserGroupAccess.getAccess() );
+
+            UserGroup userGroup = manager.get( UserGroup.class, sharingUserGroupAccess.getId() );
+
+            if ( userGroup != null )
+            {
+                userGroupAccess.setUserGroup( userGroup );
+                userGroupAccessService.addUserGroupAccess( userGroupAccess );
+
+                object.getUserGroupAccesses().add( userGroupAccess );
+            }
+        }
+
+        manager.update( object );
+    }
+}

=== added directory 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing'
=== added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/Sharing.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/Sharing.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/Sharing.java	2013-01-03 12:43:44 +0000
@@ -0,0 +1,69 @@
+package org.hisp.dhis.api.webdomain.sharing;
+
+/*
+ * Copyright (c) 2004-2012, 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 java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class Sharing
+{
+    @JsonProperty
+    private SharingObject object = new SharingObject();
+
+    @JsonProperty
+    private Map<String, String> userGroups = new HashMap<String, String>();
+
+    public Sharing()
+    {
+    }
+
+    public SharingObject getObject()
+    {
+        return object;
+    }
+
+    public void setObject( SharingObject object )
+    {
+        this.object = object;
+    }
+
+    public Map<String, String> getUserGroups()
+    {
+        return userGroups;
+    }
+
+    public void setUserGroups( Map<String, String> userGroups )
+    {
+        this.userGroups = userGroups;
+    }
+}

=== added 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	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingObject.java	2013-01-03 12:43:44 +0000
@@ -0,0 +1,121 @@
+package org.hisp.dhis.api.webdomain.sharing;
+
+/*
+ * Copyright (c) 2004-2012, 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 java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class SharingObject
+{
+    @JsonProperty
+    private String id;
+
+    @JsonProperty
+    private String clazz;
+
+    @JsonProperty
+    private String name;
+
+    @JsonProperty
+    private String publicAccess;
+
+    @JsonProperty
+    private SharingUser user = new SharingUser();
+
+    @JsonProperty
+    private List<SharingUserGroupAccess> userGroupAccesses = new ArrayList<SharingUserGroupAccess>();
+
+    public SharingObject()
+    {
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+    public String getClazz()
+    {
+        return clazz;
+    }
+
+    public void setClazz( String clazz )
+    {
+        this.clazz = clazz;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    public String getPublicAccess()
+    {
+        return publicAccess;
+    }
+
+    public void setPublicAccess( String publicAccess )
+    {
+        this.publicAccess = publicAccess;
+    }
+
+    public SharingUser getUser()
+    {
+        return user;
+    }
+
+    public void setUser( SharingUser user )
+    {
+        this.user = user;
+    }
+
+    public List<SharingUserGroupAccess> getUserGroupAccesses()
+    {
+        return userGroupAccesses;
+    }
+
+    public void setUserGroupAccesses( List<SharingUserGroupAccess> userGroupAccesses )
+    {
+        this.userGroupAccesses = userGroupAccesses;
+    }
+}

=== added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingUser.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingUser.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingUser.java	2013-01-03 12:43:44 +0000
@@ -0,0 +1,66 @@
+package org.hisp.dhis.api.webdomain.sharing;
+
+/*
+ * Copyright (c) 2004-2012, 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;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class SharingUser
+{
+    @JsonProperty
+    private String id;
+
+    @JsonProperty
+    private String name;
+
+    public SharingUser()
+    {
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+}

=== added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingUserGroupAccess.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingUserGroupAccess.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/webdomain/sharing/SharingUserGroupAccess.java	2013-01-03 12:43:44 +0000
@@ -0,0 +1,66 @@
+package org.hisp.dhis.api.webdomain.sharing;
+
+/*
+ * Copyright (c) 2004-2012, 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;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class SharingUserGroupAccess
+{
+    @JsonProperty
+    private String id;
+
+    @JsonProperty
+    private String access;
+
+    public SharingUserGroupAccess()
+    {
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+    public String getAccess()
+    {
+        return access;
+    }
+
+    public void setAccess( String access )
+    {
+        this.access = access;
+    }
+}

=== added 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	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.sharing.js	2013-01-03 12:43:44 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2004-2012, 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.
+ */
+
+dhis2.util.namespace( 'dhis2.sharing' );
+
+dhis2.sharing.manageSharing = function( type, uid )
+{
+    console.log( "manage sharing for", type, uid );
+}

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm	2012-11-30 18:17:32 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm	2013-01-03 12:43:44 +0000
@@ -44,6 +44,7 @@
     <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.comparator.js"></script>
     <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.availability.js"></script>
     <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.trigger.js"></script>
+    <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.sharing.js"></script>
     <script type="text/javascript" src="../dhis-web-commons/i18nJavaScript.action"></script>
     <script type="text/javascript" src="../main.js"></script>  
     <script type="text/javascript" src="../request.js"></script>

=== modified file 'dhis-2/dhis-web/dhis-web-commons/pom.xml'
--- dhis-2/dhis-web/dhis-web-commons/pom.xml	2012-12-19 10:55:35 +0000
+++ dhis-2/dhis-web/dhis-web-commons/pom.xml	2013-01-03 12:43:44 +0000
@@ -21,6 +21,10 @@
     </dependency>
     <dependency>
       <groupId>org.hisp.dhis</groupId>
+      <artifactId>dhis-dxf2</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.hisp.dhis</groupId>
       <artifactId>dhis-service-i18n</artifactId>
     </dependency>
     <dependency>

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/resources/dhis-web-commons.xml'
--- dhis-2/dhis-web/dhis-web-commons/src/main/resources/dhis-web-commons.xml	2012-10-29 20:17:23 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/resources/dhis-web-commons.xml	2013-01-03 12:43:44 +0000
@@ -482,7 +482,7 @@
   <!-- Common actions JSON -->
 
   <package name="dhis-web-commons-ajax-json" extends="dhis-web-commons" namespace="/dhis-web-commons-ajax-json">
-   
+
     <action name="getNotifications" class="org.hisp.dhis.commons.action.GetNotificationsAction">
 	  <result name="success" type="velocity-json">/dhis-web-commons/ajax/jsonNotifications.vm</result>
       <param name="onExceptionReturn">plainTextError</param>

=== modified file 'dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/document/action/SaveDocumentAction.java'
--- dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/document/action/SaveDocumentAction.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/document/action/SaveDocumentAction.java	2013-01-03 12:43:44 +0000
@@ -27,15 +27,17 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.io.File;
-
+import com.opensymphony.xwork2.Action;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.common.AccessHelper;
 import org.hisp.dhis.document.Document;
 import org.hisp.dhis.document.DocumentService;
 import org.hisp.dhis.external.location.LocationManager;
+import org.hisp.dhis.user.CurrentUserService;
+import org.springframework.beans.factory.annotation.Autowired;
 
-import com.opensymphony.xwork2.Action;
+import java.io.File;
 
 /**
  * @author Lars Helge Overland
@@ -68,6 +70,9 @@
         this.documentService = documentService;
     }
 
+    @Autowired
+    private CurrentUserService currentUserService;
+
     // -------------------------------------------------------------------------
     // Input
     // -------------------------------------------------------------------------
@@ -134,7 +139,7 @@
         {
             document = documentService.getDocument( id );
         }
-        
+
         if ( !external && file != null )
         {
             log.info( "Uploading file: '" + fileName + "', content-type: '" + contentType + "'" );
@@ -169,6 +174,10 @@
 
         document.setName( name );
 
+        document.setUser( currentUserService.getCurrentUser() );
+
+        document.setPublicAccess( AccessHelper.newInstance().enable( AccessHelper.Permission.READ ).build() );
+
         documentService.saveDocument( document );
 
         return SUCCESS;