← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17790: Bulk invite, better validation

 

------------------------------------------------------------
revno: 17790
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2014-12-24 15:44:09 +0100
message:
  Bulk invite, better validation
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/importsummary/ImportSummary.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ImportTypeSummary.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.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/user/UserGroupService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupService.java	2014-12-24 11:38:09 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupService.java	2014-12-24 14:44:09 +0000
@@ -45,7 +45,7 @@
 
     UserGroup getUserGroup( String uid );
 
-    boolean canAddOrRemove( String uid );
+    boolean canAddOrRemoveMember( String uid );
     
     void addUserToGroups( User user, Collection<String> uids );
     

=== 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	2014-12-24 11:38:09 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserGroupService.java	2014-12-24 14:44:09 +0000
@@ -105,7 +105,7 @@
     }
 
     @Override
-    public boolean canAddOrRemove( String uid )
+    public boolean canAddOrRemoveMember( String uid )
     {
         User currentUser = currentUserService.getCurrentUser();
         
@@ -127,7 +127,7 @@
     {        
         for ( String uid : uids )
         {
-            if ( canAddOrRemove( uid ) )
+            if ( canAddOrRemoveMember( uid ) )
             {
                 UserGroup userGroup = getUserGroup( uid );
                 user.getGroups().add( userGroup );
@@ -142,7 +142,7 @@
     {
         for ( String uid : uids )
         {
-            if ( canAddOrRemove( uid ) )
+            if ( canAddOrRemoveMember( uid ) )
             {
                 UserGroup userGroup = getUserGroup( uid );
                 user.getGroups().remove( userGroup );

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/importsummary/ImportSummary.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/importsummary/ImportSummary.java	2014-08-15 07:40:20 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/importsummary/ImportSummary.java	2014-12-24 14:44:09 +0000
@@ -44,7 +44,7 @@
 
     private String description;
 
-    /* we want to phase out this at some point, use importCount instead */
+    /* Phase out this at some point, use importCount instead */
     private ImportCount dataValueCount = new ImportCount();
 
     private ImportCount importCount = new ImportCount();
@@ -61,16 +61,29 @@
     {
     }
 
+    public ImportSummary( ImportStatus status )
+    {
+        this.status = status;
+    }
+
     public ImportSummary( ImportStatus status, String description )
     {
         this.status = status;
         this.description = description;
     }
 
-    public ImportSummary( ImportStatus status )
+    // -------------------------------------------------------------------------
+    // Logic
+    // -------------------------------------------------------------------------
+
+    public boolean isStatus( ImportStatus status )
     {
-        this.status = status;
+        return this.status != null && this.status.equals( status );
     }
+    
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
 
     @JsonProperty
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ImportTypeSummary.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ImportTypeSummary.java	2014-10-16 06:17:19 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ImportTypeSummary.java	2014-12-24 14:44:09 +0000
@@ -65,6 +65,10 @@
         this.type = type;
     }
 
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
     @JsonProperty
     @JacksonXmlProperty( isAttribute = true )
     public String getType()

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java	2014-12-24 11:38:09 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java	2014-12-24 14:44:09 +0000
@@ -40,10 +40,9 @@
 
 import org.hisp.dhis.common.IdentifiableObjectUtils;
 import org.hisp.dhis.common.Pager;
+import org.hisp.dhis.dxf2.importsummary.ImportStatus;
 import org.hisp.dhis.dxf2.importsummary.ImportSummary;
 import org.hisp.dhis.dxf2.metadata.ImportTypeSummary;
-import org.hisp.dhis.hibernate.exception.CreateAccessDeniedException;
-import org.hisp.dhis.hibernate.exception.UpdateAccessDeniedException;
 import org.hisp.dhis.importexport.ImportStrategy;
 import org.hisp.dhis.node.types.RootNode;
 import org.hisp.dhis.schema.descriptors.UserSchemaDescriptor;
@@ -168,7 +167,12 @@
     {
         User user = renderService.fromXml( request.getInputStream(), getEntityClass() );
 
-        createUser( user );
+        if ( !validateCreateUser( user, response ) )
+        {
+            return;
+        }
+        
+        renderService.toXml( response.getOutputStream(), createUser( user, response ) );
     }
 
     @Override
@@ -177,7 +181,12 @@
     {
         User user = renderService.fromJson( request.getInputStream(), getEntityClass() );
 
-        createUser( user );
+        if ( !validateCreateUser( user, response ) )
+        {
+            return;
+        }
+        
+        renderService.toJson( response.getOutputStream(), createUser( user, response ) );
     }
 
     @RequestMapping( value = INVITE_PATH, method = RequestMethod.POST, consumes = { "application/xml", "text/xml" } )
@@ -185,7 +194,12 @@
     {
         User user = renderService.fromXml( request.getInputStream(), getEntityClass() );
 
-        inviteUser( user, request, response );
+        if ( !validateInviteUser( user, response ) )
+        {
+            return;
+        }
+        
+        renderService.toXml( response.getOutputStream(), inviteUser( user, request, response ) );
     }
 
     @RequestMapping( value = INVITE_PATH, method = RequestMethod.POST, consumes = "application/json" )
@@ -193,7 +207,12 @@
     {
         User user = renderService.fromJson( request.getInputStream(), getEntityClass() );
 
-        inviteUser( user, request, response );
+        if ( !validateInviteUser( user, response ) )
+        {
+            return;
+        }
+        
+        renderService.toJson( response.getOutputStream(), inviteUser( user, request, response ) );
     }
 
     @RequestMapping( value = BULK_INVITE_PATH, method = RequestMethod.POST, consumes = { "application/xml", "text/xml" } )
@@ -240,8 +259,8 @@
 
     @Override
     @RequestMapping( value = "/{uid}", method = RequestMethod.PUT, consumes = { "application/xml", "text/xml" } )
-    public void putXmlObject( HttpServletResponse response, HttpServletRequest request, @PathVariable( "uid" ) String uid, InputStream
-        input ) throws Exception
+    public void putXmlObject( HttpServletResponse response, HttpServletRequest request, 
+        @PathVariable( "uid" ) String uid, InputStream input ) throws Exception
     {
         List<User> users = getEntity( uid );
 
@@ -253,7 +272,8 @@
 
         if ( !aclService.canUpdate( currentUserService.getCurrentUser(), users.get( 0 ) ) )
         {
-            throw new UpdateAccessDeniedException( "You don't have the proper permissions to update this object." );
+            ContextUtils.conflictResponse( response, "You don't have the proper permissions to update this object." );
+            return;
         }
 
         User parsed = renderService.fromXml( request.getInputStream(), getEntityClass() );
@@ -261,18 +281,19 @@
 
         if ( !userService.canAddOrUpdateUser( IdentifiableObjectUtils.getUids( parsed.getGroups() ) ) )
         {
-            throw new CreateAccessDeniedException( "You must have permissions to create user, or ability to manage at least one user group for the user." );
+            ContextUtils.conflictResponse( response, "You must have permissions to create user, or ability to manage at least one user group for the user." );
+            return;
         }
 
-        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed,
-            ImportStrategy.UPDATE );
+        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, ImportStrategy.UPDATE );
+        
         renderService.toXml( response.getOutputStream(), summary );
     }
 
     @Override
     @RequestMapping( value = "/{uid}", method = RequestMethod.PUT, consumes = "application/json" )
-    public void putJsonObject( HttpServletResponse response, HttpServletRequest request, @PathVariable( "uid" ) String uid, InputStream
-        input ) throws Exception
+    public void putJsonObject( HttpServletResponse response, HttpServletRequest request, 
+        @PathVariable( "uid" ) String uid, InputStream input ) throws Exception
     {
         List<User> users = getEntity( uid );
 
@@ -284,7 +305,8 @@
 
         if ( !aclService.canUpdate( currentUserService.getCurrentUser(), users.get( 0 ) ) )
         {
-            throw new UpdateAccessDeniedException( "You don't have the proper permissions to update this object." );
+            ContextUtils.conflictResponse( response, "You don't have the proper permissions to update this object." );
+            return;
         }
 
         User parsed = renderService.fromJson( request.getInputStream(), getEntityClass() );
@@ -292,11 +314,12 @@
         
         if ( !userService.canAddOrUpdateUser( IdentifiableObjectUtils.getUids( parsed.getGroups() ) ) )
         {
-            throw new CreateAccessDeniedException( "You must have permissions to create user, or ability to manage at least one user group for the user." );
+            ContextUtils.conflictResponse( response, "You must have permissions to create user, or ability to manage at least one user group for the user." );
+            return;
         }
 
-        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed,
-            ImportStrategy.UPDATE );
+        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, ImportStrategy.UPDATE );
+        
         renderService.toJson( response.getOutputStream(), summary );
     }
 
@@ -304,8 +327,77 @@
     // Supportive methods
     // -------------------------------------------------------------------------
 
+    /**
+     * Validates whether the given user can be created.
+     * 
+     * @param user the user.
+     * @param response the response.
+     */
+    private boolean validateCreateUser( User user, HttpServletResponse response )
+    {
+        if ( !aclService.canCreate( currentUserService.getCurrentUser(), getEntityClass() ) )
+        {
+            ContextUtils.conflictResponse( response, "You don't have the proper permissions to create this object." );
+            return false;
+        }
+
+        if ( !userService.canAddOrUpdateUser( IdentifiableObjectUtils.getUids( user.getGroups() ) ) )
+        {
+            ContextUtils.conflictResponse( response, "You must have permissions to create user, or ability to manage at least one user group for the user." );
+            return false;
+        }
+        
+        List<String> uids = IdentifiableObjectUtils.getUids( user.getGroups() );
+        
+        for ( String uid : uids )
+        {
+            if ( !userGroupService.canAddOrRemoveMember( uid ) )
+            {
+                ContextUtils.conflictResponse( response, "You don't have permissions to add user to user group: " + uid );
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    /**
+     * Creates a user.
+     *
+     * @param user user object parsed from the POST request.
+     * @param response the response.
+     */
+    private ImportSummary createUser( User user, HttpServletResponse response ) throws Exception
+    {
+        user.getUserCredentials().getCogsDimensionConstraints().addAll(
+            currentUserService.getCurrentUser().getUserCredentials().getCogsDimensionConstraints() );
+
+        user.getUserCredentials().getCatDimensionConstraints().addAll(
+            currentUserService.getCurrentUser().getUserCredentials().getCatDimensionConstraints() );
+
+        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), user, ImportStrategy.CREATE );
+
+        if ( summary.isStatus( ImportStatus.SUCCESS ) && summary.getImportCount().getImported() == 1 )
+        {        
+            userGroupService.addUserToGroups( user, IdentifiableObjectUtils.getUids( user.getGroups() ) );
+        }
+
+        return summary;
+    }
+    
+    /**
+     * Validates whether a user can be invited / created.
+     * 
+     * @param user the user.
+     * @param response the response.
+     */
     private boolean validateInviteUser( User user, HttpServletResponse response )
     {
+        if ( !validateCreateUser( user, response ) )
+        {
+            return false;
+        }
+        
         UserCredentials credentials = user.getUserCredentials();
 
         if ( credentials == null )
@@ -339,69 +431,26 @@
     }
     
     /**
-     * Creates a user invitation and invites the user
+     * Creates a user invitation and invites the user.
      *
-     * @param user user object parsed from the POST request
-     * @param response response for created user invitation
+     * @param user user object parsed from the POST request.
+     * @param response the response.
      */
-    private void inviteUser( User user, HttpServletRequest request, HttpServletResponse response ) throws Exception
+    private ImportSummary inviteUser( User user, HttpServletRequest request, HttpServletResponse response ) throws Exception
     {
-        if ( !validateInviteUser( user, response ) )
-        {
-            return;
-        }
-
         RestoreOptions restoreOptions = user.getUsername() == null || user.getUsername().isEmpty() ?
             RestoreOptions.INVITE_WITH_USERNAME_CHOICE : RestoreOptions.INVITE_WITH_DEFINED_USERNAME;
 
         securityService.prepareUserForInvite( user );
 
-        ImportSummary summary = createUser( user );
-
-        securityService.sendRestoreMessage( user.getUserCredentials(),
-            ContextUtils.getContextPath( request ), restoreOptions );
-
-        renderService.toJson( response.getOutputStream(), summary );
-    }
-
-    /**
-     * Creates a user
-     *
-     * @param user user object parsed from the POST request
-     * @param response response for created user
-     */
-    private ImportSummary createUser( User user ) throws Exception
-    {
-        if ( !aclService.canCreate( currentUserService.getCurrentUser(), getEntityClass() ) )
-        {
-            throw new CreateAccessDeniedException( "You don't have the proper permissions to create this object." );
-        }
-
-        if ( !userService.canAddOrUpdateUser( IdentifiableObjectUtils.getUids( user.getGroups() ) ) )
-        {
-            throw new CreateAccessDeniedException( "You must have permissions to create user, or ability to manage at least one user group for the user." );
-        }
-        
-        List<String> uids = IdentifiableObjectUtils.getUids( user.getGroups() );
-        
-        for ( String uid : uids )
-        {
-            if ( !userGroupService.canAddOrRemove( uid ) )
-            {
-                throw new CreateAccessDeniedException( "You don't have permissions to add user to user group: " + uid );
-            }
-        }
-
-        user.getUserCredentials().getCogsDimensionConstraints().addAll(
-            currentUserService.getCurrentUser().getUserCredentials().getCogsDimensionConstraints() );
-
-        user.getUserCredentials().getCatDimensionConstraints().addAll(
-            currentUserService.getCurrentUser().getUserCredentials().getCatDimensionConstraints() );
-
-        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), user, ImportStrategy.CREATE );
-
-        userGroupService.addUserToGroups( user, IdentifiableObjectUtils.getUids( user.getGroups() ) );
-
-        return summary;             
+        ImportSummary summary = createUser( user, response );
+
+        if ( summary.isStatus( ImportStatus.SUCCESS ) && summary.getImportCount().getImported() == 1 )
+        {
+            securityService.sendRestoreMessage( user.getUserCredentials(),
+                ContextUtils.getContextPath( request ), restoreOptions );
+        }
+
+        return summary;
     }
 }