killbill-aplcache
Changes
util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java 12(+12 -0)
Details
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
index 8f3b390..60e55b5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
@@ -204,4 +204,22 @@ public class SecurityResource extends JaxRsResourceBase {
securityApi.addRoleDefinition(json.getRole(), json.getPermissions(), context.createCallContextNoAccountId(createdBy, reason, comment, request));
return Response.status(Status.CREATED).build();
}
+
+
+ @TimedResource
+ @PUT
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @Path("/roles")
+ @ApiOperation(value = "Update a new role definition)")
+ public Response updateRoleDefinition(final RoleDefinitionJson json,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final HttpServletRequest request,
+ @javax.ws.rs.core.Context final UriInfo uriInfo) throws SecurityApiException {
+ securityApi.updateRoleDefinition(json.getRole(), json.getPermissions(), context.createCallContextNoAccountId(createdBy, reason, comment, request));
+ return Response.status(Status.OK).build();
+ }
+
}
diff --git a/util/src/main/java/org/killbill/billing/util/security/api/DefaultSecurityApi.java b/util/src/main/java/org/killbill/billing/util/security/api/DefaultSecurityApi.java
index 70ed26c..3d30a3c 100644
--- a/util/src/main/java/org/killbill/billing/util/security/api/DefaultSecurityApi.java
+++ b/util/src/main/java/org/killbill/billing/util/security/api/DefaultSecurityApi.java
@@ -206,6 +206,12 @@ public class DefaultSecurityApi implements SecurityApi {
}
@Override
+ public void updateRoleDefinition(final String role, final List<String> permissions, final CallContext callContext) throws SecurityApiException {
+ final List<String> sanitizedPermissions = sanitizeAndValidatePermissions(permissions);
+ userDao.updateRoleDefinition(role, sanitizedPermissions, callContext.getUserName());
+ }
+
+ @Override
public List<String> getRoleDefinition(final String role, final TenantContext tenantContext) {
final List<RolesPermissionsModelDao> permissionsModelDao = userDao.getRoleDefinition(role);
return ImmutableList.copyOf(Iterables.transform(permissionsModelDao, new Function<RolesPermissionsModelDao, String>() {
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
index 013f859..1d9757d 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
@@ -17,8 +17,11 @@
package org.killbill.billing.util.security.shiro.dao;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import org.apache.shiro.crypto.RandomNumberGenerator;
@@ -113,6 +116,50 @@ public class DefaultUserDao implements UserDao {
}
@Override
+ public void updateRoleDefinition(final String role, final List<String> permissions, final String createdBy) throws SecurityApiException {
+ final DateTime createdDate = clock.getUTCNow();
+ inTransactionWithExceptionHandling(new TransactionCallback<Void>() {
+ @Override
+ public Void inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+ final RolesPermissionsSqlDao rolesPermissionsSqlDao = handle.attach(RolesPermissionsSqlDao.class);
+ final List<RolesPermissionsModelDao> existingPermissions = rolesPermissionsSqlDao.getByRoleName(role);
+ if (existingPermissions.isEmpty()) {
+ throw new SecurityApiException(ErrorCode.SECURITY_INVALID_ROLE, role);
+ }
+
+ final Iterable<RolesPermissionsModelDao> toBeDeleted = Iterables.filter(existingPermissions, new Predicate<RolesPermissionsModelDao>() {
+ @Override
+ public boolean apply(final RolesPermissionsModelDao input) {
+ return !permissions.contains(input.getPermission());
+ }
+ });
+
+ final Iterable<String> toBeAdded = Iterables.filter(permissions, new Predicate<String>() {
+ @Override
+ public boolean apply(final String input) {
+ for (RolesPermissionsModelDao e : existingPermissions) {
+ if (e.getPermission().equals(input)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+
+ for (RolesPermissionsModelDao d : toBeDeleted) {
+ rolesPermissionsSqlDao.unactiveEvent(d.getRecordId(), createdDate, createdBy);
+ }
+
+ for (final String permission : toBeAdded) {
+ rolesPermissionsSqlDao.create(new RolesPermissionsModelDao(role, permission, createdDate, createdBy));
+ }
+ return null;
+ }
+ });
+
+ }
+
+ @Override
public List<RolesPermissionsModelDao> getRoleDefinition(final String role) {
return dbi.inTransaction(new TransactionCallback<List<RolesPermissionsModelDao>>() {
@Override
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
index dccee99..ad4187f 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
@@ -19,6 +19,10 @@ package org.killbill.billing.util.security.shiro.dao;
import java.util.List;
+import org.joda.time.DateTime;
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.util.audit.ChangeType;
+import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.Bind;
@@ -37,4 +41,12 @@ public interface RolesPermissionsSqlDao extends Transactional<RolesPermissionsSq
@SqlUpdate
public void create(@SmartBindBean final RolesPermissionsModelDao rolesPermissions);
+
+ @SqlUpdate
+ @Audited(ChangeType.UPDATE)
+ public void unactiveEvent(@Bind("recordId") final Long recordId,
+ @Bind("createdDate") final DateTime createdDate,
+ @Bind("createdBy") final String createdBy);
+
+
}
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserDao.java
index 142e13d..f0b4427 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserDao.java
@@ -29,6 +29,8 @@ public interface UserDao {
public void addRoleDefinition(String role, List<String> permissions, String createdBy) throws SecurityApiException;
+ public void updateRoleDefinition(String role, List<String> permissions, String createdBy) throws SecurityApiException;
+
public List<RolesPermissionsModelDao> getRoleDefinition(String role);
public void updateUserPassword(String username, String password, String createdBy) throws SecurityApiException;
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
index febc7ee..1d13de4 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
@@ -58,3 +58,16 @@ where role_name = :roleName
and is_active
;
>>
+
+unactiveEvent() ::= <<
+update <tableName()>
+set
+is_active = false
+, updated_by = :createdBy
+, updated_date = :createdDate
+where
+record_id = :recordId
+<AND_CHECK_TENANT("")>
+;
+>>
+
diff --git a/util/src/test/java/org/killbill/billing/util/security/shiro/realm/TestKillBillJdbcRealm.java b/util/src/test/java/org/killbill/billing/util/security/shiro/realm/TestKillBillJdbcRealm.java
index 30f90af..a2804e0 100644
--- a/util/src/test/java/org/killbill/billing/util/security/shiro/realm/TestKillBillJdbcRealm.java
+++ b/util/src/test/java/org/killbill/billing/util/security/shiro/realm/TestKillBillJdbcRealm.java
@@ -19,6 +19,8 @@ package org.killbill.billing.util.security.shiro.realm;
import java.util.List;
+import javax.validation.constraints.AssertTrue;
+
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
@@ -178,6 +180,33 @@ public class TestKillBillJdbcRealm extends UtilTestSuiteWithEmbeddedDB {
Assert.fail("Subject should not have rights to create tag definitions");
} catch (AuthorizationException e) {
}
+ }
+
+ @Test(groups = "slow")
+ public void testUpdateRoleDefinition() throws SecurityApiException {
+
+ final String username = "siskiyou";
+ final String password = "siskiyou33";
+
+ securityApi.addRoleDefinition("original", ImmutableList.of("account:*", "invoice", "tag:create_tag_definition"), callContext);
+ securityApi.addUserRoles(username, password, ImmutableList.of("restricted"), callContext);
+
+ final AuthenticationToken goodToken = new UsernamePasswordToken(username, password);
+
+ final List<String> roleDefinition = securityApi.getRoleDefinition("original", callContext);
+ Assert.assertEquals(roleDefinition.size(), 3);
+ Assert.assertTrue(roleDefinition.contains("account:*"));
+ Assert.assertTrue(roleDefinition.contains("invoice:*"));
+ Assert.assertTrue(roleDefinition.contains("tag:create_tag_definition"));
+
+ securityApi.updateRoleDefinition("original", ImmutableList.of("account:*", "payment", "tag:create_tag_definition", "entitlement:create"), callContext);
+
+ final List<String> updatedRoleDefinition = securityApi.getRoleDefinition("original", callContext);
+ Assert.assertEquals(updatedRoleDefinition.size(), 4);
+ Assert.assertTrue(updatedRoleDefinition.contains("account:*"));
+ Assert.assertTrue(updatedRoleDefinition.contains("payment:*"));
+ Assert.assertTrue(updatedRoleDefinition.contains("tag:create_tag_definition"));
+ Assert.assertTrue(updatedRoleDefinition.contains("entitlement:create"));
}