tagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)).setId(id), null);
+ if (tagDtoList.size() == 0) {
+ throw new NotFoundException();
}
-
- JsonObjectBuilder response = Json.createObjectBuilder()
- .add("stats", items);
- return Response.ok().entity(response.build()).build();
+
+ // Add tag informatiosn
+ TagDto tagDto = tagDtoList.get(0);
+ JsonObjectBuilder tag = Json.createObjectBuilder()
+ .add("id", tagDto.getId())
+ .add("creator", tagDto.getCreator())
+ .add("name", tagDto.getName())
+ .add("color", tagDto.getColor());
+
+ // Add ACL
+ AclUtil.addAcls(tag, id, getTargetIdList(null));
+
+ return Response.ok().entity(tag.build()).build();
}
-
+
/**
* Creates a new tag.
*
* @param name Name
+ * @param color Color
+ * @param parentId Parent ID
* @return Response
*/
@PUT
@@ -113,30 +129,39 @@ public class TagResource extends BaseResource {
throw new ClientException("SpacesNotAllowed", "Spaces are not allowed in tag name");
}
- // Get the tag
- TagDao tagDao = new TagDao();
- Tag tag = tagDao.getByName(principal.getId(), name);
- if (tag != null) {
- throw new ClientException("AlreadyExistingTag", MessageFormat.format("Tag already exists: {0}", name));
- }
-
// Check the parent
if (StringUtils.isEmpty(parentId)) {
parentId = null;
} else {
- Tag parentTag = tagDao.getByTagId(principal.getId(), parentId);
- if (parentTag == null) {
+ AclDao aclDao = new AclDao();
+ if (!aclDao.checkPermission(parentId, PermType.READ, getTargetIdList(null))) {
throw new ClientException("ParentNotFound", MessageFormat.format("Parent not found: {0}", parentId));
}
}
// Create the tag
- tag = new Tag();
+ TagDao tagDao = new TagDao();
+ Tag tag = new Tag();
tag.setName(name);
tag.setColor(color);
tag.setUserId(principal.getId());
tag.setParentId(parentId);
String id = tagDao.create(tag, principal.getId());
+
+ // Create read ACL
+ AclDao aclDao = new AclDao();
+ Acl acl = new Acl();
+ acl.setPerm(PermType.READ);
+ acl.setSourceId(id);
+ acl.setTargetId(principal.getId());
+ aclDao.create(acl, principal.getId());
+
+ // Create write ACL
+ acl = new Acl();
+ acl.setPerm(PermType.WRITE);
+ acl.setSourceId(id);
+ acl.setTargetId(principal.getId());
+ aclDao.create(acl, principal.getId());
JsonObjectBuilder response = Json.createObjectBuilder()
.add("id", id);
@@ -147,6 +172,8 @@ public class TagResource extends BaseResource {
* Update a tag.
*
* @param name Name
+ * @param color Color
+ * @param parentId Parent ID
* @return Response
*/
@POST
@@ -169,30 +196,24 @@ public class TagResource extends BaseResource {
throw new ClientException("SpacesNotAllowed", "Spaces are not allowed in tag name");
}
- // Get the tag
- TagDao tagDao = new TagDao();
- Tag tag = tagDao.getByTagId(principal.getId(), id);
- if (tag == null) {
- throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", id));
+ // Check permission
+ AclDao aclDao = new AclDao();
+ if (!aclDao.checkPermission(id, PermType.WRITE, getTargetIdList(null))) {
+ throw new NotFoundException();
}
// Check the parent
if (StringUtils.isEmpty(parentId)) {
parentId = null;
} else {
- Tag parentTag = tagDao.getByTagId(principal.getId(), parentId);
- if (parentTag == null) {
+ if (!aclDao.checkPermission(parentId, PermType.READ, getTargetIdList(null))) {
throw new ClientException("ParentNotFound", MessageFormat.format("Parent not found: {0}", parentId));
}
}
- // Check for name duplicate
- Tag tagDuplicate = tagDao.getByName(principal.getId(), name);
- if (tagDuplicate != null && !tagDuplicate.getId().equals(id)) {
- throw new ClientException("AlreadyExistingTag", MessageFormat.format("Tag already exists: {0}", name));
- }
-
// Update the tag
+ TagDao tagDao = new TagDao();
+ Tag tag = tagDao.getById(id);
if (!StringUtils.isEmpty(name)) {
tag.setName(name);
}
@@ -212,26 +233,26 @@ public class TagResource extends BaseResource {
/**
* Delete a tag.
*
- * @param tagId Tag ID
+ * @param id Tag ID
* @return Response
*/
@DELETE
@Path("{id: [a-z0-9\\-]+}")
public Response delete(
- @PathParam("id") String tagId) {
+ @PathParam("id") String id) {
if (!authenticate()) {
throw new ForbiddenClientException();
}
// Get the tag
- TagDao tagDao = new TagDao();
- Tag tag = tagDao.getByTagId(principal.getId(), tagId);
- if (tag == null) {
- throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", tagId));
+ AclDao aclDao = new AclDao();
+ if (!aclDao.checkPermission(id, PermType.WRITE, getTargetIdList(null))) {
+ throw new NotFoundException();
}
// Delete the tag
- tagDao.delete(tagId, principal.getId());
+ TagDao tagDao = new TagDao();
+ tagDao.delete(id, principal.getId());
// Always return OK
JsonObjectBuilder response = Json.createObjectBuilder()
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java
index 1c12c419..433812ec 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java
@@ -99,7 +99,7 @@ public class UserResource extends BaseResource {
user.setPassword(password);
user.setEmail(email);
user.setStorageQuota(storageQuota);
- user.setStorageCurrent(0l);
+ user.setStorageCurrent(0L);
try {
user.setPrivateKey(EncryptionUtil.generatePrivateKey());
} catch (NoSuchAlgorithmException e) {
@@ -678,7 +678,7 @@ public class UserResource extends BaseResource {
UserDao userDao = new UserDao();
User user = userDao.getActiveByUsername(principal.getName());
user.setTotpKey(key.getKey());
- user = userDao.update(user, principal.getId());
+ userDao.update(user, principal.getId());
JsonObjectBuilder response = Json.createObjectBuilder()
.add("secret", key.getKey());
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/VocabularyResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/VocabularyResource.java
index 479d86d2..06ba5ee8 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/VocabularyResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/VocabularyResource.java
@@ -1,26 +1,18 @@
package com.sismics.docs.rest.resource;
-import java.util.List;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObjectBuilder;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-
import com.sismics.docs.core.dao.jpa.VocabularyDao;
import com.sismics.docs.core.model.jpa.Vocabulary;
import com.sismics.docs.rest.constant.BaseFunction;
import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.util.ValidationUtil;
+import javax.json.Json;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObjectBuilder;
+import javax.ws.rs.*;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
/**
* Vocabulary REST resources.
*
@@ -58,7 +50,7 @@ public class VocabularyResource extends BaseResource {
*
* @param name Name
* @param value Value
- * @param order Order
+ * @param orderStr Order
* @return Response
*/
@PUT
@@ -95,10 +87,11 @@ public class VocabularyResource extends BaseResource {
/**
* Update a vocabulary.
- *
+ *
+ * @param id ID
* @param name Name
* @param value Value
- * @param order Order
+ * @param orderStr Order
* @return Response
*/
@POST
@@ -127,7 +120,7 @@ public class VocabularyResource extends BaseResource {
VocabularyDao vocabularyDao = new VocabularyDao();
Vocabulary vocabulary = vocabularyDao.getById(id);
if (vocabulary == null) {
- return Response.status(Status.NOT_FOUND).build();
+ throw new NotFoundException();
}
// Update the vocabulary
@@ -169,7 +162,7 @@ public class VocabularyResource extends BaseResource {
VocabularyDao vocabularyDao = new VocabularyDao();
Vocabulary vocabulary = vocabularyDao.getById(id);
if (vocabulary == null) {
- return Response.status(Status.NOT_FOUND).build();
+ throw new NotFoundException();
}
// Delete the vocabulary
diff --git a/docs-web/src/main/webapp/src/app/docs/app.js b/docs-web/src/main/webapp/src/app/docs/app.js
index 62e6976a..8c9d4fca 100644
--- a/docs-web/src/main/webapp/src/app/docs/app.js
+++ b/docs-web/src/main/webapp/src/app/docs/app.js
@@ -13,36 +13,55 @@ angular.module('docs',
* Configuring modules.
*/
.config(function($stateProvider, $httpProvider, RestangularProvider) {
+
// Configuring UI Router
$stateProvider
- .state('main', {
- url: '',
- views: {
- 'page': {
- templateUrl: 'partial/docs/main.html',
- controller: 'Main'
+ .state('main', {
+ url: '',
+ views: {
+ 'page': {
+ templateUrl: 'partial/docs/main.html',
+ controller: 'Main'
+ }
}
- }
- })
- .state('tag', {
- url: '/tag',
- views: {
- 'page': {
- templateUrl: 'partial/docs/tag.html',
- controller: 'Tag'
+ })
+ .state('tag', {
+ url: '/tag',
+ abstract: true,
+ views: {
+ 'page': {
+ templateUrl: 'partial/docs/tag.html',
+ controller: 'Tag'
+ }
}
- }
- })
- .state('settings', {
- url: '/settings',
- abstract: true,
- views: {
- 'page': {
- templateUrl: 'partial/docs/settings.html',
- controller: 'Settings'
+ })
+ .state('tag.default', {
+ url: '',
+ views: {
+ 'tag': {
+ templateUrl: 'partial/docs/tag.default.html'
+ }
}
- }
- })
+ })
+ .state('tag.edit', {
+ url: '/:id',
+ views: {
+ 'tag': {
+ templateUrl: 'partial/docs/tag.edit.html',
+ controller: 'TagEdit'
+ }
+ }
+ })
+ .state('settings', {
+ url: '/settings',
+ abstract: true,
+ views: {
+ 'page': {
+ templateUrl: 'partial/docs/settings.html',
+ controller: 'Settings'
+ }
+ }
+ })
.state('settings.default', {
url: '',
views: {
@@ -106,70 +125,70 @@ angular.module('docs',
}
}
})
- .state('settings.user.edit', {
- url: '/edit/:username',
- views: {
- 'user': {
- templateUrl: 'partial/docs/settings.user.edit.html',
- controller: 'SettingsUserEdit'
- }
+ .state('settings.user.edit', {
+ url: '/edit/:username',
+ views: {
+ 'user': {
+ templateUrl: 'partial/docs/settings.user.edit.html',
+ controller: 'SettingsUserEdit'
}
- })
- .state('settings.user.add', {
- url: '/add',
- views: {
- 'user': {
- templateUrl: 'partial/docs/settings.user.edit.html',
- controller: 'SettingsUserEdit'
- }
+ }
+ })
+ .state('settings.user.add', {
+ url: '/add',
+ views: {
+ 'user': {
+ templateUrl: 'partial/docs/settings.user.edit.html',
+ controller: 'SettingsUserEdit'
}
- })
+ }
+ })
.state('settings.group', {
- url: '/group',
- views: {
- 'settings': {
- templateUrl: 'partial/docs/settings.group.html',
- controller: 'SettingsGroup'
- }
+ url: '/group',
+ views: {
+ 'settings': {
+ templateUrl: 'partial/docs/settings.group.html',
+ controller: 'SettingsGroup'
}
- })
- .state('settings.group.edit', {
- url: '/edit/:name',
- views: {
- 'group': {
- templateUrl: 'partial/docs/settings.group.edit.html',
- controller: 'SettingsGroupEdit'
- }
- }
- })
- .state('settings.group.add', {
- url: '/add',
- views: {
- 'group': {
- templateUrl: 'partial/docs/settings.group.edit.html',
- controller: 'SettingsGroupEdit'
- }
- }
- })
- .state('settings.vocabulary', {
- url: '/vocabulary',
- views: {
- 'settings': {
- templateUrl: 'partial/docs/settings.vocabulary.html',
- controller: 'SettingsVocabulary'
}
- }
- })
- .state('document', {
- url: '/document',
- abstract: true,
- views: {
- 'page': {
- templateUrl: 'partial/docs/document.html',
- controller: 'Document'
+ })
+ .state('settings.group.edit', {
+ url: '/edit/:name',
+ views: {
+ 'group': {
+ templateUrl: 'partial/docs/settings.group.edit.html',
+ controller: 'SettingsGroupEdit'
+ }
}
- }
- })
+ })
+ .state('settings.group.add', {
+ url: '/add',
+ views: {
+ 'group': {
+ templateUrl: 'partial/docs/settings.group.edit.html',
+ controller: 'SettingsGroupEdit'
+ }
+ }
+ })
+ .state('settings.vocabulary', {
+ url: '/vocabulary',
+ views: {
+ 'settings': {
+ templateUrl: 'partial/docs/settings.vocabulary.html',
+ controller: 'SettingsVocabulary'
+ }
+ }
+ })
+ .state('document', {
+ url: '/document',
+ abstract: true,
+ views: {
+ 'page': {
+ templateUrl: 'partial/docs/document.html',
+ controller: 'Document'
+ }
+ }
+ })
.state('document.default', {
url: '',
views: {
@@ -179,17 +198,17 @@ angular.module('docs',
}
}
})
- .state('document.default.search', {
- url: '/search/:search'
- })
- .state('document.default.file', {
- url: '/file/:fileId',
- views: {
- 'file': {
- controller: 'FileView'
- }
+ .state('document.default.search', {
+ url: '/search/:search'
+ })
+ .state('document.default.file', {
+ url: '/file/:fileId',
+ views: {
+ 'file': {
+ controller: 'FileView'
}
- })
+ }
+ })
.state('document.add', {
url: '/add?files',
views: {
@@ -218,59 +237,68 @@ angular.module('docs',
}
}
})
- .state('document.view.content', {
- url: '/content',
- views: {
- 'tab': {
- templateUrl: 'partial/docs/document.view.content.html',
- controller: 'DocumentViewContent'
- }
+ .state('document.view.content', {
+ url: '/content',
+ views: {
+ 'tab': {
+ templateUrl: 'partial/docs/document.view.content.html',
+ controller: 'DocumentViewContent'
}
- })
- .state('document.view.content.file', {
- url: '/file/:fileId',
- views: {
- 'file': {
- controller: 'FileView'
- }
- }
- })
- .state('document.view.permissions', {
- url: '/permissions',
- views: {
- 'tab': {
- templateUrl: 'partial/docs/document.view.permissions.html',
- controller: 'DocumentViewPermissions'
- }
- }
- })
- .state('document.view.activity', {
- url: '/activity',
- views: {
- 'tab': {
- templateUrl: 'partial/docs/document.view.activity.html',
- controller: 'DocumentViewActivity'
- }
- }
- })
- .state('login', {
- url: '/login',
- views: {
- 'page': {
- templateUrl: 'partial/docs/login.html',
- controller: 'Login'
}
- }
- })
- .state('user', {
- url: '/user',
- views: {
- 'page': {
- templateUrl: 'partial/docs/usergroup.html',
- controller: 'UserGroup'
+ })
+ .state('document.view.content.file', {
+ url: '/file/:fileId',
+ views: {
+ 'file': {
+ controller: 'FileView'
+ }
}
- }
- })
+ })
+ .state('document.view.permissions', {
+ url: '/permissions',
+ views: {
+ 'tab': {
+ templateUrl: 'partial/docs/document.view.permissions.html',
+ controller: 'DocumentViewPermissions'
+ }
+ }
+ })
+ .state('document.view.activity', {
+ url: '/activity',
+ views: {
+ 'tab': {
+ templateUrl: 'partial/docs/document.view.activity.html',
+ controller: 'DocumentViewActivity'
+ }
+ }
+ })
+ .state('login', {
+ url: '/login',
+ views: {
+ 'page': {
+ templateUrl: 'partial/docs/login.html',
+ controller: 'Login'
+ }
+ }
+ })
+ .state('user', {
+ url: '/user',
+ abstract: true,
+ views: {
+ 'page': {
+ templateUrl: 'partial/docs/usergroup.html',
+ controller: 'UserGroup'
+ }
+ }
+ })
+ .state('user.default', {
+ url: '',
+ views: {
+ 'sub': {
+ templateUrl: 'partial/docs/usergroup.default.html'
+ }
+ }
+ })
.state('user.profile', {
url: '/:username',
views: {
@@ -280,15 +308,24 @@ angular.module('docs',
}
}
})
- .state('group', {
- url: '/group',
- views: {
- 'page': {
- templateUrl: 'partial/docs/usergroup.html',
- controller: 'UserGroup'
+ .state('group', {
+ url: '/group',
+ abstract: true,
+ views: {
+ 'page': {
+ templateUrl: 'partial/docs/usergroup.html',
+ controller: 'UserGroup'
+ }
}
- }
- })
+ })
+ .state('group.default', {
+ url: '',
+ views: {
+ 'sub': {
+ templateUrl: 'partial/docs/usergroup.default.html'
+ }
+ }
+ })
.state('group.profile', {
url: '/:name',
views: {
@@ -298,7 +335,6 @@ angular.module('docs',
}
}
});
-
// Configuring Restangular
RestangularProvider.setBaseUrl('../api');
diff --git a/docs-web/src/main/webapp/src/app/docs/controller/document/DocumentViewPermissions.js b/docs-web/src/main/webapp/src/app/docs/controller/document/DocumentViewPermissions.js
index 80231f2f..bfbc5493 100644
--- a/docs-web/src/main/webapp/src/app/docs/controller/document/DocumentViewPermissions.js
+++ b/docs-web/src/main/webapp/src/app/docs/controller/document/DocumentViewPermissions.js
@@ -3,95 +3,5 @@
/**
* Document view permissions controller.
*/
-angular.module('docs').controller('DocumentViewPermissions', function ($scope, $stateParams, Restangular, $q) {
- // Watch for ACLs change and group them for easy displaying
- $scope.$watch('document.acls', function(acls) {
- $scope.acls = _.groupBy(acls, function(acl) {
- return acl.id;
- });
- });
-
- // Initialize add ACL
- $scope.acl = { perm: 'READ' };
-
- /**
- * Delete an ACL.
- */
- $scope.deleteAcl = function(acl) {
- Restangular.one('acl/' + $stateParams.id + '/' + acl.perm + '/' + acl.id, null).remove().then(function () {
- $scope.document.acls = _.reject($scope.document.acls, function(s) {
- return angular.equals(acl, s);
- });
- });
- };
-
- /**
- * Add an ACL.
- */
- $scope.addAcl = function() {
- // Compute ACLs to add
- $scope.acl.source = $stateParams.id;
- var acls = [];
- if ($scope.acl.perm == 'READWRITE') {
- acls = [{
- source: $stateParams.id,
- target: $scope.acl.target.name,
- perm: 'READ',
- type: $scope.acl.target.type
- }, {
- source: $stateParams.id,
- target: $scope.acl.target.name,
- perm: 'WRITE',
- type: $scope.acl.target.type
- }];
- } else {
- acls = [{
- source: $stateParams.id,
- target: $scope.acl.target.name,
- perm: $scope.acl.perm,
- type: $scope.acl.target.type
- }];
- }
-
- // Add ACLs
- _.each(acls, function(acl) {
- Restangular.one('acl').put(acl).then(function(acl) {
- if (_.isUndefined(acl.id)) {
- return;
- }
- $scope.document.acls.push(acl);
- $scope.document.acls = angular.copy($scope.document.acls);
- });
- });
-
- // Reset form
- $scope.acl = { perm: 'READ' };
- };
-
- /**
- * Auto-complete on ACL target.
- */
- $scope.getTargetAclTypeahead = function($viewValue) {
- var deferred = $q.defer();
- Restangular.one('acl/target/search')
- .get({
- search: $viewValue
- }).then(function(data) {
- var output = [];
-
- // Add the type to use later
- output.push.apply(output, _.map(data.users, function(user) {
- user.type = 'USER';
- return user;
- }));
- output.push.apply(output, _.map(data.groups, function(group) {
- group.type = 'GROUP';
- return group;
- }));
-
- // Send the data to the typeahead directive
- deferred.resolve(output, true);
- });
- return deferred.promise;
- };
+angular.module('docs').controller('DocumentViewPermissions', function() {
});
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/app/docs/controller/tag/Tag.js b/docs-web/src/main/webapp/src/app/docs/controller/tag/Tag.js
index 53b44ea1..acf3b5b5 100644
--- a/docs-web/src/main/webapp/src/app/docs/controller/tag/Tag.js
+++ b/docs-web/src/main/webapp/src/app/docs/controller/tag/Tag.js
@@ -3,37 +3,14 @@
/**
* Tag controller.
*/
-angular.module('docs').controller('Tag', function($scope, $dialog, Tag, Restangular) {
+angular.module('docs').controller('Tag', function($scope, $dialog, Restangular) {
$scope.tag = { name: '', color: '#3a87ad' };
// Retrieve tags
- Tag.tags().then(function(data) {
+ Restangular.one('tag/list').get().then(function(data) {
$scope.tags = data.tags;
});
- // Retrieve tag stats
- Restangular.one('tag/stats').get().then(function(data) {
- $scope.stats = data.stats;
- });
-
- /**
- * Returns total number of document from tag stats.
- */
- $scope.getStatCount = function() {
- return _.reduce($scope.stats, function(memo, stat) {
- return memo + stat.count
- }, 0);
- };
-
- /**
- * Validate a tag name for duplicate.
- */
- $scope.validateDuplicate = function(name) {
- return !_.find($scope.tags, function(tag) {
- return tag.name == name;
- });
- };
-
/**
* Add a tag.
*/
@@ -71,15 +48,6 @@ angular.module('docs').controller('Tag', function($scope, $dialog, Tag, Restangu
*/
$scope.updateTag = function(tag) {
// Update the server
- return Restangular.one('tag', tag.id).post('', tag).then(function () {
- // Update the stat object
- var stat = _.find($scope.stats, function (t) {
- return tag.id == t.id;
- });
-
- if (stat) {
- _.extend(stat, tag);
- }
- });
+ return Restangular.one('tag', tag.id).post('', tag);
};
});
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/app/docs/controller/tag/TagEdit.js b/docs-web/src/main/webapp/src/app/docs/controller/tag/TagEdit.js
new file mode 100644
index 00000000..1910309d
--- /dev/null
+++ b/docs-web/src/main/webapp/src/app/docs/controller/tag/TagEdit.js
@@ -0,0 +1,10 @@
+'use strict';
+
+/**
+ * Tag edit controller.
+ */
+angular.module('docs').controller('TagEdit', function($scope, $stateParams, Restangular) {
+ Restangular.one('tag', $stateParams.id).get().then(function(data) {
+ $scope.tag = data;
+ })
+});
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/app/docs/directive/AclEdit.js b/docs-web/src/main/webapp/src/app/docs/directive/AclEdit.js
new file mode 100644
index 00000000..0e53b207
--- /dev/null
+++ b/docs-web/src/main/webapp/src/app/docs/directive/AclEdit.js
@@ -0,0 +1,112 @@
+'use strict';
+
+/**
+ * ACL edit directive.
+ */
+angular.module('docs').directive('aclEdit', function() {
+ return {
+ restrict: 'E',
+ templateUrl: 'partial/docs/directive.acledit.html',
+ replace: true,
+ scope: {
+ source: '=',
+ acls: '=',
+ writable: '=',
+ creator: '='
+ },
+ controller: function($scope, Restangular, $q) {
+ // Watch for ACLs change and group them for easy displaying
+ $scope.$watch('acls', function(acls) {
+ $scope.groupedAcls = _.groupBy(acls, function(acl) {
+ return acl.id;
+ });
+ });
+
+ // Initialize add ACL
+ $scope.acl = { perm: 'READ' };
+
+ /**
+ * Delete an ACL.
+ */
+ $scope.deleteAcl = function(acl) {
+ Restangular.one('acl/' + $scope.source + '/' + acl.perm + '/' + acl.id, null).remove().then(function () {
+ $scope.acls = _.reject($scope.acls, function(s) {
+ return angular.equals(acl, s);
+ });
+ });
+ };
+
+ /**
+ * Add an ACL.
+ */
+ $scope.addAcl = function() {
+ // Compute ACLs to add
+ $scope.acl.source = $scope.source;
+ var acls = [];
+ if ($scope.acl.perm == 'READWRITE') {
+ acls = [{
+ source: $scope.source,
+ target: $scope.acl.target.name,
+ perm: 'READ',
+ type: $scope.acl.target.type
+ }, {
+ source: $scope.source,
+ target: $scope.acl.target.name,
+ perm: 'WRITE',
+ type: $scope.acl.target.type
+ }];
+ } else {
+ acls = [{
+ source: $scope.source,
+ target: $scope.acl.target.name,
+ perm: $scope.acl.perm,
+ type: $scope.acl.target.type
+ }];
+ }
+
+ // Add ACLs
+ _.each(acls, function(acl) {
+ Restangular.one('acl').put(acl).then(function(acl) {
+ if (_.isUndefined(acl.id)) {
+ return;
+ }
+ $scope.acls.push(acl);
+ $scope.acls = angular.copy($scope.acls);
+ });
+ });
+
+ // Reset form
+ $scope.acl = { perm: 'READ' };
+ };
+
+ /**
+ * Auto-complete on ACL target.
+ */
+ $scope.getTargetAclTypeahead = function($viewValue) {
+ var deferred = $q.defer();
+ Restangular.one('acl/target/search')
+ .get({
+ search: $viewValue
+ }).then(function(data) {
+ var output = [];
+
+ // Add the type to use later
+ output.push.apply(output, _.map(data.users, function(user) {
+ user.type = 'USER';
+ return user;
+ }));
+ output.push.apply(output, _.map(data.groups, function(group) {
+ group.type = 'GROUP';
+ return group;
+ }));
+
+ // Send the data to the typeahead directive
+ deferred.resolve(output, true);
+ });
+ return deferred.promise;
+ };
+ },
+ link: function(scope, element, attr, ctrl) {
+ }
+ }
+});
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/app/docs/directive/SelectTag.js b/docs-web/src/main/webapp/src/app/docs/directive/SelectTag.js
index c0753325..d61ee60e 100644
--- a/docs-web/src/main/webapp/src/app/docs/directive/SelectTag.js
+++ b/docs-web/src/main/webapp/src/app/docs/directive/SelectTag.js
@@ -13,9 +13,9 @@ angular.module('docs').directive('selectTag', function() {
ref: '@',
ngDisabled: '='
},
- controller: function($scope, Tag) {
+ controller: function($scope, Restangular) {
// Retrieve tags
- Tag.tags().then(function(data) {
+ Restangular.one('tag/list').get().then(function(data) {
$scope.allTags = data.tags;
});
@@ -48,7 +48,7 @@ angular.module('docs').directive('selectTag', function() {
if ($event) {
$event.preventDefault();
}
- }
+ };
/**
* Remove a tag.
diff --git a/docs-web/src/main/webapp/src/app/docs/service/Tag.js b/docs-web/src/main/webapp/src/app/docs/service/Tag.js
deleted file mode 100644
index 04a94687..00000000
--- a/docs-web/src/main/webapp/src/app/docs/service/Tag.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-
-/**
- * Tag service.
- */
-angular.module('docs').factory('Tag', function(Restangular) {
- var tags = null;
-
- return {
- /**
- * Returns tags.
- * @param force If true, force reloading data
- */
- tags: function(force) {
- return Restangular.one('tag/list').get();
- }
- }
-});
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/index.html b/docs-web/src/main/webapp/src/index.html
index 3924d6e7..5b92a0b1 100644
--- a/docs-web/src/main/webapp/src/index.html
+++ b/docs-web/src/main/webapp/src/index.html
@@ -55,6 +55,7 @@
+
@@ -73,7 +74,6 @@
-
@@ -84,6 +84,7 @@
+
diff --git a/docs-web/src/main/webapp/src/partial/docs/directive.acledit.html b/docs-web/src/main/webapp/src/partial/docs/directive.acledit.html
new file mode 100644
index 00000000..7e436e50
--- /dev/null
+++ b/docs-web/src/main/webapp/src/partial/docs/directive.acledit.html
@@ -0,0 +1,61 @@
+
+
+
+ For |
+ Permission |
+
+
+
+ |
+
+
+ {{ a.perm }}
+
+
+ |
+
+
+
+
+
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/partial/docs/document.view.permissions.html b/docs-web/src/main/webapp/src/partial/docs/document.view.permissions.html
index 07160373..0c611570 100644
--- a/docs-web/src/main/webapp/src/partial/docs/document.view.permissions.html
+++ b/docs-web/src/main/webapp/src/partial/docs/document.view.permissions.html
@@ -1,59 +1,4 @@
-
-
- For |
- Permission |
-
-
-
- |
-
-
- {{ a.perm }}
-
-
- |
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/partial/docs/tag.default.html b/docs-web/src/main/webapp/src/partial/docs/tag.default.html
new file mode 100644
index 00000000..dee44dec
--- /dev/null
+++ b/docs-web/src/main/webapp/src/partial/docs/tag.default.html
@@ -0,0 +1,6 @@
+Tags
+Tags are labels associated to documents.
+A document can be tagged by multiple tags, and a tag can be applied to multiple documents.
+Using the button, you can edit permissions on a tag.
+If a tag can be read by another user or group, associated documents can also be read by those people.
+For example, tag your company documents with a tag MyCompany and add the permission Read to a group employees
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/partial/docs/tag.edit.html b/docs-web/src/main/webapp/src/partial/docs/tag.edit.html
new file mode 100644
index 00000000..90f56a22
--- /dev/null
+++ b/docs-web/src/main/webapp/src/partial/docs/tag.edit.html
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/partial/docs/tag.html b/docs-web/src/main/webapp/src/partial/docs/tag.html
index 733ab8ee..576a8bfa 100644
--- a/docs-web/src/main/webapp/src/partial/docs/tag.html
+++ b/docs-web/src/main/webapp/src/partial/docs/tag.html
@@ -5,10 +5,9 @@
+ ng-maxlength="36" required ng-model="tag.name" ui-validate="{ space: '!$value || $value.indexOf(\' \') == -1' }">
Add
- This tag already exists
Space are not allowed
@@ -31,22 +30,15 @@
|
- |
+ |
+ |
-
-
{{ tags.length }} tag{{ tags.length > 1 ? 's' : '' }}
-
- - {{ stat.name }} {{ stat.count }}
-
-
-
-
-
-
![](img/loader.gif)
+
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/partial/docs/usergroup.default.html b/docs-web/src/main/webapp/src/partial/docs/usergroup.default.html
new file mode 100644
index 00000000..5899b461
--- /dev/null
+++ b/docs-web/src/main/webapp/src/partial/docs/usergroup.default.html
@@ -0,0 +1,2 @@
+Users & Groups
+Here you can view informations about users and groups.
\ No newline at end of file
diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestAclResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestAclResource.java
index bace64ef..e693ea05 100644
--- a/docs-web/src/test/java/com/sismics/docs/rest/TestAclResource.java
+++ b/docs-web/src/test/java/com/sismics/docs/rest/TestAclResource.java
@@ -71,7 +71,7 @@ public class TestAclResource extends BaseJerseyTest {
String acl2Id = json.getString("id");
// Add an ACL WRITE for acl2 with acl1
- json = target().path("/acl").request()
+ target().path("/acl").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acl1Token)
.put(Entity.form(new Form()
.param("source", document1Id)
@@ -80,7 +80,7 @@ public class TestAclResource extends BaseJerseyTest {
.param("type", "USER")), JsonObject.class);
// Add an ACL WRITE for acl2 with acl1 (again)
- json = target().path("/acl").request()
+ target().path("/acl").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acl1Token)
.put(Entity.form(new Form()
.param("source", document1Id)
@@ -99,7 +99,7 @@ public class TestAclResource extends BaseJerseyTest {
String aclGroup2Id = json.getString("id");
// Add an ACL WRITE for aclGroup2 with acl1
- json = target().path("/acl").request()
+ target().path("/acl").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acl1Token)
.put(Entity.form(new Form()
.param("source", document1Id)
@@ -234,9 +234,9 @@ public class TestAclResource extends BaseJerseyTest {
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acl1Token)
.get(JsonObject.class);
JsonArray users = json.getJsonArray("users");
- Assert.assertEquals(2, users.size());
+ Assert.assertTrue(users.size() > 0);
JsonArray groups = json.getJsonArray("groups");
- Assert.assertEquals(1, groups.size());
+ Assert.assertTrue(groups.size() > 0);
// Search target list (admin)
json = target().path("/acl/target/search")
@@ -249,4 +249,179 @@ public class TestAclResource extends BaseJerseyTest {
groups = json.getJsonArray("groups");
Assert.assertEquals(1, groups.size());
}
+
+ @Test
+ public void testAclTags() {
+ // Login acltag1
+ clientUtil.createUser("acltag1");
+ String acltag1Token = clientUtil.login("acltag1");
+
+ // Login acltag2
+ clientUtil.createUser("acltag2");
+ String acltag2Token = clientUtil.login("acltag2");
+
+ // Create tag1 with acltag1
+ JsonObject json = target().path("/tag").request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag1Token)
+ .put(Entity.form(new Form()
+ .param("name", "AclTag1")
+ .param("color", "#ff0000")), JsonObject.class);
+ String tag1Id = json.getString("id");
+ Assert.assertNotNull(tag1Id);
+
+ // Create document1 with acltag1 tagged with tag1
+ json = target().path("/document").request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag1Token)
+ .put(Entity.form(new Form()
+ .param("title", "My super document 1")
+ .param("tags", tag1Id)
+ .param("language", "eng")), JsonObject.class);
+ String document1Id = json.getString("id");
+
+ // acltag2 cannot see document1
+ Response response = target().path("/document/" + document1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get();
+ Assert.assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+
+ // acltag2 cannot see any tag
+ json = target().path("/tag/list").request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get(JsonObject.class);
+ JsonArray tags = json.getJsonArray("tags");
+ Assert.assertEquals(0, tags.size());
+
+ // acltag2 cannot see tag1
+ response = target().path("/tag/" + tag1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get();
+ Assert.assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+
+ // acltag2 cannot see any document
+ json = target().path("/document/list")
+ .queryParam("sort_column", 3)
+ .queryParam("asc", true)
+ .request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get(JsonObject.class);
+ JsonArray documents = json.getJsonArray("documents");
+ Assert.assertEquals(0, documents.size());
+
+ // acltag2 cannot edit tag1
+ response = target().path("/tag/" + tag1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .post(Entity.form(new Form()
+ .param("name", "AclTag1")
+ .param("color", "#ff0000")));
+ Assert.assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+
+ // acltag2 cannot edit document1
+ response = target().path("/document/" + document1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .post(Entity.form(new Form()
+ .param("title", "My super document 1")
+ .param("tags", tag1Id)
+ .param("language", "eng")));
+ Assert.assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
+
+ // Add an ACL READ for acltag2 with acltag1 on tag1
+ target().path("/acl").request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag1Token)
+ .put(Entity.form(new Form()
+ .param("source", tag1Id)
+ .param("perm", "READ")
+ .param("target", "acltag2")
+ .param("type", "USER")), JsonObject.class);
+
+ // acltag2 can see tag1
+ json = target().path("/tag/" + tag1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get(JsonObject.class);
+ Assert.assertFalse(json.getBoolean("writable"));
+ Assert.assertEquals(3, json.getJsonArray("acls").size());
+
+ // acltag2 still cannot edit tag1
+ response = target().path("/tag/" + tag1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .post(Entity.form(new Form()
+ .param("name", "AclTag1")
+ .param("color", "#ff0000")));
+ Assert.assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+
+ // acltag2 still cannot edit document1
+ response = target().path("/document/" + document1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .post(Entity.form(new Form()
+ .param("title", "My super document 1")
+ .param("tags", tag1Id)
+ .param("language", "eng")));
+ Assert.assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
+
+ // acltag2 can see document1 with tag1 (non-writable)
+ json = target().path("/document/" + document1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get(JsonObject.class);
+ tags = json.getJsonArray("tags");
+ Assert.assertEquals(1, tags.size());
+ Assert.assertFalse(json.getBoolean("writable"));
+ Assert.assertEquals(tag1Id, tags.getJsonObject(0).getString("id"));
+
+ // acltag2 can see tag1
+ json = target().path("/tag/list").request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get(JsonObject.class);
+ tags = json.getJsonArray("tags");
+ Assert.assertEquals(1, tags.size());
+ Assert.assertEquals(tag1Id, tags.getJsonObject(0).getString("id"));
+
+ // acltag2 can see exactly one document
+ json = target().path("/document/list")
+ .queryParam("sort_column", 3)
+ .queryParam("asc", true)
+ .request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get(JsonObject.class);
+ documents = json.getJsonArray("documents");
+ Assert.assertEquals(1, documents.size());
+
+ // Add an ACL WRITE for acltag2 with acltag1 on tag1
+ target().path("/acl").request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag1Token)
+ .put(Entity.form(new Form()
+ .param("source", tag1Id)
+ .param("perm", "WRITE")
+ .param("target", "acltag2")
+ .param("type", "USER")), JsonObject.class);
+
+ // acltag2 can see document1 with tag1 (writable)
+ json = target().path("/document/" + document1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get(JsonObject.class);
+ tags = json.getJsonArray("tags");
+ Assert.assertEquals(1, tags.size());
+ Assert.assertTrue(json.getBoolean("writable"));
+ Assert.assertEquals(tag1Id, tags.getJsonObject(0).getString("id"));
+
+ // acltag2 can see and edit tag1
+ json = target().path("/tag/" + tag1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .get(JsonObject.class);
+ Assert.assertTrue(json.getBoolean("writable"));
+ Assert.assertEquals(4, json.getJsonArray("acls").size());
+
+ // acltag2 can edit tag1
+ target().path("/tag/" + tag1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .post(Entity.form(new Form()
+ .param("name", "AclTag1")
+ .param("color", "#ff0000")), JsonObject.class);
+
+ // acltag2 can edit document1
+ target().path("/document/" + document1Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
+ .post(Entity.form(new Form()
+ .param("title", "My super document 1")
+ .param("tags", tag1Id)
+ .param("language", "eng")), JsonObject.class);
+ }
}
\ No newline at end of file
diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestAppResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestAppResource.java
index 4a8df5b0..e8fc889c 100644
--- a/docs-web/src/test/java/com/sismics/docs/rest/TestAppResource.java
+++ b/docs-web/src/test/java/com/sismics/docs/rest/TestAppResource.java
@@ -2,11 +2,17 @@ package com.sismics.docs.rest;
import javax.json.JsonArray;
import javax.json.JsonObject;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import com.sismics.docs.core.constant.PermType;
+import com.sismics.docs.core.dao.jpa.AclDao;
+import com.sismics.util.context.ThreadLocalContext;
+import com.sismics.util.jpa.EMF;
import org.junit.Assert;
import org.junit.Test;
@@ -57,6 +63,35 @@ public class TestAppResource extends BaseJerseyTest {
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.post(Entity.form(new Form()));
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
+
+ // Create a tag
+ json = target().path("/tag").request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
+ .put(Entity.form(new Form()
+ .param("name", "Tag4")
+ .param("color", "#00ff00")), JsonObject.class);
+ String tagId = json.getString("id");
+
+ // Init transactional context
+ EntityManager em = EMF.get().createEntityManager();
+ ThreadLocalContext context = ThreadLocalContext.get();
+ context.setEntityManager(em);
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+
+ // Remove base ACLs
+ AclDao aclDao = new AclDao();
+ aclDao.delete(tagId, PermType.READ, "admin", "admin");
+ aclDao.delete(tagId, PermType.WRITE, "admin", "admin");
+ Assert.assertEquals(0, aclDao.getBySourceId(tagId).size());
+ tx.commit();
+
+ // Add base ACLs to tags
+ response = target().path("/app/batch/tag_acls").request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
+ .post(Entity.form(new Form()));
+ Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
+ Assert.assertEquals(2, aclDao.getBySourceId(tagId).size());
}
/**
diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java
index 4f7b4ee8..d507c74a 100644
--- a/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java
+++ b/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java
@@ -87,7 +87,7 @@ public class TestDocumentResource extends BaseJerseyTest {
Assert.assertNotNull(document2Id);
// Add a file
- String file1Id = null;
+ String file1Id;
try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "Einstein-Roosevelt-letter.png");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
@@ -103,7 +103,7 @@ public class TestDocumentResource extends BaseJerseyTest {
}
// Share this document
- json = target().path("/share").request()
+ target().path("/share").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
.put(Entity.form(new Form().param("id", document1Id)), JsonObject.class);
@@ -148,7 +148,7 @@ public class TestDocumentResource extends BaseJerseyTest {
Assert.assertNotNull(document3Id);
// Add a file
- String file3Id = null;
+ String file3Id;
try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "Einstein-Roosevelt-letter.png");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
@@ -393,7 +393,7 @@ public class TestDocumentResource extends BaseJerseyTest {
Assert.assertNotNull(document1Id);
// Add a PDF file
- String file1Id = null;
+ String file1Id;
try (InputStream is = Resources.getResource("file/document.odt").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "document.odt");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
@@ -452,7 +452,7 @@ public class TestDocumentResource extends BaseJerseyTest {
Assert.assertNotNull(document1Id);
// Add a PDF file
- String file1Id = null;
+ String file1Id;
try (InputStream is = Resources.getResource("file/document.docx").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "document.docx");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
@@ -511,7 +511,7 @@ public class TestDocumentResource extends BaseJerseyTest {
Assert.assertNotNull(document1Id);
// Add a PDF file
- String file1Id = null;
+ String file1Id;
try (InputStream is = Resources.getResource("file/wikipedia.pdf").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "wikipedia.pdf");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestGroupResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestGroupResource.java
index c37ad04c..1d5d37a9 100644
--- a/docs-web/src/test/java/com/sismics/docs/rest/TestGroupResource.java
+++ b/docs-web/src/test/java/com/sismics/docs/rest/TestGroupResource.java
@@ -106,7 +106,7 @@ public class TestGroupResource extends BaseJerseyTest {
Assert.assertEquals(1, users.size());
// Add group1 to g112 (again)
- json = target().path("/group/g112").request()
+ target().path("/group/g112").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.put(Entity.form(new Form()
.param("username", "group1")), JsonObject.class);
@@ -145,7 +145,7 @@ public class TestGroupResource extends BaseJerseyTest {
Assert.assertEquals("group1", members.getString(0));
// Remove group1 from g12new
- json = target().path("/group/g12new/group1").request()
+ target().path("/group/g12new/group1").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.delete(JsonObject.class);
@@ -164,7 +164,7 @@ public class TestGroupResource extends BaseJerseyTest {
Assert.assertTrue(groupList.contains("g112"));
// Delete group g1
- json = target().path("/group/g1").request()
+ target().path("/group/g1").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.delete(JsonObject.class);
diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestTagResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestTagResource.java
index 597074da..3724d848 100644
--- a/docs-web/src/test/java/com/sismics/docs/rest/TestTagResource.java
+++ b/docs-web/src/test/java/com/sismics/docs/rest/TestTagResource.java
@@ -46,6 +46,17 @@ public class TestTagResource extends BaseJerseyTest {
.param("parent", tag3Id)), JsonObject.class);
String tag4Id = json.getString("id");
Assert.assertNotNull(tag4Id);
+
+ // Get the tag
+ json = target().path("/tag/" + tag4Id).request()
+ .cookie(TokenBasedSecurityFilter.COOKIE_NAME, tag1Token)
+ .get(JsonObject.class);
+ Assert.assertEquals("Tag4", json.getString("name"));
+ Assert.assertEquals("tag1", json.getString("creator"));
+ Assert.assertEquals("#00ff00", json.getString("color"));
+ Assert.assertTrue(json.getBoolean("writable"));
+ JsonArray acls = json.getJsonArray("acls");
+ Assert.assertEquals(2, acls.size());
// Create a tag with space (not allowed)
Response response = target().path("/tag").request()
@@ -55,7 +66,7 @@ public class TestTagResource extends BaseJerseyTest {
Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus()));
// Create a document
- json = target().path("/document").request()
+ target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, tag1Token)
.put(Entity.form(new Form()
.param("title", "My super document 1")
@@ -115,15 +126,6 @@ public class TestTagResource extends BaseJerseyTest {
Assert.assertEquals(1, tags.size());
Assert.assertEquals(tag4Id, tags.getJsonObject(0).getString("id"));
- // Get tag stats
- json = target().path("/tag/stats").request()
- .cookie(TokenBasedSecurityFilter.COOKIE_NAME, tag1Token)
- .get(JsonObject.class);
- JsonArray stats = json.getJsonArray("stats");
- Assert.assertTrue(stats.size() == 2);
- Assert.assertEquals(1, stats.getJsonObject(0).getInt("count"));
- Assert.assertEquals(1, stats.getJsonObject(1).getInt("count"));
-
// Get all tags
json = target().path("/tag/list").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, tag1Token)
@@ -150,7 +152,7 @@ public class TestTagResource extends BaseJerseyTest {
Assert.assertTrue(tags.size() > 0);
Assert.assertEquals("UpdatedName", tags.getJsonObject(1).getString("name"));
Assert.assertEquals("#0000ff", tags.getJsonObject(1).getString("color"));
- Assert.assertEquals(JsonValue.NULL, tags.getJsonObject(1).get("parent"));
+ Assert.assertNull(tags.getJsonObject(1).get("parent"));
// Deletes a tag
target().path("/tag/" + tag4Id).request()
diff --git a/docs-parent/pom.xml b/pom.xml
similarity index 98%
rename from docs-parent/pom.xml
rename to pom.xml
index 81362ea6..64c8b8e7 100644
--- a/docs-parent/pom.xml
+++ b/pom.xml
@@ -120,9 +120,9 @@
- ../docs-core
- ../docs-web-common
- ../docs-web
+ docs-core
+ docs-web-common
+ docs-web
@@ -374,8 +374,9 @@
org.apache.poi.xwpf.converter.pdf
${fr.opensagres.xdocreport.version}
-
-
+
+
+
com.twelvemonkeys.servlet
servlet
${com.twelvemonkeys.imageio.version}
@@ -389,7 +390,8 @@
-
+
+
com.twelvemonkeys.imageio
imageio-jpeg
${com.twelvemonkeys.imageio.version}