From c48eb7a0feace4dc25ef29babe49e7ae9a9bd691 Mon Sep 17 00:00:00 2001 From: jendib Date: Fri, 9 Aug 2013 00:21:11 +0200 Subject: [PATCH] Users administration (client) --- .../sismics/docs/core/constant/Constants.java | 2 +- .../src/main/resources/config.properties | 2 +- .../resources/db/update/dbupdate-003-0.sql | 1 + docs-parent/TODO | 2 +- docs-web/src/dev/resources/config.properties | 2 +- .../docs/rest/resource/UserResource.java | 12 +++- docs-web/src/main/webapp/js/app.js | 11 +++- .../main/webapp/js/controller/SettingsUser.js | 14 +++-- .../webapp/js/controller/SettingsUserEdit.js | 37 ++++++++++- .../webapp/partial/settings.user.edit.html | 63 +++++++++++++++---- .../main/webapp/partial/settings.user.html | 6 +- docs-web/src/main/webapp/style/main.less | 7 +++ docs-web/src/prod/resources/config.properties | 2 +- .../sismics/docs/rest/TestUserResource.java | 24 ++++++- 14 files changed, 153 insertions(+), 32 deletions(-) create mode 100644 docs-core/src/main/resources/db/update/dbupdate-003-0.sql diff --git a/docs-core/src/main/java/com/sismics/docs/core/constant/Constants.java b/docs-core/src/main/java/com/sismics/docs/core/constant/Constants.java index 5af396d1..bc7fe87f 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/constant/Constants.java +++ b/docs-core/src/main/java/com/sismics/docs/core/constant/Constants.java @@ -39,5 +39,5 @@ public class Constants { /** * Default generic user role. */ - public static final String DEFAULT_USER_ROLE = "admin"; + public static final String DEFAULT_USER_ROLE = "user"; } diff --git a/docs-core/src/main/resources/config.properties b/docs-core/src/main/resources/config.properties index d8b90e8b..53e95e79 100644 --- a/docs-core/src/main/resources/config.properties +++ b/docs-core/src/main/resources/config.properties @@ -1 +1 @@ -db.version=2 \ No newline at end of file +db.version=3 \ No newline at end of file diff --git a/docs-core/src/main/resources/db/update/dbupdate-003-0.sql b/docs-core/src/main/resources/db/update/dbupdate-003-0.sql new file mode 100644 index 00000000..84e042c1 --- /dev/null +++ b/docs-core/src/main/resources/db/update/dbupdate-003-0.sql @@ -0,0 +1 @@ +insert into T_ROLE(ROL_ID_C, ROL_NAME_C, ROL_CREATEDATE_D) values('user', 'User', NOW()); \ No newline at end of file diff --git a/docs-parent/TODO b/docs-parent/TODO index 8dbc8e35..e2beaaba 100644 --- a/docs-parent/TODO +++ b/docs-parent/TODO @@ -1 +1 @@ -- Users administration (client) +- Users deletion with confirmation (client) diff --git a/docs-web/src/dev/resources/config.properties b/docs-web/src/dev/resources/config.properties index 87577f48..a7a2e43f 100644 --- a/docs-web/src/dev/resources/config.properties +++ b/docs-web/src/dev/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=2 \ No newline at end of file +db.version=3 \ No newline at end of file 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 ce152af2..6344d43c 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 @@ -3,6 +3,7 @@ package com.sismics.docs.rest.resource; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Set; import javax.servlet.http.Cookie; import javax.ws.rs.DELETE; @@ -25,6 +26,7 @@ import org.codehaus.jettison.json.JSONObject; import com.sismics.docs.core.constant.Constants; import com.sismics.docs.core.dao.jpa.AuthenticationTokenDao; +import com.sismics.docs.core.dao.jpa.RoleBaseFunctionDao; import com.sismics.docs.core.dao.jpa.UserDao; import com.sismics.docs.core.dao.jpa.dto.UserDto; import com.sismics.docs.core.model.jpa.AuthenticationToken; @@ -371,7 +373,9 @@ public class UserResource extends BaseResource { } // Ensure that the admin user is not deleted - // TODO Ensure it exists at least one user left + if (hasBaseFunction(BaseFunction.ADMIN)) { + throw new ClientException("ForbiddenError", "The admin user cannot be deleted"); + } // Delete the user UserDao userDao = new UserDao(); @@ -407,7 +411,11 @@ public class UserResource extends BaseResource { } // Ensure that the admin user is not deleted - // TODO Ensure it exists at least one user left + RoleBaseFunctionDao userBaseFuction = new RoleBaseFunctionDao(); + Set baseFunctionSet = userBaseFuction.findByRoleId(user.getRoleId()); + if (baseFunctionSet.contains(BaseFunction.ADMIN.name())) { + throw new ClientException("ForbiddenError", "The admin user cannot be deleted"); + } // Delete the user userDao.delete(user.getUsername()); diff --git a/docs-web/src/main/webapp/js/app.js b/docs-web/src/main/webapp/js/app.js index 956ff881..a24970af 100644 --- a/docs-web/src/main/webapp/js/app.js +++ b/docs-web/src/main/webapp/js/app.js @@ -85,7 +85,16 @@ var App = angular.module('docs', ['ui.state', 'ui.bootstrap', 'ui.route', 'ui.ke } }) .state('settings.user.edit', { - url: '/:username', + url: '/edit/:username', + views: { + 'user': { + templateUrl: 'partial/settings.user.edit.html', + controller: 'SettingsUserEdit' + } + } + }) + .state('settings.user.add', { + url: '/add', views: { 'user': { templateUrl: 'partial/settings.user.edit.html', diff --git a/docs-web/src/main/webapp/js/controller/SettingsUser.js b/docs-web/src/main/webapp/js/controller/SettingsUser.js index 9fb033dc..831952ab 100644 --- a/docs-web/src/main/webapp/js/controller/SettingsUser.js +++ b/docs-web/src/main/webapp/js/controller/SettingsUser.js @@ -4,10 +4,16 @@ * Settings user page controller. */ App.controller('SettingsUser', function($scope, $state, Restangular) { - // Load users from server - Restangular.one('user/list').get({ limit: 100 }).then(function(data) { - $scope.users = data.users; - }); + /** + * Load users from server. + */ + $scope.loadUsers = function() { + Restangular.one('user/list').get({ limit: 100 }).then(function(data) { + $scope.users = data.users; + }); + }; + + $scope.loadUsers(); /** * Edit a user. diff --git a/docs-web/src/main/webapp/js/controller/SettingsUserEdit.js b/docs-web/src/main/webapp/js/controller/SettingsUserEdit.js index d8320a27..89782c19 100644 --- a/docs-web/src/main/webapp/js/controller/SettingsUserEdit.js +++ b/docs-web/src/main/webapp/js/controller/SettingsUserEdit.js @@ -3,6 +3,39 @@ /** * Settings user edition page controller. */ -App.controller('SettingsUserEdit', function($scope, $stateParams, Restangular) { - $scope.user = Restangular.one('user', $stateParams.username).get(); +App.controller('SettingsUserEdit', function($scope, $state, $stateParams, Restangular) { + /** + * Returns true if in edit mode (false in add mode). + */ + $scope.isEdit = function() { + return $stateParams.username; + }; + + /** + * In edit mode, load the current user. + */ + if ($scope.isEdit()) { + Restangular.one('user', $stateParams.username).get().then(function(data) { + $scope.user = data; + }); + } + + $scope.edit = function() { + var promise = null; + + if ($scope.isEdit()) { + promise = Restangular + .one('user', $stateParams.username) + .post('', $scope.user); + } else { + promise = Restangular + .one('user') + .put($scope.user); + } + + promise.then(function() { + $scope.loadUsers(); + $state.transitionTo('settings.user'); + }); + }; }); \ No newline at end of file diff --git a/docs-web/src/main/webapp/partial/settings.user.edit.html b/docs-web/src/main/webapp/partial/settings.user.edit.html index efce7395..eee71052 100644 --- a/docs-web/src/main/webapp/partial/settings.user.edit.html +++ b/docs-web/src/main/webapp/partial/settings.user.edit.html @@ -1,13 +1,50 @@ -

{{ user.username }}

-
-
E-mail
-
{{ user.email }}
-
-
-
Theme
-
{{ user.theme }}
-
-
-
Locale
-
{{ user.locale }}
-
\ No newline at end of file +

Edit "{{ user.username }}"

+

Add user

+
+
+ +
+ + Required + Too short + Too long +
+
+
+ +
+ + Required + Must be a valid e-mail + Too short + Too long +
+
+
+ +
+ + Required + Too short + Too long +
+
+
+ +
+ + Password and password confirmation must match +
+
+
+ +
+
+{{ alert.msg }} \ No newline at end of file diff --git a/docs-web/src/main/webapp/partial/settings.user.html b/docs-web/src/main/webapp/partial/settings.user.html index 90a82d1c..9d1b862f 100644 --- a/docs-web/src/main/webapp/partial/settings.user.html +++ b/docs-web/src/main/webapp/partial/settings.user.html @@ -1,9 +1,9 @@ -

Users management

+

Users management Add

- +
@@ -11,7 +11,7 @@ - + diff --git a/docs-web/src/main/webapp/style/main.less b/docs-web/src/main/webapp/style/main.less index d7b17afe..f3b2314d 100644 --- a/docs-web/src/main/webapp/style/main.less +++ b/docs-web/src/main/webapp/style/main.less @@ -50,6 +50,13 @@ } } +// Users list +.table-users { + tbody tr { + cursor: pointer; + } +} + // Logs list .table-logs { tbody tr td { diff --git a/docs-web/src/prod/resources/config.properties b/docs-web/src/prod/resources/config.properties index 87577f48..a7a2e43f 100644 --- a/docs-web/src/prod/resources/config.properties +++ b/docs-web/src/prod/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=2 \ No newline at end of file +db.version=3 \ No newline at end of file diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestUserResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestUserResource.java index 42c81f3d..0421fb69 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestUserResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestUserResource.java @@ -238,7 +238,7 @@ public class TestUserResource extends BaseJerseyTest { */ @Test public void testUserResourceAdmin() throws JSONException { - // Create admin_user1 user + // Create admin_user1 user clientUtil.createUser("admin_user1"); // Login admin @@ -275,14 +275,34 @@ public class TestUserResource extends BaseJerseyTest { userResource = resource().path("/user"); userResource.addFilter(new CookieAuthenticationFilter(adminAuthenticationToken)); postParams = new MultivaluedMapImpl(); - postParams.add("email", " alice2@docs.com "); + postParams.add("email", " alice2@reader.com "); postParams.add("theme", " default.less"); postParams.add("locale", " en "); + postParams.add("display_title_web", true); + postParams.add("display_title_mobile", false); + postParams.add("display_unread_web", false); + postParams.add("display_unread_mobile", false); response = userResource.post(ClientResponse.class, postParams); Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); json = response.getEntity(JSONObject.class); Assert.assertEquals("ok", json.getString("status")); + // User admin deletes himself: forbidden + userResource = resource().path("/user"); + userResource.addFilter(new CookieAuthenticationFilter(adminAuthenticationToken)); + response = userResource.delete(ClientResponse.class); + Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus())); + json = response.getEntity(JSONObject.class); + Assert.assertEquals("ForbiddenError", json.getString("type")); + + // User admin deletes himself: forbidden + userResource = resource().path("/user/admin"); + userResource.addFilter(new CookieAuthenticationFilter(adminAuthenticationToken)); + response = userResource.delete(ClientResponse.class); + Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus())); + json = response.getEntity(JSONObject.class); + Assert.assertEquals("ForbiddenError", json.getString("type")); + // User admin deletes user admin_user1 userResource = resource().path("/user/admin_user1"); userResource.addFilter(new CookieAuthenticationFilter(adminAuthenticationToken));
Username
{{ user.username }} {{ user.create_date | date: 'yyyy-MM-dd' }}