first steps around moving users to new approach.

This commit is contained in:
Keith Woodlock
2012-05-14 12:47:16 +01:00
parent 9ddaf4c003
commit 7947dda4fe
12 changed files with 449 additions and 279 deletions
@@ -1,12 +1,16 @@
package org.mifosng.data.command; package org.mifosng.data.command;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
/** /**
* create or update user details command. * create or update user details command.
*/ */
@XmlRootElement @XmlRootElement
public class UserCommand { public class UserCommand implements Serializable {
private Long id; private Long id;
private String username; private String username;
@@ -14,40 +18,15 @@ public class UserCommand {
private String lastname; private String lastname;
private String password; private String password;
private String email; private String email;
private String[] roleIds;
private Long officeId; private Long officeId;
private List<String> notSelectedItems = new ArrayList<String>();
private List<String> selectedItems = new ArrayList<String>();
public UserCommand() { public UserCommand() {
// //
} }
public UserCommand(final String username, final String firstname, final String lastname, final String password,
final String email, final String[] roleIds, final Long officeId) {
this.username = username;
this.firstname = firstname;
this.lastname = lastname;
this.password = password;
this.email = email;
this.roleIds = roleIds;
this.officeId = officeId;
}
public UserCommand(final String username, final String firstname, final String lastname, final String email) {
this.username = username;
this.firstname = firstname;
this.lastname = lastname;
this.email = email;
}
public UserCommand(final String username, final String password,
final String email, final String[] roleIds, final Long officeId) {
this.username = username;
this.password = password;
this.email = email;
this.roleIds = roleIds;
this.officeId = officeId;
}
public String getDisplayName() { public String getDisplayName() {
return new StringBuilder(this.lastname).append(", ").append(this.firstname).toString(); return new StringBuilder(this.lastname).append(", ").append(this.firstname).toString();
} }
@@ -76,14 +55,6 @@ public class UserCommand {
this.email = email; this.email = email;
} }
public String[] getRoleIds() {
return this.roleIds;
}
public void setRoleIds(final String[] roleIds) {
this.roleIds = roleIds;
}
public Long getOfficeId() { public Long getOfficeId() {
return this.officeId; return this.officeId;
} }
@@ -115,4 +86,20 @@ public class UserCommand {
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
public List<String> getNotSelectedItems() {
return notSelectedItems;
}
public void setNotSelectedItems(List<String> notSelectedItems) {
this.notSelectedItems = notSelectedItems;
}
public List<String> getSelectedItems() {
return selectedItems;
}
public void setSelectedItems(List<String> selectedItems) {
this.selectedItems = selectedItems;
}
} }
@@ -33,25 +33,12 @@ public interface CommonRestOperations {
void logout(String accessToken); void logout(String accessToken);
void updateProtectedResource( void updateProtectedResource(ProtectedResourceDetails loadProtectedResourceDetailsById);
ProtectedResourceDetails loadProtectedResourceDetailsById);
Collection<AppUserData> retrieveAllUsers();
AppUserData retrieveNewUserDetails();
AppUserData retrieveUser(Long userId);
AppUserData retrieveCurrentUser(); AppUserData retrieveCurrentUser();
EntityIdentifier createUser(UserCommand command);
EntityIdentifier updateUser(UserCommand command);
EntityIdentifier updateCurrentUserPassword(ChangePasswordCommand command); EntityIdentifier updateCurrentUserPassword(ChangePasswordCommand command);
void deleteUser(Long userId);
Collection<RoleData> retrieveAllRoles(); Collection<RoleData> retrieveAllRoles();
RoleData retrieveRole(Long roleId); RoleData retrieveRole(Long roleId);
@@ -27,7 +27,6 @@ import org.mifosng.data.PermissionData;
import org.mifosng.data.PermissionList; import org.mifosng.data.PermissionList;
import org.mifosng.data.RoleData; import org.mifosng.data.RoleData;
import org.mifosng.data.RoleList; import org.mifosng.data.RoleList;
import org.mifosng.data.UserList;
import org.mifosng.data.command.AdjustLoanTransactionCommand; import org.mifosng.data.command.AdjustLoanTransactionCommand;
import org.mifosng.data.command.CalculateLoanScheduleCommand; import org.mifosng.data.command.CalculateLoanScheduleCommand;
import org.mifosng.data.command.ChangePasswordCommand; import org.mifosng.data.command.ChangePasswordCommand;
@@ -531,41 +530,6 @@ public class CommonRestOperationsImpl implements CommonRestOperations {
requestHeaders); requestHeaders);
} }
@Override
public EntityIdentifier createUser(final UserCommand command) {
try {
URI restUri = URI.create(getBaseServerUrl().concat(
"api/protected/admin/user/new"));
ResponseEntity<EntityIdentifier> s = this.oauthRestServiceTemplate
.postForEntity(restUri, createUserRequest(command),
EntityIdentifier.class);
return s.getBody();
} catch (HttpStatusCodeException e) {
ErrorResponseList errorList = parseErrors(e);
throw new ClientValidationException(errorList.getErrors());
}
}
@Override
public EntityIdentifier updateUser(UserCommand command) {
try {
URI restUri = URI.create(getBaseServerUrl().concat(
"api/protected/admin/user/").concat(
command.getId().toString()));
ResponseEntity<EntityIdentifier> s = this.oauthRestServiceTemplate
.postForEntity(restUri, createUserRequest(command),
EntityIdentifier.class);
return s.getBody();
} catch (HttpStatusCodeException e) {
ErrorResponseList errorList = parseErrors(e);
throw new ClientValidationException(errorList.getErrors());
}
}
@Override @Override
public EntityIdentifier updateCurrentUserDetails(UserCommand command) { public EntityIdentifier updateCurrentUserDetails(UserCommand command) {
try { try {
@@ -602,14 +566,6 @@ public class CommonRestOperationsImpl implements CommonRestOperations {
} }
} }
@Override
public void deleteUser(Long userId) {
URI restUri = URI.create(getBaseServerUrl().concat(
"api/protected/admin/user/").concat(userId.toString()));
this.oauthRestServiceTemplate.delete(restUri);
}
private HttpEntity<UserCommand> createUserRequest(final UserCommand command) { private HttpEntity<UserCommand> createUserRequest(final UserCommand command) {
HttpHeaders requestHeaders = new HttpHeaders(); HttpHeaders requestHeaders = new HttpHeaders();
@@ -644,46 +600,6 @@ public class CommonRestOperationsImpl implements CommonRestOperations {
return requestEntity; return requestEntity;
} }
@Override
public Collection<AppUserData> retrieveAllUsers() {
try {
URI restUri = URI.create(getBaseServerUrl().concat(
"api/protected/admin/user/all"));
ResponseEntity<UserList> s = this.oauthRestServiceTemplate
.exchange(restUri, HttpMethod.GET, emptyRequest(),
UserList.class);
return s.getBody().getUsers();
} catch (HttpStatusCodeException e) {
ErrorResponseList errorList = parseErrors(e);
throw new ClientValidationException(errorList.getErrors());
}
}
@Override
public AppUserData retrieveNewUserDetails() {
URI restUri = URI.create(getBaseServerUrl().concat(
"api/protected/admin/user/new"));
ResponseEntity<AppUserData> s = this.oauthRestServiceTemplate.exchange(
restUri, HttpMethod.GET, emptyRequest(), AppUserData.class);
return s.getBody();
}
@Override
public AppUserData retrieveUser(Long userId) {
URI restUri = URI.create(getBaseServerUrl().concat(
"api/protected/admin/user/").concat(userId.toString()));
ResponseEntity<AppUserData> s = this.oauthRestServiceTemplate.exchange(
restUri, HttpMethod.GET, emptyRequest(), AppUserData.class);
return s.getBody();
}
@Override @Override
public AppUserData retrieveCurrentUser() { public AppUserData retrieveCurrentUser() {
URI restUri = URI.create(getBaseServerUrl().concat( URI restUri = URI.create(getBaseServerUrl().concat(
@@ -78,7 +78,11 @@ public class AdministrationController {
@RequestParam(value="lastname", required=false) String lastname, @RequestParam(value="lastname", required=false) String lastname,
@RequestParam(value="email", required=false) String email) { @RequestParam(value="email", required=false) String email) {
UserCommand command = new UserCommand(username, firstname, lastname, email); UserCommand command = new UserCommand();
command.setUsername(username);
command.setFirstname(firstname);
command.setLastname(lastname);
command.setEmail(email);
return this.commonRestOperations.updateCurrentUserDetails(command); return this.commonRestOperations.updateCurrentUserDetails(command);
} }
@@ -4,13 +4,11 @@ import java.util.Collection;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.mifosng.data.AppUserData;
import org.mifosng.data.EntityIdentifier; import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.ErrorResponse; import org.mifosng.data.ErrorResponse;
import org.mifosng.data.PermissionData; import org.mifosng.data.PermissionData;
import org.mifosng.data.RoleData; import org.mifosng.data.RoleData;
import org.mifosng.data.command.RoleCommand; import org.mifosng.data.command.RoleCommand;
import org.mifosng.data.command.UserCommand;
import org.mifosng.ui.CommonRestOperations; import org.mifosng.ui.CommonRestOperations;
import org.mifosng.ui.loanproduct.ClientValidationException; import org.mifosng.ui.loanproduct.ClientValidationException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -83,63 +81,6 @@ public class AppUserController {
return this.commonRestOperations.updateRole(command); return this.commonRestOperations.updateRole(command);
} }
@RequestMapping(consumes="application/json", produces="application/json", value = "/admin/user/all", method = RequestMethod.GET)
public @ResponseBody Collection<AppUserData> viewAllUsers() {
return this.commonRestOperations.retrieveAllUsers();
}
@RequestMapping(consumes="application/json", produces="application/json", value = "/admin/user/new", method = RequestMethod.GET)
public @ResponseBody AppUserData viewUser() {
return this.commonRestOperations.retrieveNewUserDetails();
}
@RequestMapping(consumes="application/x-www-form-urlencoded", produces="application/json", value = "/admin/user/new", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
public @ResponseBody EntityIdentifier createNewUser(@RequestParam(value="selectedItems", required=false) String[] selectedRoles,
@RequestParam(value="username") String username,
@RequestParam(value="firstname") String firstname,
@RequestParam(value="lastname") String lastname,
@RequestParam(value="email") String email,
@RequestParam(value="officeId") Long officeId) {
UserCommand command = new UserCommand(username, firstname, lastname, "", email, selectedRoles, officeId);
return this.commonRestOperations.createUser(command);
}
@RequestMapping(consumes = "application/json", produces = "application/json", value = "/admin/user/{userId}", method = RequestMethod.DELETE)
public @ResponseBody
EntityIdentifier attemptToDeleteUser(@PathVariable("userId") Long userId) {
this.commonRestOperations.deleteUser(userId);
return new EntityIdentifier(Long.valueOf(1));
}
@RequestMapping(consumes="application/json", produces="application/json", value = "/admin/user/{userId}", method = RequestMethod.GET)
public @ResponseBody AppUserData viewUser(@PathVariable("userId") Long userId) {
return this.commonRestOperations.retrieveUser(userId);
}
@RequestMapping(consumes="application/x-www-form-urlencoded", produces="application/json", value = "/admin/user/{userId}", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
public @ResponseBody EntityIdentifier updateUser(@PathVariable("userId") Long userId,
@RequestParam(value="selectedItems", required=false) String[] selectedRoles,
@RequestParam(value="username") String username,
@RequestParam(value="firstname") String firstname,
@RequestParam(value="lastname") String lastname,
@RequestParam(value="email") String email,
@RequestParam(value="officeId") Long officeId) {
UserCommand command = new UserCommand(username, firstname, lastname, "", email, selectedRoles, officeId);
command.setId(userId);
return this.commonRestOperations.updateUser(command);
}
@ExceptionHandler(ClientValidationException.class) @ExceptionHandler(ClientValidationException.class)
public @ResponseBody Collection<ErrorResponse> validationException(ClientValidationException ex, HttpServletResponse response) { public @ResponseBody Collection<ErrorResponse> validationException(ClientValidationException ex, HttpServletResponse response) {
@@ -220,13 +220,10 @@
$('#selectedItems option').each(function(i) { $('#selectedItems option').each(function(i) {
$(this).attr("selected", "selected"); $(this).attr("selected", "selected");
}); });
var newFormData = JSON.stringify($('#entityform').serializeObject()); var newFormData = JSON.stringify($('#entityform').serializeObject());
console.log(newFormData); console.log(newFormData);
var form_data = $('#entityform').serialize();
var jqxhr = $.ajax({ var jqxhr = $.ajax({
url: postUrl, url: postUrl,
type: submitType, type: submitType,
@@ -55,9 +55,9 @@ $(document).ready(function() {
return false; return false;
} }
}, },
globalDate: function(dateParts) { globalDate: function(localDateAsISOString) {
try { try {
var dateParts = localDateAsISOString.split("-")
var year = dateParts[0]; var year = dateParts[0];
var month = parseInt(dateParts[1]) - 1; // month is zero indexed var month = parseInt(dateParts[1]) - 1; // month is zero indexed
var day = dateParts[2]; var day = dateParts[2];
@@ -70,9 +70,9 @@ $(document).ready(function() {
return "??"; return "??";
} }
}, },
globalDateTime: function(dateParts) { globalDateTime: function(dateInMillis) {
try { try {
var d = new Date(dateParts); var d = new Date(dateInMillis);
return Globalize.format(d,"F"); return Globalize.format(d,"F");
} catch(e) { } catch(e) {
@@ -114,17 +114,28 @@ $(document).ready(function() {
removeErrors(placeholderDiv); removeErrors(placeholderDiv);
var jsonErrors = JSON.parse(jqXHR.responseText); var jsonErrors = JSON.parse(jqXHR.responseText);
console.log(jsonErrors);
var valErrors = jsonErrors.errors;
console.log(valErrors);
var errorArray = new Array(); var errorArray = new Array();
var arrayIndex = 0; var arrayIndex = 0;
$.each(jsonErrors, function() { $.each(valErrors, function() {
var fieldId = '#' + this.field; var fieldId = '#' + this.parameterName;
$(fieldId).addClass("ui-state-error"); $(fieldId).addClass("ui-state-error");
var errorObj = new Object(); var errorObj = new Object();
errorObj.field = this.field; errorObj.field = this.parameterName;
errorObj.code = this.code; errorObj.code = this.userMessageGlobalisationCode;
errorObj.message = jQuery.i18n.prop(this.code, this.args);
var argArray = new Array();
var argArrayIndex = 0;
$.each(this.args, function() {
argArray[argArrayIndex] = this.value;
argArrayIndex++;
});
console.log(argArray);
// hardcoded support for six arguments
errorObj.message = jQuery.i18n.prop(this.userMessageGlobalisationCode, argArray[0], argArray[1], argArray[2], argArray[3], argArray[4], argArray[5]);
errorObj.value = this.value; errorObj.value = this.value;
errorArray[arrayIndex] = errorObj; errorArray[arrayIndex] = errorObj;
@@ -144,17 +155,33 @@ $(document).ready(function() {
} }
} }
function popupDialogWithFormView(url, titleCode, templateSelector, width, height, saveSuccessFunction) { $.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
function popupDialogWithFormView(getUrl, postUrl, submitType, titleCode, templateSelector, width, height, saveSuccessFunction) {
var dialogDiv = $("<div id='dialog-form'></div>"); var dialogDiv = $("<div id='dialog-form'></div>");
var jqxhr = $.ajax({ var jqxhr = $.ajax({
url: url, url: getUrl,
type: 'GET', type: 'GET',
contentType: 'application/json', contentType: 'application/json',
dataType: 'json', dataType: 'json',
cache: false, cache: false,
success: function(data, textStatus, jqXHR) { success: function(data, textStatus, jqXHR) {
console.log(data);
var formHtml = $(templateSelector).render(data); var formHtml = $(templateSelector).render(data);
dialogDiv.append(formHtml); dialogDiv.append(formHtml);
@@ -173,17 +200,20 @@ $(document).ready(function() {
$(this).attr("selected", "selected"); $(this).attr("selected", "selected");
}); });
var form_data = $('#entityform').serialize();
var newFormData = JSON.stringify($('#entityform').serializeObject());
console.log(newFormData);
var jqxhr = $.ajax({ var jqxhr = $.ajax({
url: url, url: postUrl,
type: 'POST', type: submitType,
data: form_data, contentType: 'application/json',
success: saveSuccessFunction dataType: 'json',
}); data: newFormData,
success: saveSuccessFunction,
jqxhr.error(function(jqXHR, textStatus, errorThrown) { error: function(jqXHR, textStatus, errorThrown) {
handleXhrError(jqXHR, textStatus, errorThrown, "#formErrorsTemplate", "#formerrors"); handleXhrError(jqXHR, textStatus, errorThrown, "#formErrorsTemplate", "#formerrors");
}
}); });
}; };
@@ -197,7 +227,7 @@ $(document).ready(function() {
buttons: buttonsOpts, buttons: buttonsOpts,
close: function() { close: function() {
// if i dont do this, theres a problem with errors being appended to dialog view second time round // if i dont do this, theres a problem with errors being appended to dialog view second time round
$(this).dialog("destroy").remove(); $(this).remove();
}, },
open: function (event, ui) { open: function (event, ui) {
@@ -232,11 +262,8 @@ $(document).ready(function() {
dataType: 'json', dataType: 'json',
cache: false, cache: false,
success: function(data, textStatus, jqXHR) { success: function(data, textStatus, jqXHR) {
console.log(data);
var tableObj = new Object(); var tableHtml = $(templateSelector).render(data);
tableObj.items = data;
var tableHtml = $(templateSelector).render(tableObj);
$(displayAreaDivSelector).html(""); $(displayAreaDivSelector).html("");
$(displayAreaDivSelector).html(tableHtml); $(displayAreaDivSelector).html(tableHtml);
@@ -248,7 +275,7 @@ $(document).ready(function() {
var width = 1000; var width = 1000;
var height = 550; var height = 550;
popupDialogWithFormView(url, 'dialog.title.edit.details', singleEntityTemplateSelector, width, height, saveSuccessFunction); popupDialogWithFormView(url, url, 'PUT', 'dialog.title.edit.details', singleEntityTemplateSelector, width, height, saveSuccessFunction);
e.preventDefault(); e.preventDefault();
}); });
@@ -295,46 +322,24 @@ $(document).ready(function() {
} }
$('#listusers').click(function(e) { $('#listusers').click(function(e) {
var listUrl = "${allUsersUrl}"; var listUrl = "http://localhost:8085/mifosng-provider/api/v1/users";
var templateSelector = "#usersListTemplate"; refreshUsersView();
var displayAreaDivSelector = "#contentplaceholder";
var singleEntityPrefixUrl = '${rootContext}admin/user/';
var singleEntityTemplateSelector = "#userFormTemplate";
var saveSuccessFunction = function(data, textStatus, jqXHR) {
$("#dialog-form").dialog("destroy").remove();
var listUrl = "${allUsersUrl}";
var templateSelector = "#usersListTemplate";
var displayAreaDivSelector = "#contentplaceholder";
var singleEntityPrefixUrl = '${rootContext}admin/user/';
var singleEntityTemplateSelector = "#userFormTemplate";
displayListView(listUrl, templateSelector, displayAreaDivSelector, singleEntityPrefixUrl, singleEntityTemplateSelector);
}
displayListView(listUrl, templateSelector, displayAreaDivSelector, singleEntityPrefixUrl, singleEntityTemplateSelector, saveSuccessFunction);
e.preventDefault(); e.preventDefault();
}); });
$('#adduser').click(function(e) { $('#adduser').click(function(e) {
var url = '${rootContext}admin/user/new'; var url = 'http://localhost:8085/mifosng-provider/api/v1/users/template';
var postUrl = "http://localhost:8085/mifosng-provider/api/v1/users";
var templateSelector = "#userFormTemplate"; var templateSelector = "#userFormTemplate";
var width = 1000; var width = 1000;
var height = 550; var height = 550;
var saveSuccessFunction = function(data, textStatus, jqXHR) { var saveSuccessFunction = function(data, textStatus, jqXHR) {
$("#dialog-form").dialog("close"); $("#dialog-form").dialog("close");
var listUrl = "${allUsersUrl}"; refreshUsersView();
var templateSelector = "#usersListTemplate";
var displayAreaDivSelector = "#contentplaceholder";
var singleEntityPrefixUrl = '${rootContext}admin/user/';
var singleEntityTemplateSelector = "#userFormTemplate";
displayListView(listUrl, templateSelector, displayAreaDivSelector, singleEntityPrefixUrl, singleEntityTemplateSelector);
} }
popupDialogWithFormView(url, 'dialog.title.add.user', templateSelector, width, height, saveSuccessFunction); popupDialogWithFormView(url, postUrl, 'POST', 'dialog.title.add.user', templateSelector, width, height, saveSuccessFunction);
e.preventDefault(); e.preventDefault();
}); });
@@ -397,6 +402,71 @@ $(document).ready(function() {
e.preventDefault(); e.preventDefault();
}); });
function refreshUsersView() {
var listUrl = 'http://localhost:8085/mifosng-provider/api/v1/users';
var templateSelector = "#usersListTemplate";
var displayAreaDivSelector = "#contentplaceholder";
var singleEntityPrefixUrl = 'http://localhost:8085/mifosng-provider/api/v1/users/';
var singleEntityTemplateSelector = "#userFormTemplate";
var jqxhr = $.ajax({
url: listUrl,
type: 'GET',
contentType: 'application/json',
dataType: 'json',
success: function(data, textStatus, jqXHR) {
console.log(data);
var officeListHtml = $(templateSelector).render(data);
$(displayAreaDivSelector).html(officeListHtml);
$("a.edit").click( function(e) {
var linkId = this.id;
var entityId = linkId.replace("edit", "");
var getUrl = 'http://localhost:8085/mifosng-provider/api/v1/users/' + entityId;
var putUrl = 'http://localhost:8085/mifosng-provider/api/v1/users/' + entityId;
var templateSelector = "#userFormTemplate";
var width = 600;
var height = 400;
var saveSuccessFunction = function(data, textStatus, jqXHR) {
$("#dialog-form").dialog("close");
refreshUsersView();
}
popupDialogWithFormView(getUrl, putUrl, 'PUT', "dialog.title.edit.details", templateSelector, width, height, saveSuccessFunction);
e.preventDefault();
});
$("a.delete").click( function(e) {
var linkId = this.id;
var entityId = linkId.replace("delete", "");
var url = 'http://localhost:8085/mifosng-provider/api/v1/users/' + entityId;
showNotAvailableDialog('dialog.title.functionality.not.available');
e.preventDefault();
});
var oTable = $("#entitytable").dataTable( {
"bSort": true,
"bInfo": true,
"bJQueryUI": true,
"bRetrieve": false,
"bScrollCollapse": false,
"bPaginate": false,
"bLengthChange": false,
"bFilter": false,
"bAutoWidth": false,
} );
}
});
jqxhr.error(function(jqXHR, textStatus, errorThrown) {
handleXhrError(jqXHR, textStatus, errorThrown, "#formErrorsTemplate", "#formerrors");
});
}
// end of document.ready // end of document.ready
}); });
</script> </script>
@@ -440,7 +440,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{{#each items}} {{#each users}}
<tr> <tr>
<td>{{=officeName}}</td> <td>{{=officeName}}</td>
<td>{{=username}}</td> <td>{{=username}}</td>
@@ -760,11 +760,13 @@ public class ReadPlatformServiceImpl implements ReadPlatformService {
List<OfficeData> offices = retrieveOffices(); List<OfficeData> offices = retrieveOffices();
List<RoleData> availableRoles = new ArrayList<RoleData>( List<RoleData> availableRoles = new ArrayList<RoleData>(retrieveAllRoles());
retrieveAllRoles());
AppUser user = this.appUserRepository.findOne(usersThatMatch( AppUser user = this.appUserRepository.findOne(usersThatMatch(currentUser.getOrganisation(), userId));
currentUser.getOrganisation(), userId));
if (user == null) {
throw new PlatformResourceNotFoundException("error.msg.user.id.invalid", "User with identifier {0} does not exist.", userId);
}
List<RoleData> userRoleData = new ArrayList<RoleData>(); List<RoleData> userRoleData = new ArrayList<RoleData>();
Set<Role> userRoles = user.getRoles(); Set<Role> userRoles = user.getRoles();
@@ -8,11 +8,11 @@ import org.mifosng.data.ErrorResponse;
import org.mifosng.data.command.UserCommand; import org.mifosng.data.command.UserCommand;
import org.mifosng.platform.exceptions.NewDataValidationException; import org.mifosng.platform.exceptions.NewDataValidationException;
public class UserValidator { public class UserCommandValidator {
private final UserCommand command; private final UserCommand command;
public UserValidator(UserCommand command) { public UserCommandValidator(UserCommand command) {
this.command = command; this.command = command;
} }
@@ -27,7 +27,7 @@ public class UserValidator {
dataValidationErrors.add(error); dataValidationErrors.add(error);
} }
if (command.getRoleIds() == null) { if (command.getSelectedItems() == null) {
ErrorResponse error = new ErrorResponse("validation.msg.user.roles.cannot.be.blank", "selectedItems"); ErrorResponse error = new ErrorResponse("validation.msg.user.roles.cannot.be.blank", "selectedItems");
dataValidationErrors.add(error); dataValidationErrors.add(error);
} }
@@ -15,6 +15,7 @@ import java.util.Set;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosng.data.ApiParameterError;
import org.mifosng.data.EntityIdentifier; import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.ErrorResponse; import org.mifosng.data.ErrorResponse;
import org.mifosng.data.LoanSchedule; import org.mifosng.data.LoanSchedule;
@@ -42,8 +43,10 @@ import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.exceptions.ApplicationDomainRuleException; import org.mifosng.platform.exceptions.ApplicationDomainRuleException;
import org.mifosng.platform.exceptions.InvalidSignupException; import org.mifosng.platform.exceptions.InvalidSignupException;
import org.mifosng.platform.exceptions.NewDataValidationException;
import org.mifosng.platform.exceptions.NoAuthorizationException; import org.mifosng.platform.exceptions.NoAuthorizationException;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.exceptions.PlatformResourceNotFoundException;
import org.mifosng.platform.exceptions.UnAuthenticatedUserException; import org.mifosng.platform.exceptions.UnAuthenticatedUserException;
import org.mifosng.platform.infrastructure.BasicPasswordEncodablePlatformUser; import org.mifosng.platform.infrastructure.BasicPasswordEncodablePlatformUser;
import org.mifosng.platform.infrastructure.PlatformPasswordEncoder; import org.mifosng.platform.infrastructure.PlatformPasswordEncoder;
@@ -147,11 +150,11 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
try { try {
AppUser currentUser = extractAuthenticatedUser(); AppUser currentUser = extractAuthenticatedUser();
UserValidator validator = new UserValidator(command); UserCommandValidator validator = new UserCommandValidator(command);
validator.validate(); validator.validate();
Set<Role> allRoles = new HashSet<Role>(); Set<Role> allRoles = new HashSet<Role>();
for (String roleId : command.getRoleIds()) { for (String roleId : command.getSelectedItems()) {
Role role = this.roleRepository.findOne(Long.valueOf(roleId)); Role role = this.roleRepository.findOne(Long.valueOf(roleId));
allRoles.add(role); allRoles.add(role);
} }
@@ -173,36 +176,42 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
@Transactional @Transactional
@Override @Override
public Long updateUser(UserCommand command) { public Long updateUser(UserCommand command) {
try { try {
AppUser currentUser = extractAuthenticatedUser(); AppUser currentUser = extractAuthenticatedUser();
UserValidator validator = new UserValidator(command); UserCommandValidator validator = new UserCommandValidator(command);
validator.validate(); validator.validate();
List<ErrorResponse> dataValidationErrors = new ArrayList<ErrorResponse>(); List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
if (command.getId() == null) { if (command.getId() == null) {
ErrorResponse error = new ErrorResponse("validation.msg.user.id.cannot.be.blank", "id"); ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.id.cannot.be.blank", "The parameter id cannot be empty.", "id");
dataValidationErrors.add(error); dataValidationErrors.add(error);
}
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
if (!dataValidationErrors.isEmpty()) {
throw new NewDataValidationException(dataValidationErrors, "Data validation error exist.");
} }
Set<Role> allRoles = new HashSet<Role>(); Set<Role> allRoles = new HashSet<Role>();
for (String roleId : command.getRoleIds()) { for (String roleId : command.getSelectedItems()) {
Role role = this.roleRepository.findOne(Long.valueOf(roleId)); Role role = this.roleRepository.findOne(Long.valueOf(roleId));
allRoles.add(role); allRoles.add(role);
} }
Office office = this.officeRepository.findOne(command.getOfficeId()); Office office = this.officeRepository.findOne(command.getOfficeId());
if (office == null) {
throw new PlatformResourceNotFoundException("error.msg.office.id.invalid", "Office with identifier {0} does not exist.", command.getOfficeId());
}
AppUser userToUpdate = this.appUserRepository.findOne(usersThatMatch(currentUser.getOrganisation(), command.getId())); AppUser userToUpdate = this.appUserRepository.findOne(usersThatMatch(currentUser.getOrganisation(), command.getId()));
if (userToUpdate == null) {
throw new PlatformResourceNotFoundException("error.msg.user.id.invalid", "User with identifier {0} does not exist.", command.getId());
}
userToUpdate.update(allRoles, office, command.getUsername(), command.getFirstname(), command.getLastname(), command.getEmail()); userToUpdate.update(allRoles, office, command.getUsername(), command.getFirstname(), command.getLastname(), command.getEmail());
return userToUpdate.getId(); return userToUpdate.getId();
} catch (DataIntegrityViolationException e) { } catch (DataIntegrityViolationException e) {
throw new UsernameAlreadyExistsException(e); throw new PlatformDataIntegrityException("validation.msg.username.already.exists.in.organisation", "Username already exists.", "username", command.getUsername());
} }
} }
@@ -211,7 +220,7 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
public Long updateCurrentUser(UserCommand command) { public Long updateCurrentUser(UserCommand command) {
AppUser currentUser = extractAuthenticatedUser(); AppUser currentUser = extractAuthenticatedUser();
UserValidator validator = new UserValidator(command); UserCommandValidator validator = new UserCommandValidator(command);
validator.validateAccountSettingDetails(); validator.validateAccountSettingDetails();
AppUser userToUpdate = this.appUserRepository.findOne(currentUser.getId()); AppUser userToUpdate = this.appUserRepository.findOne(currentUser.getId());
@@ -0,0 +1,257 @@
package org.mifosng.platform.api.user;
import java.util.Arrays;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
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.ErrorResponse;
import org.mifosng.data.ErrorResponseList;
import org.mifosng.data.UserList;
import org.mifosng.data.command.ChangePasswordCommand;
import org.mifosng.data.command.UserCommand;
import org.mifosng.platform.ReadPlatformService;
import org.mifosng.platform.WritePlatformService;
import org.mifosng.platform.exceptions.ApplicationDomainRuleException;
import org.mifosng.platform.exceptions.NewDataValidationException;
import org.mifosng.platform.exceptions.UnAuthenticatedUserException;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.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/users")
@Component
@Scope("singleton")
public class UserApiResource {
private final static Logger logger = LoggerFactory.getLogger(UserApiResource.class);
@Autowired
private ReadPlatformService readPlatformService;
@Autowired
private WritePlatformService writePlatformService;
@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
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveUsers() {
hardcodeUserIntoSecurityContext();
Collection<AppUserData> users = this.readPlatformService.retrieveAllUsers();
return Response.ok().entity(new UserList(users)).build();
}
@GET
@Path("{userId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveUser(@PathParam("userId") final Long userId) {
hardcodeUserIntoSecurityContext();
AppUserData user = this.readPlatformService.retrieveUser(userId);
return Response.ok().entity(user).build();
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response newUserDetails() {
hardcodeUserIntoSecurityContext();
AppUserData newUser = this.readPlatformService.retrieveNewUserDetails();
return Response.ok().entity(newUser).build();
}
@POST
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response createUser(@Context HttpServletRequest request) {
// try {
String selectedItems = request.getParameter("selectedItems");
final UserCommand command = new UserCommand();
// command.setSelectedItems(Arrays.asList(a));
hardcodeUserIntoSecurityContext();
Long userId = this.writePlatformService.createUser(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
// } catch (UsernameAlreadyExistsException e) {
// List<ErrorResponse> allErrors = new ArrayList<ErrorResponse>();
// ErrorResponse err = new ErrorResponse("validation.msg.username.already.exists.in.organisation", "username", command.getUsername());
// allErrors.add(err);
//
// throw new WebApplicationException(Response
// .status(Status.BAD_REQUEST)
// .entity(new ErrorResponseList(allErrors)).build());
// } catch (PlatformEmailSendException e) {
// List<ErrorResponse> allErrors = new ArrayList<ErrorResponse>();
// ErrorResponse err = new ErrorResponse("error.msg.user.email.invalid","email", "Email is invalid.");
// allErrors.add(err);
// throw new WebApplicationException(Response
// .status(Status.BAD_REQUEST)
// .entity(new ErrorResponseList(allErrors)).build());
// }
}
@DELETE
@Path("{userId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response deleteUser(@PathParam("userId") final Long userId) {
try {
this.writePlatformService.deleteUser(userId);
return Response.ok().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());
}
}
@PUT
@Path("{userId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response updateUser(@PathParam("userId") final Long userId, UserCommand command) {
hardcodeUserIntoSecurityContext();
// UserCommand command = new UserCommand();
// command.setSelectedItems(new ArrayList<String>(commandEile.getSelectedItems()));
command.setId(userId);
this.writePlatformService.updateUser(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
}
@GET
@Path("user/current")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveCurrentUser() {
try {
hardcodeUserIntoSecurityContext();
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 {
hardcodeUserIntoSecurityContext();
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 {
hardcodeUserIntoSecurityContext();
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());
}
}
}