MIFOSX-648: allow user to fetch their own account data no matter what permissions they hold.

This commit is contained in:
Keith Woodlock
2013-09-09 09:54:42 +01:00
parent bdb2162ab7
commit 0de4adf6e5
3 changed files with 472 additions and 512 deletions
@@ -73,7 +73,7 @@ public class SavingsProduct extends AbstractPersistable<Long> {
/** /**
* The interest period is the span of time at the end of which savings in a * The interest period is the span of time at the end of which savings in a
* client's account earn interest. * client's account earn interest.
* *
* A value from the {@link SavingsCompoundingInterestPeriodType} * A value from the {@link SavingsCompoundingInterestPeriodType}
* enumeration. * enumeration.
*/ */
@@ -119,9 +119,8 @@ public class SavingsProduct extends AbstractPersistable<Long> {
@Column(name = "withdrawal_fee_type_enum", nullable = true) @Column(name = "withdrawal_fee_type_enum", nullable = true)
private Integer withdrawalFeeType; private Integer withdrawalFeeType;
@Column(name = "withdrawal_fee_for_transfer") @Column(name = "withdrawal_fee_for_transfer")
@SuppressWarnings("unused")
private boolean withdrawalFeeApplicableForTransfer; private boolean withdrawalFeeApplicableForTransfer;
@Column(name = "annual_fee_amount", scale = 6, precision = 19, nullable = true) @Column(name = "annual_fee_amount", scale = 6, precision = 19, nullable = true)
@@ -138,12 +137,12 @@ public class SavingsProduct extends AbstractPersistable<Long> {
final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType, final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance, final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType, final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType, boolean withdrawalFeeApplicableForTransfer, final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType, final boolean withdrawalFeeApplicableForTransfer,
final BigDecimal annualFeeAmount, final MonthDay annualFeeOnMonthDay, final AccountingRuleType accountingRuleType) { final BigDecimal annualFeeAmount, final MonthDay annualFeeOnMonthDay, final AccountingRuleType accountingRuleType) {
return new SavingsProduct(name, description, currency, interestRate, interestCompoundingPeriodType, interestPostingPeriodType, return new SavingsProduct(name, description, currency, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType,withdrawalFeeApplicableForTransfer, annualFeeAmount, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType,withdrawalFeeApplicableForTransfer, annualFeeAmount,
annualFeeOnMonthDay, accountingRuleType); annualFeeOnMonthDay, accountingRuleType);
} }
@@ -376,7 +375,7 @@ public class SavingsProduct extends AbstractPersistable<Long> {
actualChanges.put(withdrawalFeeTypeParamName, newValue); actualChanges.put(withdrawalFeeTypeParamName, newValue);
this.withdrawalFeeType = newValue != null ? SavingsWithdrawalFeesType.fromInt(newValue).getValue() : newValue; this.withdrawalFeeType = newValue != null ? SavingsWithdrawalFeesType.fromInt(newValue).getValue() : newValue;
} }
if(command.isChangeInBooleanParameterNamed(withdrawalFeeForTransfersParamName, this.withdrawalFeeApplicableForTransfer)){ if(command.isChangeInBooleanParameterNamed(withdrawalFeeForTransfersParamName, this.withdrawalFeeApplicableForTransfer)){
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(withdrawalFeeForTransfersParamName); final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(withdrawalFeeForTransfersParamName);
actualChanges.put(withdrawalFeeForTransfersParamName, newValue); actualChanges.put(withdrawalFeeForTransfersParamName, newValue);
@@ -484,16 +483,16 @@ public class SavingsProduct extends AbstractPersistable<Long> {
.resource(SAVINGS_PRODUCT_RESOURCE_NAME); .resource(SAVINGS_PRODUCT_RESOURCE_NAME);
if (this.lockinPeriodFrequency == null) { if (this.lockinPeriodFrequency == null) {
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).ignoreIfNull() baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(this.lockinPeriodFrequencyType).ignoreIfNull()
.inMinMaxRange(0, 3); .inMinMaxRange(0, 3);
if (this.lockinPeriodFrequencyType != null) { if (this.lockinPeriodFrequencyType != null) {
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull() baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(this.lockinPeriodFrequency).notNull()
.integerZeroOrGreater(); .integerZeroOrGreater();
} }
} else { } else {
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequencyType).integerZeroOrGreater(); baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(this.lockinPeriodFrequencyType).integerZeroOrGreater();
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull() baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(this.lockinPeriodFrequencyType).notNull()
.inMinMaxRange(0, 3); .inMinMaxRange(0, 3);
} }
@@ -75,25 +75,25 @@ public class UsersApiResource {
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveUsers(@Context final UriInfo uriInfo) { public String retrieveAll(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
final Collection<AppUserData> users = this.readPlatformService.retrieveAllUsers(); final Collection<AppUserData> users = this.readPlatformService.retrieveAllUsers();
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, users, RESPONSE_DATA_PARAMETERS); return this.toApiJsonSerializer.serialize(settings, users, this.RESPONSE_DATA_PARAMETERS);
} }
@GET @GET
@Path("{userId}") @Path("{userId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveUser(@PathParam("userId") final Long userId, @Context final UriInfo uriInfo) { public String retrieveOne(@PathParam("userId") final Long userId, @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions, userId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
AppUserData user = this.readPlatformService.retrieveUser(userId); AppUserData user = this.readPlatformService.retrieveUser(userId);
if (settings.isTemplate()) { if (settings.isTemplate()) {
@@ -101,27 +101,27 @@ public class UsersApiResource {
user = AppUserData.template(user, offices); user = AppUserData.template(user, offices);
} }
return this.toApiJsonSerializer.serialize(settings, user, RESPONSE_DATA_PARAMETERS); return this.toApiJsonSerializer.serialize(settings, user, this.RESPONSE_DATA_PARAMETERS);
} }
@GET @GET
@Path("template") @Path("template")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String newUserDetails(@Context final UriInfo uriInfo) { public String template(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
final AppUserData user = this.readPlatformService.retrieveNewUserDetails(); final AppUserData user = this.readPlatformService.retrieveNewUserDetails();
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, user, RESPONSE_DATA_PARAMETERS); return this.toApiJsonSerializer.serialize(settings, user, this.RESPONSE_DATA_PARAMETERS);
} }
@POST @POST
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createUser(final String apiRequestBodyAsJson) { public String create(final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder() // final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.createUser() // .createUser() //
@@ -137,7 +137,7 @@ public class UsersApiResource {
@Path("{userId}") @Path("{userId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateUser(@PathParam("userId") final Long userId, final String apiRequestBodyAsJson) { public String update(@PathParam("userId") final Long userId, final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder() // final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.updateUser(userId) // .updateUser(userId) //
@@ -153,7 +153,7 @@ public class UsersApiResource {
@Path("{userId}") @Path("{userId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String deleteUser(@PathParam("userId") final Long userId) { public String delete(@PathParam("userId") final Long userId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder() // final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.deleteUser(userId) // .deleteUser(userId) //
@@ -42,491 +42,452 @@ import org.springframework.security.core.userdetails.User;
@Table(name = "m_appuser", uniqueConstraints = @UniqueConstraint(columnNames = { "username" }, name = "username_org")) @Table(name = "m_appuser", uniqueConstraints = @UniqueConstraint(columnNames = { "username" }, name = "username_org"))
public class AppUser extends AbstractPersistable<Long> implements PlatformUser { public class AppUser extends AbstractPersistable<Long> implements PlatformUser {
private final static Logger logger = LoggerFactory.getLogger(AppUser.class); private final static Logger logger = LoggerFactory.getLogger(AppUser.class);
@Column(name = "email", nullable = false, length = 100) @Column(name = "email", nullable = false, length = 100)
private String email; private String email;
@Column(name = "username", nullable = false, length = 100) @Column(name = "username", nullable = false, length = 100)
private String username; private String username;
@Column(name = "firstname", nullable = false, length = 100) @Column(name = "firstname", nullable = false, length = 100)
private String firstname; private String firstname;
@Column(name = "lastname", nullable = false, length = 100) @Column(name = "lastname", nullable = false, length = 100)
private String lastname; private String lastname;
@Column(name = "password", nullable = false) @Column(name = "password", nullable = false)
private String password; private String password;
@Column(name = "nonexpired", nullable = false) @Column(name = "nonexpired", nullable = false)
private boolean accountNonExpired; private boolean accountNonExpired;
@Column(name = "nonlocked", nullable = false) @Column(name = "nonlocked", nullable = false)
private final boolean accountNonLocked; private final boolean accountNonLocked;
@Column(name = "nonexpired_credentials", nullable = false) @Column(name = "nonexpired_credentials", nullable = false)
private final boolean credentialsNonExpired; private final boolean credentialsNonExpired;
@Column(name = "enabled", nullable = false) @Column(name = "enabled", nullable = false)
private boolean enabled; private boolean enabled;
@Column(name = "firsttime_login_remaining", nullable = false) @Column(name = "firsttime_login_remaining", nullable = false)
private boolean firstTimeLoginRemaining; private boolean firstTimeLoginRemaining;
@Column(name = "is_deleted", nullable = false) @Column(name = "is_deleted", nullable = false)
private boolean deleted; private boolean deleted;
@ManyToOne @ManyToOne
@JoinColumn(name = "office_id", nullable = false) @JoinColumn(name = "office_id", nullable = false)
private Office office; private Office office;
@ManyToOne @ManyToOne
@JoinColumn(name = "staff_id", nullable = true) @JoinColumn(name = "staff_id", nullable = true)
private Staff staff; private Staff staff;
@ManyToMany(fetch = FetchType.EAGER) @ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "m_appuser_role", joinColumns = @JoinColumn(name = "appuser_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) @JoinTable(name = "m_appuser_role", joinColumns = @JoinColumn(name = "appuser_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles; private Set<Role> roles;
public static AppUser fromJson(final Office userOffice, public static AppUser fromJson(final Office userOffice, final Set<Role> allRoles, final JsonCommand command) {
final Set<Role> allRoles, final JsonCommand command) {
final String username = command.stringValueOfParameterNamed("username");
final String username = command.stringValueOfParameterNamed("username"); String password = command.stringValueOfParameterNamed("password");
String password = command.stringValueOfParameterNamed("password"); final Boolean sendPasswordToEmail = command.booleanObjectValueOfParameterNamed("sendPasswordToEmail");
final Boolean sendPasswordToEmail = command
.booleanObjectValueOfParameterNamed("sendPasswordToEmail"); if (sendPasswordToEmail.booleanValue()) {
password = new RandomPasswordGenerator(13).generate();
if (sendPasswordToEmail.booleanValue()) { }
password = new RandomPasswordGenerator(13).generate();
} final boolean userEnabled = true;
final boolean userAccountNonExpired = true;
final boolean userEnabled = true; final boolean userCredentialsNonExpired = true;
final boolean userAccountNonExpired = true; final boolean userAccountNonLocked = true;
final boolean userCredentialsNonExpired = true;
final boolean userAccountNonLocked = true; final Collection<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION"));
final Collection<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
authorities.add(new SimpleGrantedAuthority( final User user = new User(username, password, userEnabled, userAccountNonExpired, userCredentialsNonExpired, userAccountNonLocked,
"DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION")); authorities);
final User user = new User(username, password, userEnabled, final String email = command.stringValueOfParameterNamed("email");
userAccountNonExpired, userCredentialsNonExpired, final String firstname = command.stringValueOfParameterNamed("firstname");
userAccountNonLocked, authorities); final String lastname = command.stringValueOfParameterNamed("lastname");
final String email = command.stringValueOfParameterNamed("email"); return new AppUser(userOffice, user, allRoles, email, firstname, lastname);
final String firstname = command }
.stringValueOfParameterNamed("firstname");
final String lastname = command.stringValueOfParameterNamed("lastname"); protected AppUser() {
this.accountNonLocked = false;
return new AppUser(userOffice, user, allRoles, email, firstname, this.credentialsNonExpired = false;
lastname); this.roles = new HashSet<Role>();
} }
protected AppUser() { public AppUser(final Office office, final User user, final Set<Role> roles, final String email, final String firstname,
this.accountNonLocked = false; final String lastname) {
this.credentialsNonExpired = false; this.office = office;
this.roles = new HashSet<Role>(); this.email = email.trim();
} this.username = user.getUsername().trim();
this.firstname = firstname.trim();
public AppUser(final Office office, final User user, final Set<Role> roles, this.lastname = lastname.trim();
final String email, final String firstname, final String lastname) { this.password = user.getPassword().trim();
this.office = office; this.accountNonExpired = user.isAccountNonExpired();
this.email = email.trim(); this.accountNonLocked = user.isAccountNonLocked();
this.username = user.getUsername().trim(); this.credentialsNonExpired = user.isCredentialsNonExpired();
this.firstname = firstname.trim(); this.enabled = user.isEnabled();
this.lastname = lastname.trim(); this.roles = roles;
this.password = user.getPassword().trim(); this.firstTimeLoginRemaining = true;
this.accountNonExpired = user.isAccountNonExpired(); }
this.accountNonLocked = user.isAccountNonLocked();
this.credentialsNonExpired = user.isCredentialsNonExpired(); public EnumOptionData organisationalRoleData() {
this.enabled = user.isEnabled(); EnumOptionData organisationalRole = null;
this.roles = roles; if (this.staff != null) {
this.firstTimeLoginRemaining = true; organisationalRole = this.staff.organisationalRoleData();
} }
return organisationalRole;
public EnumOptionData organisationalRoleData() { }
EnumOptionData organisationalRole = null;
if (this.staff != null) { public void updatePassword(final String encodePassword) {
organisationalRole = this.staff.organisationalRoleData(); this.password = encodePassword;
} this.firstTimeLoginRemaining = false;
return organisationalRole; }
}
public void changeOffice(final Office differentOffice) {
public void updatePassword(final String encodePassword) { this.office = differentOffice;
this.password = encodePassword; }
this.firstTimeLoginRemaining = false;
} public void updateRoles(final Set<Role> allRoles) {
if (!allRoles.isEmpty()) {
public void changeOffice(final Office differentOffice) { this.roles.clear();
this.office = differentOffice; this.roles = allRoles;
} }
}
public void updateRoles(final Set<Role> allRoles) {
if (!allRoles.isEmpty()) { public Map<String, Object> update(final JsonCommand command, final PlatformPasswordEncoder platformPasswordEncoder) {
this.roles.clear();
this.roles = allRoles; final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
}
} // unencoded password provided
final String passwordParamName = "password";
public Map<String, Object> update(final JsonCommand command, final String passwordEncodedParamName = "passwordEncoded";
final PlatformPasswordEncoder platformPasswordEncoder) { if (command.hasParameter(passwordParamName)) {
if (command.isChangeInPasswordParameterNamed(passwordParamName, this.password, platformPasswordEncoder, getId())) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>( final String passwordEncodedValue = command.passwordValueOfParameterNamed(passwordParamName, platformPasswordEncoder,
7); getId());
actualChanges.put(passwordEncodedParamName, passwordEncodedValue);
// unencoded password provided updatePassword(passwordEncodedValue);
final String passwordParamName = "password"; }
final String passwordEncodedParamName = "passwordEncoded"; }
if (command.hasParameter(passwordParamName)) {
if (command.isChangeInPasswordParameterNamed(passwordParamName, if (command.hasParameter(passwordEncodedParamName)) {
this.password, platformPasswordEncoder, getId())) { if (command.isChangeInStringParameterNamed(passwordEncodedParamName, this.password)) {
final String passwordEncodedValue = command final String newValue = command.stringValueOfParameterNamed(passwordEncodedParamName);
.passwordValueOfParameterNamed(passwordParamName, actualChanges.put(passwordEncodedParamName, newValue);
platformPasswordEncoder, getId()); updatePassword(newValue);
actualChanges.put(passwordEncodedParamName, }
passwordEncodedValue); }
updatePassword(passwordEncodedValue);
} final String officeIdParamName = "officeId";
} if (command.isChangeInLongParameterNamed(officeIdParamName, this.office.getId())) {
final Long newValue = command.longValueOfParameterNamed(officeIdParamName);
if (command.hasParameter(passwordEncodedParamName)) { actualChanges.put(officeIdParamName, newValue);
if (command.isChangeInStringParameterNamed( }
passwordEncodedParamName, this.password)) {
final String newValue = command final String rolesParamName = "roles";
.stringValueOfParameterNamed(passwordEncodedParamName); if (command.isChangeInArrayParameterNamed(rolesParamName, getRolesAsIdStringArray())) {
actualChanges.put(passwordEncodedParamName, newValue); final String[] newValue = command.arrayValueOfParameterNamed(rolesParamName);
updatePassword(newValue); actualChanges.put(rolesParamName, newValue);
} }
}
final String usernameParamName = "username";
final String officeIdParamName = "officeId"; if (command.isChangeInStringParameterNamed(usernameParamName, this.username)) {
if (command.isChangeInLongParameterNamed(officeIdParamName, final String newValue = command.stringValueOfParameterNamed(usernameParamName);
this.office.getId())) { actualChanges.put(usernameParamName, newValue);
final Long newValue = command this.username = newValue;
.longValueOfParameterNamed(officeIdParamName); }
actualChanges.put(officeIdParamName, newValue);
} final String firstnameParamName = "firstname";
if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstname)) {
final String rolesParamName = "roles"; final String newValue = command.stringValueOfParameterNamed(firstnameParamName);
if (command.isChangeInArrayParameterNamed(rolesParamName, actualChanges.put(firstnameParamName, newValue);
getRolesAsIdStringArray())) { this.firstname = newValue;
final String[] newValue = command }
.arrayValueOfParameterNamed(rolesParamName);
actualChanges.put(rolesParamName, newValue); final String lastnameParamName = "lastname";
} if (command.isChangeInStringParameterNamed(lastnameParamName, this.lastname)) {
final String newValue = command.stringValueOfParameterNamed(lastnameParamName);
final String usernameParamName = "username"; actualChanges.put(lastnameParamName, newValue);
if (command.isChangeInStringParameterNamed(usernameParamName, this.lastname = newValue;
this.username)) { }
final String newValue = command
.stringValueOfParameterNamed(usernameParamName); final String emailParamName = "email";
actualChanges.put(usernameParamName, newValue); if (command.isChangeInStringParameterNamed(emailParamName, this.email)) {
this.username = newValue; final String newValue = command.stringValueOfParameterNamed(emailParamName);
} actualChanges.put(emailParamName, newValue);
this.email = newValue;
final String firstnameParamName = "firstname"; }
if (command.isChangeInStringParameterNamed(firstnameParamName,
this.firstname)) { return actualChanges;
final String newValue = command }
.stringValueOfParameterNamed(firstnameParamName);
actualChanges.put(firstnameParamName, newValue); private String[] getRolesAsIdStringArray() {
this.firstname = newValue; final List<String> roleIds = new ArrayList<String>();
}
for (final Role role : this.roles) {
final String lastnameParamName = "lastname"; roleIds.add(role.getId().toString());
if (command.isChangeInStringParameterNamed(lastnameParamName, }
this.lastname)) {
final String newValue = command return roleIds.toArray(new String[roleIds.size()]);
.stringValueOfParameterNamed(lastnameParamName); }
actualChanges.put(lastnameParamName, newValue);
this.lastname = newValue; /**
} * Delete is a <i>soft delete</i>. Updates flag so it wont appear in
* query/report results.
final String emailParamName = "email"; *
if (command.isChangeInStringParameterNamed(emailParamName, this.email)) { * Any fields with unique constraints and prepended with id of record.
final String newValue = command */
.stringValueOfParameterNamed(emailParamName); public void delete() {
actualChanges.put(emailParamName, newValue); this.deleted = true;
this.email = newValue; this.enabled = false;
} this.accountNonExpired = false;
this.firstTimeLoginRemaining = true;
return actualChanges; this.username = getId() + "_DELETED_" + this.username;
} }
private String[] getRolesAsIdStringArray() { public boolean isDeleted() {
final List<String> roleIds = new ArrayList<String>(); return this.deleted;
}
for (final Role role : this.roles) {
roleIds.add(role.getId().toString()); @Override
} public Collection<GrantedAuthority> getAuthorities() {
return populateGrantedAuthorities();
return roleIds.toArray(new String[roleIds.size()]); }
}
private List<GrantedAuthority> populateGrantedAuthorities() {
/** final List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
* Delete is a <i>soft delete</i>. Updates flag so it wont appear in for (final Role role : this.roles) {
* query/report results. final Collection<Permission> permissions = role.getPermissions();
* for (final Permission permission : permissions) {
* Any fields with unique constraints and prepended with id of record. grantedAuthorities.add(new SimpleGrantedAuthority(permission.getCode()));
*/ }
public void delete() { }
this.deleted = true; return grantedAuthorities;
this.enabled = false; }
this.accountNonExpired = false;
this.firstTimeLoginRemaining = true; @Override
this.username = getId() + "_DELETED_" + this.username; public String getPassword() {
} return this.password;
}
public boolean isDeleted() {
return this.deleted; @Override
} public String getUsername() {
return this.username;
@Override }
public Collection<GrantedAuthority> getAuthorities() {
return populateGrantedAuthorities(); @Override
} public boolean isAccountNonExpired() {
return this.accountNonExpired;
private List<GrantedAuthority> populateGrantedAuthorities() { }
final List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
for (final Role role : this.roles) { @Override
final Collection<Permission> permissions = role.getPermissions(); public boolean isAccountNonLocked() {
for (final Permission permission : permissions) { return this.accountNonLocked;
grantedAuthorities.add(new SimpleGrantedAuthority(permission }
.getCode()));
} @Override
} public boolean isCredentialsNonExpired() {
return grantedAuthorities; return this.credentialsNonExpired;
} }
@Override @Override
public String getPassword() { public boolean isEnabled() {
return this.password; return this.enabled;
} }
@Override public String getFirstname() {
public String getUsername() { return this.firstname;
return this.username; }
}
public String getLastname() {
@Override return this.lastname;
public boolean isAccountNonExpired() { }
return this.accountNonExpired;
} public String getEmail() {
return this.email;
@Override }
public boolean isAccountNonLocked() {
return this.accountNonLocked; public Set<Role> getRoles() {
} return this.roles;
}
@Override
public boolean isCredentialsNonExpired() { public Office getOffice() {
return this.credentialsNonExpired; return this.office;
} }
@Override public boolean canNotApproveLoanInPast() {
public boolean isEnabled() { return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "APPROVEINPAST_LOAN");
return this.enabled; }
}
public boolean canNotRejectLoanInPast() {
public String getFirstname() { return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "REJECTINPAST_LOAN");
return this.firstname; }
}
public boolean canNotWithdrawByClientLoanInPast() {
public String getLastname() { return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "WITHDRAWINPAST_LOAN");
return this.lastname; }
}
public boolean canNotDisburseLoanInPast() {
public String getEmail() { return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "DISBURSEINPAST_LOAN");
return this.email; }
}
public boolean canNotMakeRepaymentOnLoanInPast() {
public Set<Role> getRoles() { return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "REPAYMENTINPAST_LOAN");
return this.roles; }
}
public boolean hasNotPermissionForReport(final String reportName) {
public Office getOffice() {
return this.office; if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "REPORTING_SUPER_USER", "READ_" + reportName)) { return true; }
}
return false;
public boolean canNotApproveLoanInPast() { }
return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "APPROVEINPAST_LOAN");
} public boolean hasNotPermissionForDatatable(final String datatable, final String accessType) {
public boolean canNotRejectLoanInPast() { final String matchPermission = accessType + "_" + datatable;
return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "REJECTINPAST_LOAN");
} if (accessType.equalsIgnoreCase("READ")) {
public boolean canNotWithdrawByClientLoanInPast() { if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", matchPermission)) { return true; }
return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "WITHDRAWINPAST_LOAN");
} return false;
}
public boolean canNotDisburseLoanInPast() {
return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "DISBURSEINPAST_LOAN"); if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", matchPermission)) { return true; }
}
return false;
public boolean canNotMakeRepaymentOnLoanInPast() { }
return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "REPAYMENTINPAST_LOAN");
} public boolean hasNotPermissionForAnyOf(final String... permissionCodes) {
boolean hasNotPermission = true;
public boolean hasNotPermissionForReport(final String reportName) { for (final String permissionCode : permissionCodes) {
final boolean checkPermission = hasPermissionTo(permissionCode);
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", if (checkPermission) {
"REPORTING_SUPER_USER", "READ_" + reportName)) { hasNotPermission = false;
return true; break;
} }
}
return false; return hasNotPermission;
} }
public boolean hasNotPermissionForDatatable(final String datatable, public void validateHasReadPermission(final String resourceType) {
final String accessType) {
final String authorizationMessage = "User has no authority to view " + resourceType.toLowerCase() + "s";
final String matchPermission = accessType + "_" + datatable; final String matchPermission = "READ_" + resourceType.toUpperCase();
if (accessType.equalsIgnoreCase("READ")) { if (!hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", matchPermission)) { return; }
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", throw new NoAuthorizationException(authorizationMessage);
matchPermission)) { }
return true;
} private boolean hasNotPermissionTo(final String permissionCode) {
return !hasPermissionTo(permissionCode);
return false; }
}
private boolean hasPermissionTo(final String permissionCode) {
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", matchPermission)) { boolean hasPermission = hasAllFunctionsPermission();
return true; if (!hasPermission) {
} for (final Role role : this.roles) {
if (role.hasPermissionTo(permissionCode)) {
return false; hasPermission = true;
} break;
}
public boolean hasNotPermissionForAnyOf(final String... permissionCodes) { }
boolean hasNotPermission = true; }
for (final String permissionCode : permissionCodes) { return hasPermission;
final boolean checkPermission = hasPermissionTo(permissionCode); }
if (checkPermission) {
hasNotPermission = false; private boolean hasAllFunctionsPermission() {
break; boolean match = false;
} for (final Role role : this.roles) {
} if (role.hasPermissionTo("ALL_FUNCTIONS")) {
return hasNotPermission; match = true;
} break;
}
public void validateHasReadPermission(final String resourceType) { }
return match;
final String authorizationMessage = "User has no authority to view " }
+ resourceType.toLowerCase() + "s";
final String matchPermission = "READ_" + resourceType.toUpperCase(); public boolean hasIdOf(final Long userId) {
return getId().equals(userId);
if (!hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", }
matchPermission)) {
return; private boolean hasNotAnyPermission(final List<String> permissions) {
} return !hasAnyPermission(permissions);
}
throw new NoAuthorizationException(authorizationMessage);
} private boolean hasAnyPermission(final List<String> permissions) {
boolean hasAtLeastOneOf = false;
private boolean hasNotPermissionTo(final String permissionCode) {
return !hasPermissionTo(permissionCode); for (final String permissionCode : permissions) {
} if (hasPermissionTo(permissionCode)) {
hasAtLeastOneOf = true;
private boolean hasPermissionTo(final String permissionCode) { break;
boolean hasPermission = hasAllFunctionsPermission(); }
if (!hasPermission) { }
for (final Role role : this.roles) {
if (role.hasPermissionTo(permissionCode)) { return hasAtLeastOneOf;
hasPermission = true; }
break;
} public void validateHasPermissionTo(final String function, final List<String> allowedPermissions) {
} if (hasNotAnyPermission(allowedPermissions)) {
} final String authorizationMessage = "User has no authority to: " + function;
return hasPermission; throw new NoAuthorizationException(authorizationMessage);
} }
}
private boolean hasAllFunctionsPermission() {
boolean match = false; public void validateHasPermissionTo(final String function) {
for (final Role role : this.roles) { if (hasNotPermissionTo(function)) {
if (role.hasPermissionTo("ALL_FUNCTIONS")) { final String authorizationMessage = "User has no authority to: " + function;
match = true; logger.info("Unauthorized access: userId: " + getId() + " action: " + function + " allowed: " + getAuthorities());
break; throw new NoAuthorizationException(authorizationMessage);
} }
} }
return match;
} public void validateHasReadPermission(final String function, final Long userId) {
if ("USER".equalsIgnoreCase(function) && userId.equals(getId())) {
public boolean hasIdOf(final Long userId) { // abstain from validation as user allowed fetch their own data no matter what permissions they have.
return getId().equals(userId); } else {
} validateHasPermissionTo(function);
}
private boolean hasNotAnyPermission(final List<String> permissions) { }
return !hasAnyPermission(permissions);
} public void validateHasCheckerPermissionTo(final String function) {
private boolean hasAnyPermission(final List<String> permissions) { final String checkerPermissionName = function.toUpperCase() + "_CHECKER";
boolean hasAtLeastOneOf = false; if (hasNotPermissionTo("CHECKER_SUPER_USER") && hasNotPermissionTo(checkerPermissionName)) {
final String authorizationMessage = "User has no authority to be a checker for: " + function;
for (final String permissionCode : permissions) { throw new NoAuthorizationException(authorizationMessage);
if (hasPermissionTo(permissionCode)) { }
hasAtLeastOneOf = true; }
break;
} public void validateHasDatatableReadPermission(final String datatable) {
} if (hasNotPermissionForDatatable(datatable, "READ")) { throw new NoAuthorizationException("Not authorised to read datatable: "
+ datatable); }
return hasAtLeastOneOf; }
}
public Long getStaffId() {
public void validateHasPermissionTo(final String function, Long staffId = null;
final List<String> allowedPermissions) { if (this.staff != null) {
if (hasNotAnyPermission(allowedPermissions)) { staffId = this.staff.getId();
final String authorizationMessage = "User has no authority to: " }
+ function; return staffId;
throw new NoAuthorizationException(authorizationMessage); }
}
} public String getStaffDisplayName() {
String staffDisplayName = null;
public void validateHasPermissionTo(final String function) { if (this.staff != null) {
if (hasNotPermissionTo(function)) { staffDisplayName = this.staff.displayName();
final String authorizationMessage = "User has no authority to: " }
+ function; return staffDisplayName;
logger.info("Unauthorized access: userId: " + getId() + " action: " }
+ function + " allowed: " + getAuthorities());
throw new NoAuthorizationException(authorizationMessage);
}
}
public void validateHasCheckerPermissionTo(final String function) {
final String checkerPermissionName = function.toUpperCase()
+ "_CHECKER";
if (hasNotPermissionTo("CHECKER_SUPER_USER")
&& hasNotPermissionTo(checkerPermissionName)) {
final String authorizationMessage = "User has no authority to be a checker for: "
+ function;
throw new NoAuthorizationException(authorizationMessage);
}
}
public void validateHasDatatableReadPermission(final String datatable) {
if (hasNotPermissionForDatatable(datatable, "READ")) {
throw new NoAuthorizationException(
"Not authorised to read datatable: " + datatable);
}
}
public Long getStaffId() {
Long staffId = null;
if (this.staff != null) {
staffId = this.staff.getId();
}
return staffId;
}
public String getStaffDisplayName() {
String staffDisplayName = null;
if (this.staff != null) {
staffDisplayName = this.staff.displayName();
}
return staffDisplayName;
}
} }