dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #30372
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15421: Add to webapi: POST /users/invite
Merge authors:
Jim Grace (jimgrace)
------------------------------------------------------------
revno: 15421 [merge]
committer: jimgrace@xxxxxxxxx
branch nick: dhis2
timestamp: Mon 2014-05-26 15:10:33 -0400
message:
Add to webapi: POST /users/invite
modified:
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-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.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-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 2014-03-27 08:25:39 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/DefaultSecurityService.java 2014-05-24 18:16:41 +0000
@@ -110,25 +110,25 @@
// SecurityService implementation
// -------------------------------------------------------------------------
- public boolean prepareUserForInvite( UserCredentials credentials )
+ public boolean prepareUserForInvite( User user )
{
- if ( credentials == null || credentials.getUser() == null )
+ if ( user == null || user.getUserCredentials() == null )
{
return false;
}
- if ( credentials.getUsername().isEmpty() )
+ if ( user.getUsername() == null || user.getUsername().isEmpty() )
{
String username = "user_invitation_" + CodeGenerator.generateCode( INVITED_USERNAME_UNIQUE_LENGTH );
- credentials.setUsername( username );
+ user.getUserCredentials().setUsername( username );
}
String rawPassword = CodeGenerator.generateCode( INVITED_USER_PASSWORD_LENGTH );
- credentials.getUser().setSurname( "(TBD)" );
- credentials.getUser().setFirstName( "(TBD)" );
- credentials.setPassword( passwordManager.encodePassword( credentials.getUsername(), rawPassword ) );
+ user.setSurname( "(TBD)" );
+ user.setFirstName( "(TBD)" );
+ user.getUserCredentials().setPassword( passwordManager.encodePassword( user.getUsername(), rawPassword ) );
return true;
}
=== 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 2014-03-18 08:10:10 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/SecurityService.java 2014-05-24 18:16:41 +0000
@@ -29,6 +29,7 @@
*/
import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.user.User;
import org.hisp.dhis.user.UserCredentials;
/**
@@ -40,10 +41,10 @@
* Sets information for a user who will be invited by email to finish
* setting up their user account.
*
- * @param credentials the credentials of the user to invite.
+ * @param user the user to invite.
* @return true if the invitation was sent, otherwise false.
*/
- boolean prepareUserForInvite( UserCredentials credentials );
+ boolean prepareUserForInvite( User user );
/**
* Invokes the initRestore method and dispatches email messages with
=== 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-05-22 12:40:24 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java 2014-05-26 19:10:33 +0000
@@ -29,6 +29,7 @@
*/
import com.google.common.collect.Lists;
+import org.apache.struts2.ServletActionContext;
import org.hisp.dhis.webapi.controller.AbstractCrudController;
import org.hisp.dhis.webapi.controller.WebMetaData;
import org.hisp.dhis.webapi.controller.WebOptions;
@@ -39,7 +40,12 @@
import org.hisp.dhis.hibernate.exception.UpdateAccessDeniedException;
import org.hisp.dhis.importexport.ImportStrategy;
import org.hisp.dhis.security.PasswordManager;
+import org.hisp.dhis.security.RestoreOptions;
+import org.hisp.dhis.security.SecurityService;
+import org.hisp.dhis.setting.SystemSettingManager;
import org.hisp.dhis.user.User;
+import org.hisp.dhis.user.UserGroup;
+import org.hisp.dhis.user.UserGroupService;
import org.hisp.dhis.user.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
@@ -59,6 +65,8 @@
import java.util.List;
import java.util.Map;
+import static org.hisp.dhis.setting.SystemSettingManager.KEY_ONLY_MANAGE_WITHIN_USER_GROUPS;
+
/**
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
*/
@@ -68,13 +76,23 @@
extends AbstractCrudController<User>
{
public static final String RESOURCE_PATH = "/users";
+ public static final String INVITE_PATH = "/invite";
@Autowired
private UserService userService;
@Autowired
+ private UserGroupService userGroupService;
+
+ @Autowired
private PasswordManager passwordManager;
+ @Autowired
+ private SecurityService securityService;
+
+ @Autowired
+ private SystemSettingManager systemSettingManager;
+
@Override
@PreAuthorize( "hasRole('ALL') or hasRole('F_USER_VIEW')" )
public String getObjectList( @RequestParam Map<String, String> parameters, Model model, HttpServletResponse response, HttpServletRequest request )
@@ -130,38 +148,34 @@
@RequestMapping( method = RequestMethod.POST, consumes = { "application/xml", "text/xml" } )
public void postXmlObject( HttpServletResponse response, HttpServletRequest request, InputStream input ) throws Exception
{
- if ( !aclService.canCreate( currentUserService.getCurrentUser(), getEntityClass() ) )
- {
- throw new CreateAccessDeniedException( "You don't have the proper permissions to create this object." );
- }
-
User user = renderService.fromXml( request.getInputStream(), getEntityClass() );
- String encodePassword = passwordManager.encodePassword( user.getUsername(),
- user.getUserCredentials().getPassword() );
- user.getUserCredentials().setPassword( encodePassword );
-
- ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), user, ImportStrategy.CREATE );
- renderService.toJson( response.getOutputStream(), summary );
+ createUser( user, response );
}
@Override
@RequestMapping( method = RequestMethod.POST, consumes = "application/json" )
public void postJsonObject( HttpServletResponse response, HttpServletRequest request, InputStream input ) throws Exception
{
- if ( !aclService.canCreate( currentUserService.getCurrentUser(), getEntityClass() ) )
- {
- throw new CreateAccessDeniedException( "You don't have the proper permissions to create this object." );
- }
-
- User user = renderService.fromJson( request.getInputStream(), getEntityClass() );
-
- String encodePassword = passwordManager.encodePassword( user.getUsername(),
- user.getUserCredentials().getPassword() );
- user.getUserCredentials().setPassword( encodePassword );
-
- ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), user, ImportStrategy.CREATE );
- renderService.toJson( response.getOutputStream(), summary );
+ User user = renderService.fromJson( request.getInputStream(), getEntityClass() );
+
+ createUser( user, response );
+ }
+
+ @RequestMapping( value = INVITE_PATH, method = RequestMethod.POST, consumes = { "application/xml", "text/xml" } )
+ public void postXmlInvite( HttpServletResponse response, HttpServletRequest request, InputStream input ) throws Exception
+ {
+ User user = renderService.fromXml( request.getInputStream(), getEntityClass() );
+
+ inviteUser( user, response );
+ }
+
+ @RequestMapping( value = INVITE_PATH, method = RequestMethod.POST, consumes = "application/json" )
+ public void postJsonInvite( HttpServletResponse response, HttpServletRequest request, InputStream input ) throws Exception
+ {
+ User user = renderService.fromJson( request.getInputStream(), getEntityClass() );
+
+ inviteUser( user, response );
}
//--------------------------------------------------------------------------
@@ -230,4 +244,128 @@
ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, ImportStrategy.UPDATE );
renderService.toJson( response.getOutputStream(), summary );
}
+
+ //--------------------------------------------------------------------------
+ // Supportive methods
+ //--------------------------------------------------------------------------
+
+ /**
+ * Creates a user invitation and invites the user
+ *
+ * @param user user object parsed from the POST request
+ * @param response response for created user invitation
+ * @throws Exception
+ */
+ private void inviteUser( User user, HttpServletResponse response ) throws Exception
+ {
+ RestoreOptions restoreOptions = user.getUsername() == null || user.getUsername().isEmpty() ?
+ RestoreOptions.INVITE_WITH_USERNAME_CHOICE : RestoreOptions.INVITE_WITH_DEFINED_USERNAME;
+
+ securityService.prepareUserForInvite( user );
+
+ createUser( user, response );
+
+ securityService.sendRestoreMessage( user.getUserCredentials(),
+ ContextUtils.getContextPath( ServletActionContext.getRequest() ), restoreOptions );
+ }
+
+ /**
+ * Creates a user
+ *
+ * @param user user object parsed from the POST request
+ * @param response response for created user
+ * @throws Exception
+ */
+ private void createUser( User user, HttpServletResponse response ) throws Exception
+ {
+ if ( currentUserService.getCurrentUser() == null )
+ {
+ throw new CreateAccessDeniedException( "Internal error: currentUserService.getCurrentUser() returns null." );
+ }
+
+ if ( !aclService.canCreate( currentUserService.getCurrentUser(), getEntityClass() ) )
+ {
+ throw new CreateAccessDeniedException( "You don't have the proper permissions to create this object." );
+ }
+
+ checkUserGroups( user );
+
+ user.getUserCredentials().getCogsDimensionConstraints().addAll(
+ currentUserService.getCurrentUser().getUserCredentials().getCogsDimensionConstraints() );
+
+ String encodePassword = passwordManager.encodePassword( user.getUsername(),
+ user.getUserCredentials().getPassword() );
+ user.getUserCredentials().setPassword( encodePassword );
+
+ ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), user, ImportStrategy.CREATE );
+
+ renderService.toJson( response.getOutputStream(), summary );
+
+ addUserGroups( user );
+ }
+
+ /**
+ * Before adding the user, checks to see that any specified user groups
+ * exist. Also checks to see that user can be created by the current
+ * user, if it is required that the current user have read/write access
+ * to a user group that is assigned to the new user.
+ *
+ * @param user user object parsed from the POST request
+ */
+ private void checkUserGroups( User user )
+ {
+ boolean writeGroupRequired = (Boolean) systemSettingManager.getSystemSetting( KEY_ONLY_MANAGE_WITHIN_USER_GROUPS, false );
+
+ boolean writeGroupFound = false;
+
+ if ( currentUserService.getCurrentUser() != null && user.getGroups() != null )
+ {
+ for ( UserGroup ug : user.getGroups() )
+ {
+ UserGroup group = userGroupService.getUserGroup( ug.getUid() );
+
+ if ( group == null )
+ {
+ throw new UpdateAccessDeniedException( "Can't add user: Can't find user group with UID = " + ug.getUid() );
+ }
+
+ if ( writeGroupRequired && securityService.canWrite( group ) )
+ {
+ writeGroupFound = true;
+
+ break;
+ }
+ }
+ }
+
+ if ( writeGroupRequired && !writeGroupFound )
+ {
+ throw new CreateAccessDeniedException( "The new user must be assigned to a user group to which you have write access." );
+ }
+ }
+
+ /**
+ * Adds user groups (if any) to the newly-created user
+ *
+ * @param user user object (including user groups) parsed from the POST request
+ */
+ private void addUserGroups( User user )
+ {
+ if ( user.getGroups() != null )
+ {
+ boolean writeGroupRequired = (Boolean) systemSettingManager.getSystemSetting( KEY_ONLY_MANAGE_WITHIN_USER_GROUPS, false );
+
+ for ( UserGroup ug : new ArrayList<UserGroup>( user.getGroups() ) )
+ {
+ UserGroup group = userGroupService.getUserGroup( ug.getUid() );
+
+ if ( group != null && ( !writeGroupRequired || securityService.canWrite( group ) ) )
+ {
+ group.addUser( user );
+
+ userGroupService.updateUserGroup( group );
+ }
+ }
+ }
+ }
}
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java 2014-05-22 12:40:24 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java 2014-05-26 19:10:33 +0000
@@ -342,7 +342,7 @@
userCredentials.setUsername( inviteUsername );
user.setEmail( inviteEmail );
- securityService.prepareUserForInvite( userCredentials );
+ securityService.prepareUserForInvite( user );
}
else
{