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

Closes #167: disable users

This commit is contained in:
Benjamin Gamard
2017-11-20 21:21:50 +01:00
parent fb75bafe96
commit d786862a60
16 changed files with 138 additions and 22 deletions

View File

@@ -1,3 +1,3 @@
api.current_version=${project.version}
api.min_version=1.0
db.version=13
db.version=14

View File

@@ -63,6 +63,7 @@ public class AppResource extends BaseResource {
* @apiSuccess {Boolean} guest_login True if guest login is enabled
* @apiSuccess {String} total_memory Allocated JVM memory (in bytes)
* @apiSuccess {String} free_memory Free JVM memory (in bytes)
* @apiSuccess {String} active_user_count Number of active users
* @apiSuccess {String} global_storage_current Global storage currently used (in bytes)
* @apiSuccess {String} global_storage_quota Maximum global storage (in bytes)
* @apiPermission none
@@ -89,6 +90,7 @@ public class AppResource extends BaseResource {
.add("guest_login", guestLogin)
.add("total_memory", Runtime.getRuntime().totalMemory())
.add("free_memory", Runtime.getRuntime().freeMemory())
.add("active_user_count", userDao.getActiveUserCount())
.add("global_storage_current", userDao.getGlobalStorageCurrent());
if (globalQuota > 0) {
response.add("global_storage_quota", globalQuota);

View File

@@ -186,6 +186,7 @@ public class UserResource extends BaseResource {
* @apiParam {String{8..50}} password Password
* @apiParam {String{1..100}} email E-mail
* @apiParam {Number} storage_quota Storage quota (in bytes)
* @apiParam {Boolean} disabled Disabled status
* @apiSuccess {String} status Status OK
* @apiError (client) ForbiddenError Access denied
* @apiError (client) ValidationError Validation error
@@ -204,7 +205,8 @@ public class UserResource extends BaseResource {
@PathParam("username") String username,
@FormParam("password") String password,
@FormParam("email") String email,
@FormParam("storage_quota") String storageQuotaStr) {
@FormParam("storage_quota") String storageQuotaStr,
@FormParam("disabled") Boolean disabled) {
if (!authenticate()) {
throw new ForbiddenClientException();
}
@@ -218,7 +220,7 @@ public class UserResource extends BaseResource {
UserDao userDao = new UserDao();
User user = userDao.getActiveByUsername(username);
if (user == null) {
throw new ClientException("UserNotFound", "The user doesn't exist");
throw new ClientException("UserNotFound", "The user does not exist");
}
// Update the user
@@ -229,6 +231,22 @@ public class UserResource extends BaseResource {
Long storageQuota = ValidationUtil.validateLong(storageQuotaStr, "storage_quota");
user.setStorageQuota(storageQuota);
}
if (disabled != null) {
// Cannot disable the admin user or the guest user
RoleBaseFunctionDao userBaseFuction = new RoleBaseFunctionDao();
Set<String> baseFunctionSet = userBaseFuction.findByRoleId(Sets.newHashSet(user.getRoleId()));
if (Constants.GUEST_USER_ID.equals(username) || baseFunctionSet.contains(BaseFunction.ADMIN.name())) {
disabled = false;
}
if (disabled && user.getDisableDate() == null) {
// Recording the disabled date
user.setDisableDate(new Date());
} else if (!disabled && user.getDisableDate() != null) {
// Emptying the disabled date
user.setDisableDate(null);
}
}
user = userDao.update(user, principal.getId());
// Change the password
@@ -631,6 +649,7 @@ public class UserResource extends BaseResource {
* @apiSuccess {Number} storage_quota Storage quota (in bytes)
* @apiSuccess {Number} storage_current Quota used (in bytes)
* @apiSuccess {String[]} groups Groups
* @apiSuccess {Boolean} disabled True if the user is disabled
* @apiError (client) ForbiddenError Access denied
* @apiError (client) UserNotFound The user does not exist
* @apiPermission user
@@ -668,7 +687,8 @@ public class UserResource extends BaseResource {
.add("groups", groups)
.add("email", user.getEmail())
.add("storage_quota", user.getStorageQuota())
.add("storage_current", user.getStorageCurrent());
.add("storage_current", user.getStorageCurrent())
.add("disabled", user.getDisableDate() != null);
return Response.ok().entity(response.build()).build();
}
@@ -688,6 +708,7 @@ public class UserResource extends BaseResource {
* @apiSuccess {Number} users.storage_quota Storage quota (in bytes)
* @apiSuccess {Number} users.storage_current Quota used (in bytes)
* @apiSuccess {Number} users.create_date Create date (timestamp)
* @apiSuccess {Number} users.disabled True if the user is disabled
* @apiError (client) ForbiddenError Access denied
* @apiPermission user
* @apiVersion 1.5.0
@@ -730,7 +751,8 @@ public class UserResource extends BaseResource {
.add("email", userDto.getEmail())
.add("storage_quota", userDto.getStorageQuota())
.add("storage_current", userDto.getStorageCurrent())
.add("create_date", userDto.getCreateTimestamp()));
.add("create_date", userDto.getCreateTimestamp())
.add("disabled", userDto.getDisableTimestamp() != null));
}
JsonObjectBuilder response = Json.createObjectBuilder()

View File

@@ -245,7 +245,8 @@
"storage_quota": "Storage quota",
"storage_quota_placeholder": "Storage quota (in MB)",
"password": "Password",
"password_confirm": "Password (confirm)"
"password_confirm": "Password (confirm)",
"disabled": "Disabled user"
}
},
"security": {

View File

@@ -88,12 +88,23 @@
</div>
</div>
<div class="form-group" ng-show="isEdit() && user.username != 'admin' && user.username != 'guest'">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox text-danger">
<label>
<input name="disabled" type="checkbox" ng-model="user.disabled" />
<strong>{{ 'settings.user.edit.disabled' | translate }}</strong>
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" ng-click="edit()" ng-disabled="!editUserForm.$valid">
<span class="glyphicon glyphicon-pencil"></span> {{ isEdit() ? 'edit' : 'add' | translate }}
</button>
<button type="button" class="btn btn-danger" ng-click="remove()" ng-show="isEdit() && user.username != 'guest'">
<button type="button" class="btn btn-danger" ng-click="remove()" ng-show="isEdit() && user.username != 'admin' && user.username != 'guest'">
<span class="glyphicon glyphicon-trash"></span> {{ 'delete' | translate }}
</button>
</div>

View File

@@ -16,7 +16,8 @@
<tr ng-repeat="user in users | orderBy: 'username'" ng-click="editUser(user)"
ng-class="{ active: $stateParams.username == user.username }">
<td>
{{ user.username }}
<span ng-if="!user.disabled">{{ user.username }}</span>
<s ng-if="user.disabled">{{ user.username }}</s>
<span class="glyphicon glyphicon-lock" ng-show="user.totp_enabled" uib-tooltip="{{ 'settings.user.totp_enabled' | translate }}"></span>
</td>
<td>{{ user.create_date | date: dateFormat }}</td>

View File

@@ -1,3 +1,3 @@
api.current_version=${project.version}
api.min_version=1.0
db.version=13
db.version=14

View File

@@ -1,3 +1,3 @@
api.current_version=${project.version}
api.min_version=1.0
db.version=13
db.version=14

View File

@@ -37,6 +37,7 @@ public class TestAppResource extends BaseJerseyTest {
Assert.assertTrue(totalMemory > 0 && totalMemory > freeMemory);
Assert.assertFalse(json.getBoolean("guest_login"));
Assert.assertTrue(json.containsKey("global_storage_current"));
Assert.assertTrue(json.getJsonNumber("active_user_count").longValue() > 0);
// Rebuild Lucene index
Response response = target().path("/app/batch/reindex").request()

View File

@@ -57,6 +57,7 @@ public class TestUserResource extends BaseJerseyTest {
Assert.assertNotNull(user.getJsonNumber("storage_current"));
Assert.assertNotNull(user.getJsonNumber("create_date"));
Assert.assertFalse(user.getBoolean("totp_enabled"));
Assert.assertFalse(user.getBoolean("disabled"));
// Create a user KO (login length validation)
Response response = target().path("/user").request()
@@ -262,7 +263,7 @@ public class TestUserResource extends BaseJerseyTest {
Assert.assertEquals("newadminemail@docs.com", json.getString("email"));
// User admin update admin_user1 information
json = target().path("/user").request()
json = target().path("/user/admin_user1").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.post(Entity.form(new Form()
.param("email", " alice2@docs.com ")), JsonObject.class);
@@ -276,6 +277,36 @@ public class TestUserResource extends BaseJerseyTest {
json = response.readEntity(JsonObject.class);
Assert.assertEquals("ForbiddenError", json.getString("type"));
// User admin disable admin_user1
json = target().path("/user/admin_user1").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.post(Entity.form(new Form()
.param("disabled", "true")), JsonObject.class);
Assert.assertEquals("ok", json.getString("status"));
// User admin_user1 tries to authenticate
response = target().path("/user/login").request()
.post(Entity.form(new Form()
.param("username", "admin_user1")
.param("password", "12345678")
.param("remember", "false")));
Assert.assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
// User admin enable admin_user1
json = target().path("/user/admin_user1").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.post(Entity.form(new Form()
.param("disabled", "false")), JsonObject.class);
Assert.assertEquals("ok", json.getString("status"));
// User admin_user1 tries to authenticate
response = target().path("/user/login").request()
.post(Entity.form(new Form()
.param("username", "admin_user1")
.param("password", "12345678")
.param("remember", "false")));
Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus());
// User admin deletes user admin_user1
json = target().path("/user/admin_user1").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)