add useraccounts resource which is responsible for supporting capabilities that allow a user update their account details.

This commit is contained in:
Keith Woodlock
2012-05-14 17:00:40 +01:00
parent 5ccecb8bc4
commit 06ac2869b7
10 changed files with 207 additions and 263 deletions
@@ -2,7 +2,6 @@ package org.mifosng.platform;
import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.command.AdjustLoanTransactionCommand;
import org.mifosng.data.command.ChangePasswordCommand;
import org.mifosng.data.command.EnrollClientCommand;
import org.mifosng.data.command.LoanStateTransitionCommand;
import org.mifosng.data.command.LoanTransactionCommand;
@@ -12,15 +11,10 @@ import org.mifosng.data.command.SubmitLoanApplicationCommand;
import org.mifosng.data.command.UndoLoanApprovalCommand;
import org.mifosng.data.command.UndoLoanDisbursalCommand;
import org.mifosng.data.command.UpdateUsernamePasswordCommand;
import org.mifosng.data.command.UserCommand;
import org.springframework.security.access.prepost.PreAuthorize;
public interface WritePlatformService {
Long updateCurrentUser(UserCommand command);
Long updateCurrentUserPassword(ChangePasswordCommand command);
Long createRole(RoleCommand command);
Long updateRole(RoleCommand command);
@@ -20,7 +20,6 @@ import org.mifosng.data.MoneyData;
import org.mifosng.data.ScheduledLoanInstallment;
import org.mifosng.data.command.AdjustLoanTransactionCommand;
import org.mifosng.data.command.CalculateLoanScheduleCommand;
import org.mifosng.data.command.ChangePasswordCommand;
import org.mifosng.data.command.EnrollClientCommand;
import org.mifosng.data.command.LoanStateTransitionCommand;
import org.mifosng.data.command.LoanTransactionCommand;
@@ -30,7 +29,6 @@ import org.mifosng.data.command.SubmitLoanApplicationCommand;
import org.mifosng.data.command.UndoLoanApprovalCommand;
import org.mifosng.data.command.UndoLoanDisbursalCommand;
import org.mifosng.data.command.UpdateUsernamePasswordCommand;
import org.mifosng.data.command.UserCommand;
import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.ClientRepository;
import org.mifosng.platform.client.domain.Note;
@@ -70,7 +68,6 @@ import org.mifosng.platform.user.domain.PermissionRepository;
import org.mifosng.platform.user.domain.PlatformUserRepository;
import org.mifosng.platform.user.domain.Role;
import org.mifosng.platform.user.domain.RoleRepository;
import org.mifosng.platform.user.service.UserCommandValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.core.Authentication;
@@ -92,7 +89,6 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
private final CalculationPlatformService calculationPlatformService;
private final RoleRepository roleRepository;
private final PermissionRepository permissionRepository;
private final AppUserRepository appUserRepository;
private final NoteRepository noteRepository;
private final LoanTransactionRepository loanTransactionRepository;
@@ -108,7 +104,6 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
final LoanTransactionRepository loanTransactionRepository,
final LoanStatusRepository loanStatusRepository,
final CalculationPlatformService calculationPlatformService,
final AppUserRepository appUserRepository,
final RoleRepository roleRepository,
final PermissionRepository permissionRepository) {
this.officeRepository = officeRepository;
@@ -121,50 +116,10 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
this.loanTransactionRepository = loanTransactionRepository;
this.loanStatusRepository = loanStatusRepository;
this.calculationPlatformService = calculationPlatformService;
this.appUserRepository = appUserRepository;
this.roleRepository = roleRepository;
this.permissionRepository = permissionRepository;
}
@Transactional
@Override
public Long updateCurrentUser(UserCommand command) {
AppUser currentUser = extractAuthenticatedUser();
UserCommandValidator validator = new UserCommandValidator(command);
validator.validateAccountSettingDetails();
AppUser userToUpdate = this.appUserRepository.findOne(currentUser.getId());
userToUpdate.update(command.getUsername(), command.getFirstname(), command.getLastname(), command.getEmail());
this.appUserRepository.save(userToUpdate);
return userToUpdate.getId();
}
@Transactional
@Override
public Long updateCurrentUserPassword(ChangePasswordCommand command) {
AppUser currentUser = extractAuthenticatedUser();
ChangePasswordCommandValidator validator = new ChangePasswordCommandValidator(command);
validator.validate();
AppUser userToUpdate = this.appUserRepository.findOne(currentUser.getId());
PlatformUser dummyPlatformUser = new BasicPasswordEncodablePlatformUser(
((AppUser) userToUpdate).getId(),
userToUpdate.getUsername(), command.getPassword());
String newPasswordEncoded = this.platformPasswordEncoder
.encode(dummyPlatformUser);
userToUpdate.updatePasswordOnFirstTimeLogin(newPasswordEncoded);
return userToUpdate.getId();
}
@Transactional
@Override
public Long createRole(final RoleCommand command) {
@@ -0,0 +1,96 @@
package org.mifosng.platform.api.user;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.mifosng.data.AppUserData;
import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.command.ChangePasswordCommand;
import org.mifosng.data.command.UserCommand;
import org.mifosng.platform.ReadPlatformService;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.mifosng.platform.user.service.AppUserWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Path("/v1/useraccounts")
@Component
@Scope("singleton")
public class UserAccountApiResource {
@Autowired
private ReadPlatformService readPlatformService;
@Autowired
private AppUserWritePlatformService appUserWritePlatformService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@GET
@Path("current")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveCurrentUser() {
hardcodeUserIntoSecurityContext();
AppUserData user = this.readPlatformService.retrieveCurrentUser();
return Response.ok().entity(user).build();
}
@PUT
@Path("current")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response updateCurrentUser(UserCommand command) {
hardcodeUserIntoSecurityContext();
Long userId = this.appUserWritePlatformService.updateCurrentUser(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
}
@GET
@Path("current/password/template")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveCurrentPasswordTemplate() {
return Response.ok().entity(new ChangePasswordCommand()).build();
}
@PUT
@Path("current/password")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response updateCurrentUserPassword(ChangePasswordCommand command) {
hardcodeUserIntoSecurityContext();
Long userId = this.appUserWritePlatformService.updateCurrentUserPassword(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
}
}
@@ -15,7 +15,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.mifosng.data.AppUserData;
import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.EnumOptionList;
import org.mifosng.data.EnumOptionReadModel;
@@ -25,9 +24,7 @@ import org.mifosng.data.PermissionData;
import org.mifosng.data.PermissionList;
import org.mifosng.data.RoleData;
import org.mifosng.data.RoleList;
import org.mifosng.data.command.ChangePasswordCommand;
import org.mifosng.data.command.RoleCommand;
import org.mifosng.data.command.UserCommand;
import org.mifosng.platform.ReadPlatformService;
import org.mifosng.platform.WritePlatformService;
import org.mifosng.platform.exceptions.ApplicationDomainRuleException;
@@ -35,7 +32,6 @@ import org.mifosng.platform.exceptions.NewDataValidationException;
import org.mifosng.platform.exceptions.UnAuthenticatedUserException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Component;
@@ -50,79 +46,6 @@ public class UserAdmistrationResource {
@Autowired
private WritePlatformService writePlatformService;
@GET
@Path("user/current")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response retrieveCurrentUser() {
try {
AppUserData user = this.readPlatformService.retrieveCurrentUser();
return Response.ok().entity(user).build();
} catch (UnAuthenticatedUserException e) {
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
} catch (AccessDeniedException e) {
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
} catch (ApplicationDomainRuleException e) {
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
} catch (NewDataValidationException e) {
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
}
}
@POST
@Path("user/current")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response updateCurrentUser(UserCommand command) {
try {
Long userId = this.writePlatformService.updateCurrentUser(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
} catch (UnAuthenticatedUserException e) {
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
} catch (AccessDeniedException e) {
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
} catch (ApplicationDomainRuleException e) {
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
} catch (NewDataValidationException e) {
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
} catch (DataIntegrityViolationException e) {
ErrorResponse errorResponse = new ErrorResponse("error.msg.username.already.exists.in.organisation", "username", command.getUsername());
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
}
}
@POST
@Path("user/current/password")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response updateCurrentUserPassword(ChangePasswordCommand command) {
try {
Long userId = this.writePlatformService.updateCurrentUserPassword(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
} catch (UnAuthenticatedUserException e) {
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
} catch (AccessDeniedException e) {
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
} catch (ApplicationDomainRuleException e) {
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
} catch (NewDataValidationException e) {
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
}
}
@GET
@Path("role/all")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@@ -1,5 +1,6 @@
package org.mifosng.platform.user.service;
import org.mifosng.data.command.ChangePasswordCommand;
import org.mifosng.data.command.UserCommand;
public interface AppUserWritePlatformService {
@@ -9,4 +10,8 @@ public interface AppUserWritePlatformService {
Long updateUser(final UserCommand command);
void deleteUser(final Long userId);
Long updateCurrentUser(UserCommand command);
Long updateCurrentUserPassword(ChangePasswordCommand command);
}
@@ -9,11 +9,16 @@ import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosng.data.ApiParameterError;
import org.mifosng.data.command.ChangePasswordCommand;
import org.mifosng.data.command.UserCommand;
import org.mifosng.platform.ChangePasswordCommandValidator;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.exceptions.PlatformResourceNotFoundException;
import org.mifosng.platform.infrastructure.BasicPasswordEncodablePlatformUser;
import org.mifosng.platform.infrastructure.PlatformEmailSendException;
import org.mifosng.platform.infrastructure.PlatformPasswordEncoder;
import org.mifosng.platform.infrastructure.PlatformUser;
import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.OfficeRepository;
import org.mifosng.platform.security.PlatformSecurityContext;
@@ -35,19 +40,21 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
private final static Logger logger = LoggerFactory.getLogger(AppUserWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final UserDomainService userDomainService;
private final PlatformPasswordEncoder platformPasswordEncoder;
private final AppUserRepository appUserRepository;
private final OfficeRepository officeRepository;
private final RoleRepository roleRepository;
private final UserDomainService userDomainService;
@Autowired
public AppUserWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final AppUserRepository appUserRepository, final UserDomainService userDomainService,
final OfficeRepository officeRepository, final RoleRepository roleRepository) {
final OfficeRepository officeRepository, final RoleRepository roleRepository, final PlatformPasswordEncoder platformPasswordEncoder) {
this.context = context;
this.appUserRepository = appUserRepository;
this.userDomainService = userDomainService;
this.officeRepository = officeRepository;
this.roleRepository = roleRepository;
this.platformPasswordEncoder = platformPasswordEncoder;
}
@Transactional
@@ -142,6 +149,44 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
public void deleteUser(Long userId) {
this.appUserRepository.delete(userId);
}
@Transactional
@Override
public Long updateCurrentUser(UserCommand command) {
AppUser currentUser = context.authenticatedUser();
UserCommandValidator validator = new UserCommandValidator(command);
validator.validateAccountSettingDetails();
AppUser userToUpdate = this.appUserRepository.findOne(currentUser.getId());
userToUpdate.update(command.getUsername(), command.getFirstname(), command.getLastname(), command.getEmail());
this.appUserRepository.save(userToUpdate);
return userToUpdate.getId();
}
@Transactional
@Override
public Long updateCurrentUserPassword(ChangePasswordCommand command) {
AppUser currentUser = context.authenticatedUser();
ChangePasswordCommandValidator validator = new ChangePasswordCommandValidator(command);
validator.validate();
AppUser userToUpdate = this.appUserRepository.findOne(currentUser.getId());
PlatformUser dummyPlatformUser = new BasicPasswordEncodablePlatformUser(
((AppUser) userToUpdate).getId(),
userToUpdate.getUsername(), command.getPassword());
String newPasswordEncoded = this.platformPasswordEncoder.encode(dummyPlatformUser);
userToUpdate.updatePasswordOnFirstTimeLogin(newPasswordEncoded);
return userToUpdate.getId();
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue is.