1
0
mirror of https://github.com/sismics/docs.git synced 2025-12-13 01:36:18 +00:00

Closes #252: route model permissions

This commit is contained in:
Benjamin Gamard
2018-10-28 17:03:21 +01:00
parent dc5a157dad
commit 4910dfd527
11 changed files with 128 additions and 35 deletions

View File

@@ -1,16 +1,14 @@
package com.sismics.docs.rest.resource;
import com.google.common.collect.Lists;
import com.sismics.docs.core.constant.AclTargetType;
import com.sismics.docs.core.constant.ActionType;
import com.sismics.docs.core.constant.RouteStepTransition;
import com.sismics.docs.core.constant.RouteStepType;
import com.sismics.docs.core.constant.*;
import com.sismics.docs.core.dao.AclDao;
import com.sismics.docs.core.dao.GroupDao;
import com.sismics.docs.core.dao.RouteModelDao;
import com.sismics.docs.core.dao.TagDao;
import com.sismics.docs.core.dao.UserDao;
import com.sismics.docs.core.dao.criteria.RouteModelCriteria;
import com.sismics.docs.core.dao.dto.RouteModelDto;
import com.sismics.docs.core.model.jpa.Acl;
import com.sismics.docs.core.model.jpa.Group;
import com.sismics.docs.core.model.jpa.RouteModel;
import com.sismics.docs.core.model.jpa.User;
@@ -19,6 +17,7 @@ import com.sismics.docs.core.util.jpa.SortCriteria;
import com.sismics.docs.rest.constant.BaseFunction;
import com.sismics.rest.exception.ClientException;
import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.util.AclUtil;
import com.sismics.rest.util.ValidationUtil;
import javax.json.*;
@@ -64,7 +63,7 @@ public class RouteModelResource extends BaseResource {
SortCriteria sortCriteria = new SortCriteria(sortColumn, asc);
RouteModelDao routeModelDao = new RouteModelDao();
List<RouteModelDto> routeModelDtoList = routeModelDao.findByCriteria(new RouteModelCriteria(), sortCriteria);
List<RouteModelDto> routeModelDtoList = routeModelDao.findByCriteria(new RouteModelCriteria().setTargetIdList(getTargetIdList(null)), sortCriteria);
for (RouteModelDto routeModelDto : routeModelDtoList) {
routeModels.add(Json.createObjectBuilder()
.add("id", routeModelDto.getId())
@@ -111,6 +110,23 @@ public class RouteModelResource extends BaseResource {
.setName(name)
.setSteps(steps), principal.getId());
// Create read ACL
AclDao aclDao = new AclDao();
Acl acl = new Acl();
acl.setPerm(PermType.READ);
acl.setType(AclType.USER);
acl.setSourceId(id);
acl.setTargetId(principal.getId());
aclDao.create(acl, principal.getId());
// Create write ACL
acl = new Acl();
acl.setPerm(PermType.WRITE);
acl.setType(AclType.USER);
acl.setSourceId(id);
acl.setTargetId(principal.getId());
aclDao.create(acl, principal.getId());
// Always return OK
JsonObjectBuilder response = Json.createObjectBuilder()
.add("id", id);
@@ -125,7 +141,6 @@ public class RouteModelResource extends BaseResource {
private void validateRouteModelSteps(String steps) {
UserDao userDao = new UserDao();
GroupDao groupDao = new GroupDao();
TagDao tagDao = new TagDao();
try (JsonReader reader = Json.createReader(new StringReader(steps))) {
JsonArray stepsJson = reader.readArray();
@@ -374,6 +389,9 @@ public class RouteModelResource extends BaseResource {
.add("create_date", routeModel.getCreateDate().getTime())
.add("steps", routeModel.getSteps());
// Add ACL
AclUtil.addAcls(response, id, getTargetIdList(null));
return Response.ok().entity(response.build()).build();
}
}

View File

@@ -70,6 +70,11 @@ public class RouteResource extends BaseResource {
throw new NotFoundException();
}
// Check permission on this route model
if (!aclDao.checkPermission(routeModelId, PermType.READ, getTargetIdList(null))) {
throw new ForbiddenClientException();
}
// Avoid creating 2 running routes on the same document
RouteStepDao routeStepDao = new RouteStepDao();
if (routeStepDao.getCurrentStep(documentId) != null) {

View File

@@ -59,26 +59,6 @@ angular.module('docs').controller('SettingsWorkflowEdit', function($scope, $dial
return $stateParams.id;
};
/**
* In edit mode, load the current workflow.
*/
if ($scope.isEdit()) {
Restangular.one('routemodel', $stateParams.id).get().then(function (data) {
$scope.workflow = data;
$scope.workflow.steps = JSON.parse(data.steps);
_.each($scope.workflow.steps, function (step) {
if (!step.transitions) {
// Patch for old route models
$scope.updateTransitions(step);
}
});
});
} else {
$scope.workflow = {
steps: []
}
}
/**
* Update the current workflow.
*/
@@ -188,4 +168,25 @@ angular.module('docs').controller('SettingsWorkflowEdit', function($scope, $dial
Restangular.one('tag/list').get().then(function(data) {
$scope.tags = data.tags;
});
/**
* In edit mode, load the current workflow.
*/
if ($scope.isEdit()) {
Restangular.one('routemodel', $stateParams.id).get().then(function (data) {
$scope.workflow = data;
$scope.workflow.steps = JSON.parse(data.steps);
_.each($scope.workflow.steps, function (step) {
if (!step.transitions) {
// Patch for old route models
$scope.updateTransitions(step);
}
});
});
} else {
$scope.workflow = {
steps: []
};
$scope.addStep();
}
});

View File

@@ -311,7 +311,8 @@
"target_help": "<strong>Approve:</strong> Accept or reject the review<br/><strong>Validate:</strong> Review and continue the workflow",
"add_step": "Add a workflow step",
"actions": "What happens after?",
"remove_action": "Remove action"
"remove_action": "Remove action",
"acl_info": "Only users and groups defined here will be able to start this workflow on a document"
}
},
"security": {

View File

@@ -136,6 +136,16 @@
</div>
</div>
<div class="panel panel-default mt-30" ng-show="isEdit()">
<div class="panel-body">
<p translate="settings.workflow.edit.acl_info"></p>
<acl-edit source="workflow.id"
acls="workflow.acls"
writable="workflow.writable"
creator="workflow.creator"></acl-edit>
</div>
</div>
<div class="clearfix form-group mt-10">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" ng-click="edit()" ng-disabled="!editWorkflowForm.$valid">

View File

@@ -607,6 +607,10 @@ input[readonly].share-link {
margin-bottom: 19px;
}
.mt-30 {
margin-top: 30px;
}
.ml-10 {
margin-left: 10px;
}

View File

@@ -24,6 +24,10 @@ public class TestRouteModelResource extends BaseJerseyTest {
// Login admin
String adminToken = clientUtil.login("admin", "admin", false);
// Login routeModel1
clientUtil.createUser("routeModel1");
String routeModel1Token = clientUtil.login("routeModel1");
// Create a tag
JsonObject json = target().path("/tag").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
@@ -32,7 +36,7 @@ public class TestRouteModelResource extends BaseJerseyTest {
.param("color", "#ff0000")), JsonObject.class);
String tagRouteId = json.getString("id");
// Get all route models
// Get all route models with admin
json = target().path("/routemodel")
.queryParam("sort_column", "2")
.queryParam("asc", "false")
@@ -50,7 +54,7 @@ public class TestRouteModelResource extends BaseJerseyTest {
.param("steps", "[{\"type\":\"VALIDATE\",\"transitions\":[{\"name\":\"VALIDATED\",\"actions\":[]}],\"target\":{\"name\":\"administrators\",\"type\":\"GROUP\"},\"name\":\"Check the document's metadata\"}]")), JsonObject.class);
String routeModelId = json.getString("id");
// Get all route models
// Get all route models with admin
json = target().path("/routemodel")
.queryParam("sort_column", "2")
.queryParam("asc", "false")
@@ -62,6 +66,35 @@ public class TestRouteModelResource extends BaseJerseyTest {
Assert.assertEquals(routeModelId, routeModels.getJsonObject(0).getString("id"));
Assert.assertEquals("Workflow validation 1", routeModels.getJsonObject(0).getString("name"));
// Get all route models with routeModel1
json = target().path("/routemodel")
.queryParam("sort_column", "2")
.queryParam("asc", "false")
.request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, routeModel1Token)
.get(JsonObject.class);
routeModels = json.getJsonArray("routemodels");
Assert.assertEquals(0, routeModels.size());
// Add an ACL READ for routeModel1 with admin
json = target().path("/acl").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.put(Entity.form(new Form()
.param("source", routeModelId)
.param("perm", "READ")
.param("target", "routeModel1")
.param("type", "USER")), JsonObject.class);
// Get all route models with routeModel1
json = target().path("/routemodel")
.queryParam("sort_column", "2")
.queryParam("asc", "false")
.request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, routeModel1Token)
.get(JsonObject.class);
routeModels = json.getJsonArray("routemodels");
Assert.assertEquals(1, routeModels.size());
// Get the route model
json = target().path("/routemodel/" + routeModelId)
.request()
@@ -70,6 +103,8 @@ public class TestRouteModelResource extends BaseJerseyTest {
Assert.assertEquals(routeModelId, json.getString("id"));
Assert.assertEquals("Workflow validation 1", json.getString("name"));
Assert.assertEquals("[{\"type\":\"VALIDATE\",\"transitions\":[{\"name\":\"VALIDATED\",\"actions\":[]}],\"target\":{\"name\":\"administrators\",\"type\":\"GROUP\"},\"name\":\"Check the document's metadata\"}]", json.getString("steps"));
JsonArray acls = json.getJsonArray("acls");
Assert.assertEquals(3, acls.size());// 2 for admin, 1 for routeModel1
// Update the route model with actions
target().path("/routemodel/" + routeModelId).request()