diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/PermissionsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/PermissionsApiResource.java index 501c7df9c..28444280c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/PermissionsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/PermissionsApiResource.java @@ -5,17 +5,23 @@ import java.util.Set; 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.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; +import org.mifosng.platform.api.commands.PermissionsCommand; +import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.PermissionUsageData; +import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.service.PermissionReadPlatformService; +import org.mifosng.platform.user.service.PermissionWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -27,7 +33,13 @@ public class PermissionsApiResource { @Autowired private PermissionReadPlatformService permissionReadPlatformService; + + @Autowired + private PermissionWritePlatformService permissionWritePlatformService; + @Autowired + private PortfolioApiDataConversionService apiDataConversionService; + @Autowired private PortfolioApiJsonSerializerService apiJsonSerializerService; @@ -43,11 +55,29 @@ public class PermissionsApiResource { context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + final boolean makerCheckerable = ApiParameterHelper.makerCheckerable(uriInfo.getQueryParameters()); + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - final Collection permissions = this.permissionReadPlatformService.retrieveAllPermissions(); + + Collection permissions = null; + if (makerCheckerable) permissions = this.permissionReadPlatformService.retrieveAllMakerCheckerablePermissions(); + else permissions = this.permissionReadPlatformService.retrieveAllPermissions(); return this.apiJsonSerializerService.serializePermissionDataToJson(prettyPrint, responseParameters, permissions); } + + + @PUT + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response updatePermissionsDetails(final String jsonRequestBody) { + + final PermissionsCommand command = this.apiDataConversionService.convertApiRequestJsonToPermissionsCommand(jsonRequestBody); + + final Long entityId = this.permissionWritePlatformService.updateMakerCheckerPermissions(command); + + return Response.ok().entity(new EntityIdentifier(entityId)).build(); + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java index 8e42bb1a4..0fbea5b86 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java @@ -15,8 +15,8 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.api.data.CommandSourceData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.PermissionUsageData; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/PermissionsCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/PermissionsCommand.java new file mode 100644 index 000000000..103bb6f0b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/PermissionsCommand.java @@ -0,0 +1,26 @@ +package org.mifosng.platform.api.commands; + +import java.util.Map; + +/** + * Immutable command for updating permissions (initially maker-checker). + */ +public class PermissionsCommand { + + private final Map permissions; + + private final transient boolean makerCheckerApproval; + + public PermissionsCommand(final Map permissionsMap, final boolean makerCheckerApproval) { + this.permissions = permissionsMap; + this.makerCheckerApproval = makerCheckerApproval; + } + + public Map getPermissions() { + return this.permissions; + } + + public boolean isApprovedByChecker() { + return this.makerCheckerApproval; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/accounting/api/commands/RolePermissionCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/RolePermissionCommand.java similarity index 93% rename from mifosng-provider/src/main/java/org/mifosng/platform/accounting/api/commands/RolePermissionCommand.java rename to mifosng-provider/src/main/java/org/mifosng/platform/api/commands/RolePermissionCommand.java index a262dbc14..f0a60d193 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/accounting/api/commands/RolePermissionCommand.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/RolePermissionCommand.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.accounting.api.commands; +package org.mifosng.platform.api.commands; import java.util.Map; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/PermissionUsageData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/PermissionUsageData.java index c8e522119..2988c8277 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/PermissionUsageData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/PermissionUsageData.java @@ -15,20 +15,17 @@ public class PermissionUsageData { private final String actionName; @SuppressWarnings("unused") private final Boolean selected; - @SuppressWarnings("unused") - private final Boolean canMakerChecker; public static PermissionUsageData from(final String permissionCode, final boolean isSelected) { - return new PermissionUsageData(null, permissionCode, null, null, isSelected, null); + return new PermissionUsageData(null, permissionCode, null, null, isSelected); } public PermissionUsageData(final String grouping, final String code, final String entityName, final String actionName, - final Boolean selected, final Boolean canMakerChecker) { + final Boolean selected) { this.grouping = grouping; this.code = code; this.entityName = entityName; this.actionName = actionName; this.selected = selected; - this.canMakerChecker = canMakerChecker; } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java index 56e4b9751..e13a04f79 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java @@ -1,6 +1,5 @@ package org.mifosng.platform.api.infrastructure; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; import org.mifosng.platform.api.commands.LoanReassignmentCommand; @@ -25,7 +24,9 @@ import org.mifosng.platform.api.commands.LoanTransactionCommand; import org.mifosng.platform.api.commands.NoteCommand; import org.mifosng.platform.api.commands.OfficeCommand; import org.mifosng.platform.api.commands.OrganisationCurrencyCommand; +import org.mifosng.platform.api.commands.PermissionsCommand; import org.mifosng.platform.api.commands.RoleCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.SavingAccountCommand; import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosng.platform.api.commands.StaffCommand; @@ -41,6 +42,8 @@ public interface PortfolioApiDataConversionService { OfficeCommand convertJsonToOfficeCommand(Long resourceIdentifier, String json); RoleCommand convertApiRequestJsonToRoleCommand(Long resourceIdentifier, String json); + + PermissionsCommand convertApiRequestJsonToPermissionsCommand(String jsonRequestBody); RolePermissionCommand convertApiRequestJsonToRolePermissionCommand(Long roleId, String jsonRequestBody); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java index 8d98ac04c..d716abb00 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java @@ -17,7 +17,6 @@ import java.util.Set; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; import org.mifosng.platform.api.commands.ChargeCommand; @@ -42,7 +41,9 @@ import org.mifosng.platform.api.commands.LoanTransactionCommand; import org.mifosng.platform.api.commands.NoteCommand; import org.mifosng.platform.api.commands.OfficeCommand; import org.mifosng.platform.api.commands.OrganisationCurrencyCommand; +import org.mifosng.platform.api.commands.PermissionsCommand; import org.mifosng.platform.api.commands.RoleCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.SavingAccountCommand; import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosng.platform.api.commands.StaffCommand; @@ -256,6 +257,17 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo // command object return this.portfolioCommandDeserializerService.deserializeRoleCommand(resourceIdentifier, json, false); } + + @Override + public PermissionsCommand convertApiRequestJsonToPermissionsCommand(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + final Map permissionsMap = gsonConverter.fromJson(json, typeOfMap); + + return new PermissionsCommand(permissionsMap, false); + } @Override public RolePermissionCommand convertApiRequestJsonToRolePermissionCommand(final Long resourceIdentifier, final String json) { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeerializerServiceGoogleGson.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeerializerServiceGoogleGson.java index 6d0ead906..201bf7a2d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeerializerServiceGoogleGson.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeerializerServiceGoogleGson.java @@ -4,9 +4,9 @@ import java.util.HashSet; import java.util.Set; import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.UserCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.infrastructure.api.JsonParserHelper; import org.mifosng.platform.infrastructure.errorhandling.InvalidJsonException; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeserializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeserializerService.java index 3b39862b9..31dc82527 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeserializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeserializerService.java @@ -1,8 +1,8 @@ package org.mifosng.platform.api.infrastructure; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.UserCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; /** * Service for de-serializing JSON for a command into the platforms internal diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerService.java index 2c1cf4f0b..fc4cc0ec7 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerService.java @@ -1,8 +1,8 @@ package org.mifosng.platform.api.infrastructure; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.UserCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; /** * Service for serializing commands into another format. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerServiceJson.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerServiceJson.java index dcfe5f5aa..d52292e1a 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerServiceJson.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerServiceJson.java @@ -2,9 +2,9 @@ package org.mifosng.platform.api.infrastructure; import java.util.HashSet; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.UserCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.infrastructure.api.GoogleGsonSerializerHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/PermissionCantBeMakerCheckerableException.java b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/PermissionCantBeMakerCheckerableException.java new file mode 100644 index 000000000..0f0edceab --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/PermissionCantBeMakerCheckerableException.java @@ -0,0 +1,13 @@ +package org.mifosng.platform.exceptions; + +/** + * A {@link RuntimeException} thrown when permission resources are not found. + */ +public class PermissionCantBeMakerCheckerableException extends + AbstractPlatformResourceNotFoundException { + + public PermissionCantBeMakerCheckerableException(String code) { + super("error.msg.permission.code.not.makercheckerable", "Permission with Code " + + code + " can't be Maker Checkerable", code); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/ApiParameterHelper.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/ApiParameterHelper.java index a2f40d5fc..e910aba81 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/ApiParameterHelper.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/ApiParameterHelper.java @@ -80,6 +80,15 @@ public class ApiParameterHelper { } return template; } + + public static boolean makerCheckerable(final MultivaluedMap queryParams) { + boolean makerCheckerable = false; + if (queryParams.getFirst("makerCheckerable") != null) { + String prettyPrintValue = queryParams.getFirst("makerCheckerable"); + makerCheckerable = "true".equalsIgnoreCase(prettyPrintValue); + } + return makerCheckerable; + } public static boolean genericResultSet(final MultivaluedMap queryParams) { boolean genericResultSet = false; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java index 5e1e6f783..66529bcde 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java @@ -1,8 +1,8 @@ package org.mifosng.platform.makerchecker.service; import org.joda.time.LocalDate; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java index 0cb5cf747..25ef0af86 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java @@ -6,12 +6,12 @@ import org.springframework.security.access.prepost.PreAuthorize; public interface CodeWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_CODE')") + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CODE')") Long createCode(final CodeCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_CODE')") + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_CODE')") Long updateCode(final CodeCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE', 'DELETE_CODE')") + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CODE')") EntityIdentifier deleteCode(Long codeId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/AppUser.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/AppUser.java index 5c32320a7..b95f663df 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/AppUser.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/AppUser.java @@ -172,7 +172,7 @@ public class AppUser extends AbstractAuditableCustom implements P for (Role role : this.roles) { Collection permissions = role.getPermissions(); for (Permission permission : permissions) { - grantedAuthorities.add(new SimpleGrantedAuthority(permission.code())); + grantedAuthorities.add(new SimpleGrantedAuthority(permission.getCode())); } } return grantedAuthorities; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/Permission.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/Permission.java index 004396c84..467589cde 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/Permission.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/Permission.java @@ -10,7 +10,6 @@ import org.springframework.data.jpa.domain.AbstractPersistable; @Table(name = "m_permission") public class Permission extends AbstractPersistable { - @SuppressWarnings("unused") @Column(name = "grouping", nullable = false, length = 45) private final String grouping; @@ -25,8 +24,9 @@ public class Permission extends AbstractPersistable { @Column(name = "action_name", nullable = true, length = 100) private final String actionName; - @Column(name = "can_maker_checker", nullable = false) - private final boolean canMakerChecker; + @SuppressWarnings("unused") + @Column(name = "can_maker_checker", nullable = false) + private boolean canMakerChecker; protected Permission() { this.grouping = null; @@ -40,11 +40,20 @@ public class Permission extends AbstractPersistable { return this.code.equalsIgnoreCase(checkCode); } - public String code() { + public String getCode() { return this.code; } public boolean hasMakerCheckerEnabled() { return this.canMakerChecker; } + + public void setCanMakerChecker(Boolean canMakerChecker) { + this.canMakerChecker = canMakerChecker; + } + + public String getGrouping() { + return this.grouping; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformService.java index 466012bb8..f6ce170e0 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformService.java @@ -7,6 +7,8 @@ import org.mifosng.platform.api.data.PermissionUsageData; public interface PermissionReadPlatformService { Collection retrieveAllPermissions(); + + Collection retrieveAllMakerCheckerablePermissions(); Collection retrieveAllRolePermissions(Long roleId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformServiceImpl.java index 8c43088be..dfb1e9945 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionReadPlatformServiceImpl.java @@ -7,70 +7,110 @@ import java.util.Collection; import org.mifosng.platform.api.data.PermissionUsageData; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.security.PlatformSecurityContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; @Service -public class PermissionReadPlatformServiceImpl implements PermissionReadPlatformService { +public class PermissionReadPlatformServiceImpl implements + PermissionReadPlatformService { - private final JdbcTemplate jdbcTemplate; - private final PlatformSecurityContext context; + private final static Logger logger = LoggerFactory + .getLogger(PermissionReadPlatformService.class); + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; - @Autowired - public PermissionReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { - this.context = context; - this.jdbcTemplate = new JdbcTemplate(dataSource); - } + @Autowired + public PermissionReadPlatformServiceImpl( + final PlatformSecurityContext context, + final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } - @Override - public Collection retrieveAllPermissions() { + @Override + public Collection retrieveAllPermissions() { - context.authenticatedUser(); + context.authenticatedUser(); - final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper(); - final String sql = mapper.permissionSchema(); + final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper(); + final String sql = mapper.permissionSchema(); + logger.info("retrieveAllPermissions: " + sql); + return this.jdbcTemplate.query(sql, mapper, new Object[] {}); + } - return this.jdbcTemplate.query(sql, mapper, new Object[] {}); - } + @Override + public Collection retrieveAllMakerCheckerablePermissions() { - @Override - public Collection retrieveAllRolePermissions(final Long roleId) { + context.authenticatedUser(); - final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper(); - final String sql = mapper.rolePermissionSchema(); + final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper(); + final String sql = mapper.makerCheckerablePermissionSchema(); + logger.info("retrieveAllMakerCheckerablePermissions: " + sql); - return this.jdbcTemplate.query(sql, mapper, new Object[] { roleId }); - } + return this.jdbcTemplate.query(sql, mapper, new Object[] {}); + } - private static final class PermissionUsageDataMapper implements RowMapper { + @Override + public Collection retrieveAllRolePermissions( + final Long roleId) { - @Override - public PermissionUsageData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper(); + final String sql = mapper.rolePermissionSchema(); + logger.info("retrieveAllRolePermissions: " + sql); - final String grouping = rs.getString("grouping"); - final String code = rs.getString("code"); - final String entityName = rs.getString("entityName"); - final String actionName = rs.getString("actionName"); - final Boolean selected = rs.getBoolean("selected"); - final Boolean canMakerChecker = rs.getBoolean("canMakerChecker"); + return this.jdbcTemplate.query(sql, mapper, new Object[] { roleId }); + } - return new PermissionUsageData(grouping, code, entityName, actionName, selected, canMakerChecker); - } + private static final class PermissionUsageDataMapper implements + RowMapper { - public String permissionSchema() { - return "select p.grouping, p.code, p.entity_name as entityName, p.action_name as actionName, true as selected, p.can_maker_checker as canMakerChecker" - + " from m_permission p " + " order by p.grouping, ifnull(entity_name, ''), p.code"; - } + @Override + public PermissionUsageData mapRow(final ResultSet rs, + @SuppressWarnings("unused") final int rowNum) + throws SQLException { - public String rolePermissionSchema() { - return "select p.grouping, p.code, p.entity_name as entityName, p.action_name as actionName, if(isnull(rp.role_id), false, true) as selected, " - + " if(isnull(rp.role_id), false, p.can_maker_checker) as canMakerChecker " - + " from m_permission p " - + " left join m_role_permission rp on rp.permission_id = p.id and rp.role_id = ? " - + " order by p.grouping, ifnull(entity_name, ''), p.code"; - } - } + final String grouping = rs.getString("grouping"); + final String code = rs.getString("code"); + final String entityName = rs.getString("entityName"); + final String actionName = rs.getString("actionName"); + final Boolean selected = rs.getBoolean("selected"); + + return new PermissionUsageData(grouping, code, entityName, + actionName, selected); + } + + public String permissionSchema() { + /* get all non-CHECKER permissions */ + return "select p.grouping, p.code, p.entity_name as entityName, p.action_name as actionName, true as selected" + + " from m_permission p " + + " where code not like '%\\_CHECKER'" + + " order by p.grouping, ifnull(entity_name, ''), p.code"; + } + + public String makerCheckerablePermissionSchema() { + /* + * get all 'Maker-Checkerable' permissions - Maintenance permissions + * (i.e. exclude the 'special' grouping, the READ permissions and + * the CHECKER permissions + */ + + return "select p.grouping, p.code, p.entity_name as entityName, p.action_name as actionName, p.can_maker_checker as selected" + + " from m_permission p " + + " where grouping != 'special' and code not like 'READ_%' and code not like '%\\_CHECKER'" + + " order by p.grouping, ifnull(entity_name, ''), p.code"; + } + + public String rolePermissionSchema() { + return "select p.grouping, p.code, p.entity_name as entityName, p.action_name as actionName, if(isnull(rp.role_id), false, true) as selected " + + " from m_permission p " + + " left join m_role_permission rp on rp.permission_id = p.id and rp.role_id = ? " + + " order by p.grouping, ifnull(entity_name, ''), p.code"; + } + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionWritePlatformService.java new file mode 100644 index 000000000..65128f59d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionWritePlatformService.java @@ -0,0 +1,11 @@ +package org.mifosng.platform.user.service; + + +import org.mifosng.platform.api.commands.PermissionsCommand; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface PermissionWritePlatformService { + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PERMISSIONS_ROLE')") + Long updateMakerCheckerPermissions(PermissionsCommand command); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..f472ff736 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/PermissionWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,74 @@ +package org.mifosng.platform.user.service; + +import java.util.Collection; +import java.util.Map; + +import org.mifosng.platform.api.commands.PermissionsCommand; +import org.mifosng.platform.exceptions.PermissionNotFoundException; +import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosng.platform.user.domain.Permission; +import org.mifosng.platform.user.domain.PermissionRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class PermissionWritePlatformServiceJpaRepositoryImpl implements + PermissionWritePlatformService { + + private final PlatformSecurityContext context; + private final PermissionRepository permissionRepository; + + @Autowired + public PermissionWritePlatformServiceJpaRepositoryImpl( + final PlatformSecurityContext context, + final PermissionRepository permissionRepository) { + this.context = context; + this.permissionRepository = permissionRepository; + } + + @Transactional + @Override + public Long updateMakerCheckerPermissions(final PermissionsCommand command) { + context.authenticatedUser(); + + final Collection allPermissions = this.permissionRepository + .findAll(); + + final Map commandPermissions = command + .getPermissions(); + for (final String permissionCode : commandPermissions.keySet()) { + + final Permission permission = findPermissionByCode(allPermissions, + permissionCode); + + if (permission.getCode().endsWith("_CHECKER") + || permission.getCode().startsWith("READ_") + || permission.getGrouping().equalsIgnoreCase("special")) { + throw new PermissionNotFoundException(permissionCode); + } + + final boolean isSelected = commandPermissions.get(permissionCode) + .booleanValue(); + permission.setCanMakerChecker(isSelected); + + this.permissionRepository.save(permission); + } + + return new Long(0); + } + + private Permission findPermissionByCode( + Collection allPermissions, String permissionCode) { + + if (allPermissions != null) { + for (Permission permission : allPermissions) { + if (permission.hasCode(permissionCode)) { + return permission; + } + } + } + + throw new PermissionNotFoundException(permissionCode); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformService.java index d592ad237..934e8b72c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformService.java @@ -1,7 +1,7 @@ package org.mifosng.platform.user.service; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; import org.springframework.security.access.prepost.PreAuthorize; public interface RoleWritePlatformService { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java index dd3ce8281..0b5abf6f5 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java @@ -3,8 +3,8 @@ package org.mifosng.platform.user.service; import java.util.Collection; import java.util.Map; -import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; +import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosng.platform.exceptions.PermissionNotFoundException; import org.mifosng.platform.exceptions.RoleNotFoundException;