← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 22285: Support username uniqueness checks, also adds uid/code/lastUpdated to usercredentials

 

------------------------------------------------------------
revno: 22285
committer: Morten Olav Hansen <morten@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2016-03-14 15:30:30 +0700
message:
  Support username uniqueness checks, also adds uid/code/lastUpdated to usercredentials
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserCredentials.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java
  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/org/hisp/dhis/user/hibernate/UserCredentials.hbm.xml
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/hooks/UserObjectBundleHook.java
  dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_compulsory.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections_gf.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections_gf_update.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_av_unique_and_mandatory.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_indicators.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_vr.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_vr_update.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_noreg.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_noreg_sections.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_reg1.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata_uga.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata_with_av.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/user_duplicate_username.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/users.json
  dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/users_update.json


--
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/user/UserCredentials.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserCredentials.java	2016-02-11 09:27:02 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserCredentials.java	2016-03-14 08:30:30 +0000
@@ -163,6 +163,7 @@
     {
         this.lastLogin = new Date();
         this.passwordLastUpdated = new Date();
+        this.setAutoFields(); // needed to support userCredentials uniqueness
     }
 
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java	2016-03-14 06:31:31 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java	2016-03-14 08:30:30 +0000
@@ -103,14 +103,7 @@
         {
             params.getObjects().get( klass ).stream()
                 .filter( identifiableObject -> StringUtils.isEmpty( identifiableObject.getUid() ) )
-                .forEach( identifiableObject -> {
-                    ((BaseIdentifiableObject) identifiableObject).setUid( CodeGenerator.generateCode() );
-
-                    if ( User.class.isInstance( identifiableObject ) )
-                    {
-                        ((User) identifiableObject).getUserCredentials().setUid( identifiableObject.getUid() );
-                    }
-                } );
+                .forEach( identifiableObject -> ((BaseIdentifiableObject) identifiableObject).setUid( CodeGenerator.generateCode() ) );
         }
 
         Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> uniqueCollectionMap = new HashMap<>();
@@ -200,6 +193,23 @@
             }
         }
 
+        if ( uniqueCollectionMap.containsKey( User.class ) )
+        {
+            List<IdentifiableObject> userCredentials = new ArrayList<>();
+
+            for ( IdentifiableObject identifiableObject : uniqueCollectionMap.get( User.class ) )
+            {
+                User user = (User) identifiableObject;
+
+                if ( user.getUserCredentials() != null )
+                {
+                    userCredentials.add( user.getUserCredentials() );
+                }
+            }
+
+            uniqueCollectionMap.put( UserCredentials.class, userCredentials );
+        }
+
         preheat.setUniquenessMap( collectUniqueness( uniqueCollectionMap ) );
 
         // add preheat placeholders for objects that will be created
@@ -271,7 +281,6 @@
 
         Map<Class<? extends IdentifiableObject>, Set<String>> uidMap = map.get( PreheatIdentifier.UID );
         Map<Class<? extends IdentifiableObject>, Set<String>> codeMap = map.get( PreheatIdentifier.CODE );
-        Map<Class<? extends IdentifiableObject>, Map<String, Map<Object, String>>> uniqueMap = new HashMap<>();
 
         if ( objects.isEmpty() )
         {
@@ -281,25 +290,6 @@
         Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> scanObjects = new HashMap<>();
         scanObjects.putAll( objects ); // clone objects list, we don't want to modify it
 
-        if ( scanObjects.containsKey( User.class ) )
-        {
-            List<IdentifiableObject> users = scanObjects.get( User.class );
-            List<IdentifiableObject> userCredentials = new ArrayList<>();
-
-            for ( IdentifiableObject identifiableObject : users )
-            {
-                User user = (User) identifiableObject;
-
-                if ( user.getUserCredentials() != null )
-                {
-                    user.getUserCredentials().setUid( user.getUid() );
-                    userCredentials.add( user.getUserCredentials() );
-                }
-            }
-
-            scanObjects.put( UserCredentials.class, userCredentials );
-        }
-
         for ( Class<? extends IdentifiableObject> objectClass : scanObjects.keySet() )
         {
             Schema schema = schemaService.getDynamicSchema( objectClass );
@@ -435,31 +425,10 @@
             return uniqueMap;
         }
 
-        Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> scanObjects = new HashMap<>();
-        scanObjects.putAll( objects ); // clone objects list, we don't want to modify it
-
-        if ( scanObjects.containsKey( User.class ) )
-        {
-            List<IdentifiableObject> users = scanObjects.get( User.class );
-            List<IdentifiableObject> userCredentials = new ArrayList<>();
-
-            for ( IdentifiableObject identifiableObject : users )
-            {
-                User user = (User) identifiableObject;
-
-                if ( user.getUserCredentials() != null )
-                {
-                    userCredentials.add( user.getUserCredentials() );
-                }
-            }
-
-            scanObjects.put( UserCredentials.class, userCredentials );
-        }
-
-        for ( Class<? extends IdentifiableObject> objectClass : scanObjects.keySet() )
+        for ( Class<? extends IdentifiableObject> objectClass : objects.keySet() )
         {
             Schema schema = schemaService.getDynamicSchema( objectClass );
-            List<IdentifiableObject> identifiableObjects = scanObjects.get( objectClass );
+            List<IdentifiableObject> identifiableObjects = objects.get( objectClass );
             uniqueMap.put( objectClass, handleUniqueProperties( schema, identifiableObjects ) );
         }
 
@@ -747,30 +716,27 @@
             .collect( Collectors.toList() );
 
         uniqueProperties.forEach( property -> {
+            if ( !uniquenessMap.containsKey( property.getName() ) )
+            {
+                uniquenessMap.put( property.getName(), new HashMap<>() );
+            }
+
             Object value = ReflectionUtils.invokeMethod( object, property.getGetterMethod() );
 
             if ( value != null )
             {
-                if ( uniquenessMap.containsKey( property.getName() ) && !uniquenessMap.get( property.getName() ).isEmpty() )
+                String persistedUid = uniquenessMap.get( property.getName() ).get( value );
+
+                if ( persistedUid != null )
                 {
-                    String persistedUid = uniquenessMap.get( property.getName() ).get( value );
-
-                    if ( persistedUid != null )
+                    if ( !object.getUid().equals( persistedUid ) )
                     {
-                        if ( !object.getUid().equals( persistedUid ) )
-                        {
-                            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E5003, property.getName(), value,
-                                identifier.getIdentifiersWithName( object ), persistedUid ) );
-                        }
+                        errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E5003, property.getName(), value,
+                            identifier.getIdentifiersWithName( object ), persistedUid ) );
                     }
                 }
                 else
                 {
-                    if ( !uniquenessMap.containsKey( property.getName() ) )
-                    {
-                        uniquenessMap.put( property.getName(), new HashMap<>() );
-                    }
-
                     uniquenessMap.get( property.getName() ).put( value, object.getUid() );
                 }
             }

=== 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	2016-03-10 04:37:34 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2016-03-14 08:30:30 +0000
@@ -1438,6 +1438,7 @@
         <value>categoryoptioncombo</value>
         <value>translation</value>
         <value>userinfo</value>
+        <value>users</value>
         <value>usergroup</value>
         <value>userrole</value>
         <value>optionset</value>

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/user/hibernate/UserCredentials.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/user/hibernate/UserCredentials.hbm.xml	2015-11-08 13:56:42 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/user/hibernate/UserCredentials.hbm.xml	2016-03-14 08:30:30 +0000
@@ -1,7 +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";>
+  "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.user.UserCredentials" table="users">
@@ -13,6 +15,7 @@
         <param name="property">userInfo</param>
       </generator>
     </id>
+    &identifiableProperties;
 
     <many-to-one name="user" class="org.hisp.dhis.user.User" column="creatoruserid" foreign-key="fk_user_userid" />
 
@@ -65,7 +68,5 @@
 
     <property name="disabled" />
 
-    <property name="created" />
-
   </class>
 </hibernate-mapping>

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java	2016-03-14 06:31:31 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java	2016-03-14 08:30:30 +0000
@@ -104,8 +104,6 @@
         ObjectBundle bundle = new ObjectBundle( params, preheatService.preheat( preheatParams ), params.getObjects() );
         bundle.setObjectReferences( preheatService.collectObjectReferences( params.getObjects() ) );
 
-        System.err.println( "O: " + bundle.getObjectReferences().get( UserCredentials.class ) );
-
         return bundle;
     }
 

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/hooks/UserObjectBundleHook.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/hooks/UserObjectBundleHook.java	2016-03-14 06:31:31 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/hooks/UserObjectBundleHook.java	2016-03-14 08:30:30 +0000
@@ -145,7 +145,7 @@
 
             User user = (User) identifiableObject;
             UserCredentials userCredentials = user.getUserCredentials();
-            Map<String, Object> userCredentialsReferenceMap = userCredentialsReferences.get( user.getUid() );
+            Map<String, Object> userCredentialsReferenceMap = userCredentialsReferences.get( userCredentials.getUid() );
 
             if ( userCredentialsReferenceMap == null || userCredentialsReferenceMap.isEmpty() )
             {

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java	2016-03-14 06:31:31 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java	2016-03-14 08:30:30 +0000
@@ -1431,6 +1431,26 @@
         assertEquals( 1, manager.getAll( User.class ).size() );
     }
 
+    @Test
+    public void testCreateMetadataWithDuplicateUsernameAndInjectedUser() throws IOException
+    {
+        createUserAndInjectSecurityContext( true );
+
+        Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> metadata = renderService.fromMetadata(
+            new ClassPathResource( "dxf2/user_duplicate_username.json" ).getInputStream(), RenderFormat.JSON );
+
+        ObjectBundleParams params = new ObjectBundleParams();
+        params.setObjectBundleMode( ObjectBundleMode.COMMIT );
+        params.setImportMode( ImportStrategy.CREATE_AND_UPDATE );
+        params.setObjects( metadata );
+
+        ObjectBundle bundle = objectBundleService.create( params );
+        objectBundleService.validate( bundle );
+
+        objectBundleService.commit( bundle );
+        assertEquals( 2, manager.getAll( User.class ).size() );
+    }
+
     private void defaultSetup()
     {
         DataElement de1 = createDataElement( 'A' );

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_compulsory.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_compulsory.json	2016-03-09 10:26:29 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_compulsory.json	2016-03-14 08:30:30 +0000
@@ -125,6 +125,7 @@
       "teiSearchOrganisationUnits": [ ],
       "lastUpdated": "2016-03-09T09:41:06.953+0000",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "externalAuth": false,
         "created": "2016-03-09T09:41:07.157+0000",
         "passwordLastUpdated": "2016-03-09T09:41:07.022+0000",

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections.json	2016-03-08 08:09:23 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections.json	2016-03-14 08:30:30 +0000
@@ -376,6 +376,7 @@
       ],
       "dataViewOrganisationUnits": [ ],
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "catDimensionConstraints": [ ],
         "userInfo": {
           "id": "T12jeH7KPzk"

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections_gf.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections_gf.json	2016-03-08 08:09:23 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections_gf.json	2016-03-14 08:30:30 +0000
@@ -258,6 +258,7 @@
       ],
       "firstName": "admin",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "cogsDimensionConstraints": [ ],
         "lastLogin": "2016-03-08T07:26:51.942+0000",
         "invitation": false,

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections_gf_update.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections_gf_update.json	2016-03-09 08:02:01 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/dataset_with_sections_gf_update.json	2016-03-14 08:30:30 +0000
@@ -258,6 +258,7 @@
       ],
       "firstName": "admin",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "cogsDimensionConstraints": [ ],
         "lastLogin": "2016-03-08T07:26:51.942+0000",
         "invitation": false,

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_av_unique_and_mandatory.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_av_unique_and_mandatory.json	2016-02-29 08:22:45 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_av_unique_and_mandatory.json	2016-03-14 08:30:30 +0000
@@ -312,6 +312,7 @@
       "firstName": "admin",
       "attributeValues": [],
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "userInfo": {
           "id": "W0AiiQXzQhv"
         },

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_indicators.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_indicators.json	2016-03-10 06:06:01 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_indicators.json	2016-03-14 08:30:30 +0000
@@ -80,6 +80,7 @@
       "surname": "admin",
       "lastUpdated": "2016-03-10T04:22:23.892+0000",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "user": {
           "id": "Fiob73BgnJm"
         },

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_vr.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_vr.json	2016-03-10 06:13:47 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_vr.json	2016-03-14 08:30:30 +0000
@@ -132,6 +132,7 @@
       "dataViewOrganisationUnits": [ ],
       "lastUpdated": "2016-03-10T05:01:28.993+0000",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "username": "admin",
         "disabled": false,
         "passwordLastUpdated": "2016-03-10T05:00:11.791+0000",

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_vr_update.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_vr_update.json	2016-03-10 06:20:15 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/metadata_with_vr_update.json	2016-03-14 08:30:30 +0000
@@ -132,6 +132,7 @@
       "dataViewOrganisationUnits": [ ],
       "lastUpdated": "2016-03-10T05:01:28.993+0000",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "username": "admin",
         "disabled": false,
         "passwordLastUpdated": "2016-03-10T05:00:11.791+0000",

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_noreg.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_noreg.json	2016-03-10 08:29:00 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_noreg.json	2016-03-14 08:30:30 +0000
@@ -299,6 +299,7 @@
       ],
       "teiSearchOrganisationUnits": [ ],
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "selfRegistered": false,
         "externalAuth": false,
         "invitation": false,

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_noreg_sections.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_noreg_sections.json	2016-03-10 08:37:23 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_noreg_sections.json	2016-03-14 08:30:30 +0000
@@ -383,6 +383,7 @@
         }
       ],
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "user": {
           "id": "ZK1wkC59FCw"
         },

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_reg1.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_reg1.json	2016-03-11 07:05:57 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/program_reg1.json	2016-03-14 08:30:30 +0000
@@ -414,6 +414,7 @@
       "id": "A3U6uPM3H58",
       "lastUpdated": "2016-03-11T06:57:46.094+0000",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "lastLogin": "2016-03-11T06:51:52.462+0000",
         "invitation": false,
         "user": {

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata.json	2016-02-27 03:28:59 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata.json	2016-03-14 08:30:30 +0000
@@ -36,6 +36,7 @@
       ],
       "surname": "admin",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "lastLogin": "2016-02-17T06:14:12.274+0000",
         "created": "2016-02-17T06:14:12.362+0000",
         "userRoles": [

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata_uga.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata_uga.json	2016-03-03 10:04:35 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata_uga.json	2016-03-14 08:30:30 +0000
@@ -233,6 +233,7 @@
       "created": "2016-03-03T07:15:10.066+0000",
       "surname": "admin",
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "created": "2016-03-03T07:15:10.199+0000",
         "catDimensionConstraints": [],
         "externalAuth": false,

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata_with_av.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata_with_av.json	2016-02-27 03:29:27 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/simple_metadata_with_av.json	2016-03-14 08:30:30 +0000
@@ -4,15 +4,15 @@
       "user": {
         "id": "ueKaFVdR8Fz"
       },
-      "aggregationLevels": [],
+      "aggregationLevels": [ ],
       "created": "2016-02-17T06:15:06.079+0000",
       "zeroIsSignificant": false,
-      "attributeValues": [],
+      "attributeValues": [ ],
       "code": "DataElementCodeA",
       "publicAccess": "rw------",
       "aggregationType": "SUM",
       "domainType": "AGGREGATE",
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "shortName": "DataElementShortA",
       "name": "DataElementA",
       "id": "SG4HuKlNEFH",
@@ -31,15 +31,15 @@
       "categoryCombo": {
         "id": "zU1OZFVxnw7"
       },
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "domainType": "AGGREGATE",
       "aggregationType": "SUM",
       "publicAccess": "rw------",
-      "attributeValues": [],
+      "attributeValues": [ ],
       "code": "DataElementCodeB",
       "created": "2016-02-17T06:15:49.487+0000",
       "zeroIsSignificant": false,
-      "aggregationLevels": [],
+      "aggregationLevels": [ ],
       "user": {
         "id": "ueKaFVdR8Fz"
       }
@@ -54,10 +54,10 @@
         "id": "zU1OZFVxnw7"
       },
       "domainType": "AGGREGATE",
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "lastUpdated": "2016-02-27T03:17:13.827+0000",
       "valueType": "TEXT",
-      "aggregationLevels": [],
+      "aggregationLevels": [ ],
       "user": {
         "id": "ueKaFVdR8Fz"
       },
@@ -86,7 +86,7 @@
     {
       "publicAccess": "rw------",
       "aggregationType": "SUM",
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "domainType": "AGGREGATE",
       "id": "k90AVpBahO4",
       "categoryCombo": {
@@ -99,7 +99,7 @@
       "user": {
         "id": "ueKaFVdR8Fz"
       },
-      "aggregationLevels": [],
+      "aggregationLevels": [ ],
       "zeroIsSignificant": false,
       "created": "2016-02-27T03:17:51.961+0000",
       "attributeValues": [
@@ -126,14 +126,14 @@
   "options": [
     {
       "code": "Gender_Female",
-      "attributeValues": [],
+      "attributeValues": [ ],
       "lastUpdated": "2016-02-27T03:09:09.734+0000",
       "name": "Female",
       "id": "uBDO9S6MdoE",
       "created": "2016-02-27T03:09:09.734+0000"
     },
     {
-      "attributeValues": [],
+      "attributeValues": [ ],
       "code": "Gender_Male",
       "lastUpdated": "2016-02-27T03:09:03.161+0000",
       "id": "IoxIRLL7ZTU",
@@ -145,7 +145,7 @@
   "userRoles": [
     {
       "lastUpdated": "2016-02-17T06:14:12.260+0000",
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "created": "2016-02-17T06:14:12.260+0000",
       "name": "Superuser",
       "id": "rKLtmQLRMU8",
@@ -184,8 +184,8 @@
         "F_APPROVE_DATA_LOWER_LEVELS",
         "F_TRACKED_ENTITY_DATAVALUE_DELETE"
       ],
-      "dataSets": [],
-      "programs": [],
+      "dataSets": [ ],
+      "programs": [ ],
       "publicAccess": "--------"
     }
   ],
@@ -208,7 +208,7 @@
       "featureType": "NONE",
       "lastUpdated": "2016-02-17T06:17:01.228+0000",
       "code": "OrgUnitCodeA",
-      "attributeValues": [],
+      "attributeValues": [ ],
       "uuid": "6ea86a20-1eb1-4bbd-87ea-948ee1e01f20",
       "description": "",
       "created": "2016-02-17T06:17:01.218+0000",
@@ -220,7 +220,7 @@
   "categories": [
     {
       "created": "2016-02-17T06:13:29.131+0000",
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "name": "default",
       "id": "XSypGD15atv",
       "lastUpdated": "2016-02-27T03:27:08.138+0000",
@@ -237,7 +237,7 @@
   "trackedEntities": [
     {
       "lastUpdated": "2016-02-17T06:25:08.000+0000",
-      "attributeValues": [],
+      "attributeValues": [ ],
       "description": "Person",
       "created": "2016-02-17T06:25:08.000+0000",
       "name": "Person",
@@ -326,7 +326,7 @@
     {
       "publicAccess": "--------",
       "created": "2016-02-17T06:13:29.133+0000",
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "name": "default",
       "skipTotal": false,
       "id": "zU1OZFVxnw7",
@@ -349,13 +349,13 @@
         }
       ],
       "validCompleteOnly": false,
-      "attributeValues": [],
+      "attributeValues": [ ],
       "code": "DataSetCodeA",
       "fieldCombinationRequired": false,
       "user": {
         "id": "ueKaFVdR8Fz"
       },
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "dataElements": [
         {
           "id": "CCwk5Yx440o"
@@ -368,9 +368,9 @@
       "noValueRequiresComment": false,
       "shortName": "DataSetShortA",
       "name": "DataSetA",
-      "indicators": [],
+      "indicators": [ ],
       "renderHorizontally": false,
-      "compulsoryDataElementOperands": [],
+      "compulsoryDataElementOperands": [ ],
       "categoryCombo": {
         "id": "zU1OZFVxnw7"
       },
@@ -392,8 +392,8 @@
       "id": "ueKaFVdR8Fz",
       "firstName": "admin",
       "created": "2016-02-17T06:14:12.250+0000",
-      "dataViewOrganisationUnits": [],
-      "attributeValues": [],
+      "dataViewOrganisationUnits": [ ],
+      "attributeValues": [ ],
       "surname": "admin",
       "organisationUnits": [
         {
@@ -402,8 +402,9 @@
       ],
       "lastUpdated": "2016-02-17T06:14:12.250+0000",
       "userCredentials": {
-        "cogsDimensionConstraints": [],
-        "catDimensionConstraints": [],
+        "id": "m3ww4DWJtMf",
+        "cogsDimensionConstraints": [ ],
+        "catDimensionConstraints": [ ],
         "invitation": false,
         "username": "admin",
         "selfRegistered": false,
@@ -431,7 +432,7 @@
         "id": "ueKaFVdR8Fz"
       },
       "code": "Gender",
-      "attributeValues": [],
+      "attributeValues": [ ],
       "lastUpdated": "2016-02-27T03:09:09.736+0000",
       "valueType": "TEXT",
       "name": "Gender",
@@ -444,7 +445,7 @@
           "id": "uBDO9S6MdoE"
         }
       ],
-      "userGroupAccesses": [],
+      "userGroupAccesses": [ ],
       "created": "2016-02-27T03:08:49.239+0000"
     }
   ],
@@ -454,10 +455,10 @@
       "shortName": "default",
       "name": "default",
       "created": "2016-02-17T06:13:29.120+0000",
-      "userGroupAccesses": [],
-      "attributeValues": [],
+      "userGroupAccesses": [ ],
+      "attributeValues": [ ],
       "lastUpdated": "2016-02-17T06:13:29.137+0000",
-      "organisationUnits": [],
+      "organisationUnits": [ ],
       "publicAccess": "--------"
     }
   ]

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/user_duplicate_username.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/user_duplicate_username.json	2016-03-14 06:31:31 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/user_duplicate_username.json	2016-03-14 08:30:30 +0000
@@ -82,6 +82,7 @@
         }
       ],
       "userCredentials": {
+        "id": "mcHDMwMMdPZ",
         "user": {
           "id": "enHApD3I6Ho"
         },
@@ -127,6 +128,7 @@
         }
       ],
       "userCredentials": {
+        "id": "Tp9lYEAOEg0",
         "username": "admin",
         "userRoles": [
           {

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/users.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/users.json	2016-03-12 06:43:22 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/users.json	2016-03-14 08:30:30 +0000
@@ -152,6 +152,7 @@
         }
       ],
       "userCredentials": {
+        "id": "yqJHNnkF3SJ",
         "user": {
           "id": "enHApD3I6Ho"
         },
@@ -197,6 +198,7 @@
         }
       ],
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "username": "UserA",
         "userRoles": [
           {
@@ -235,6 +237,7 @@
         }
       ],
       "userCredentials": {
+        "id": "EgBSdwGi7rr",
         "externalAuth": false,
         "disabled": false,
         "invitation": false,

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/users_update.json'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/users_update.json	2016-03-12 08:52:42 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/users_update.json	2016-03-14 08:30:30 +0000
@@ -152,6 +152,7 @@
         }
       ],
       "userCredentials": {
+        "id": "yqJHNnkF3SJ",
         "user": {
           "id": "enHApD3I6Ho"
         },
@@ -197,6 +198,7 @@
         }
       ],
       "userCredentials": {
+        "id": "m3ww4DWJtMf",
         "username": "UserAA",
         "userRoles": [
           {
@@ -235,6 +237,7 @@
         }
       ],
       "userCredentials": {
+        "id": "EgBSdwGi7rr",
         "externalAuth": false,
         "disabled": false,
         "invitation": false,