From 1cae964c09c43c6debb94dc5205de9d3375f1e37 Mon Sep 17 00:00:00 2001 From: jendib Date: Tue, 24 Nov 2015 00:30:01 +0100 Subject: [PATCH] #41: DB: Storage quota and current usage, accessible from /user --- .../sismics/docs/core/dao/jpa/UserDao.java | 2 + .../com/sismics/docs/core/model/jpa/User.java | 106 +++++------------- .../src/main/resources/config.properties | 2 +- .../resources/db/update/dbupdate-004-0.sql | 3 + .../sismics/docs/core/dao/jpa/TestJpa.java | 2 + .../com/sismics/rest/util/ValidationUtil.java | 18 ++- .../sismics/docs/rest/util/ClientUtil.java | 2 +- docs-web/src/dev/resources/config.properties | 2 +- .../docs/rest/resource/UserResource.java | 33 ++++-- docs-web/src/prod/resources/config.properties | 2 +- .../src/stress/resources/config.properties | 2 +- .../sismics/docs/rest/TestUserResource.java | 29 ++++- 12 files changed, 107 insertions(+), 96 deletions(-) create mode 100644 docs-core/src/main/resources/db/update/dbupdate-004-0.sql diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/UserDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/UserDao.java index 3a6c0154..972593a0 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/UserDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/UserDao.java @@ -101,6 +101,8 @@ public class UserDao { // Update the user userFromDb.setEmail(user.getEmail()); + userFromDb.setStorageQuota(user.getStorageQuota()); + userFromDb.setStorageCurrent(user.getStorageCurrent()); // Create audit log AuditLogUtil.create(userFromDb, AuditLogType.UPDATE); diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/User.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/User.java index eb51877b..5476a4ab 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/User.java +++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/User.java @@ -54,6 +54,18 @@ public class User implements Loggable { @Column(name = "USE_EMAIL_C", nullable = false, length = 100) private String email; + /** + * Storage quota. + */ + @Column(name = "USE_STORAGEQUOTA_N", nullable = false) + private Long storageQuota; + + /** + * Storage current usage. + */ + @Column(name = "USE_STORAGECURRENT_N", nullable = false) + private Long storageCurrent; + /** * Creation date. */ @@ -66,149 +78,87 @@ public class User implements Loggable { @Column(name = "USE_DELETEDATE_D") private Date deleteDate; - /** - * Getter of id. - * - * @return id - */ public String getId() { return id; } - /** - * Setter of id. - * - * @param id id - */ public void setId(String id) { this.id = id; } - /** - * Getter of roleId. - * - * @return roleId - */ public String getRoleId() { return roleId; } - /** - * Setter of roleId. - * - * @param roleId roleId - */ public void setRoleId(String roleId) { this.roleId = roleId; } - /** - * Getter of username. - * - * @return username - */ public String getUsername() { return username; } - /** - * Setter of username. - * - * @param username username - */ public void setUsername(String username) { this.username = username; } - /** - * Getter of password. - * - * @return password - */ public String getPassword() { return password; } - /** - * Setter of password. - * - * @param password password - */ public void setPassword(String password) { this.password = password; } - /** - * Getter of email. - * - * @return email - */ public String getEmail() { return email; } - /** - * Setter of email. - * - * @param email email - */ public void setEmail(String email) { this.email = email; } - /** - * Getter of createDate. - * - * @return createDate - */ public Date getCreateDate() { return createDate; } - /** - * Setter of createDate. - * - * @param createDate createDate - */ public void setCreateDate(Date createDate) { this.createDate = createDate; } - /** - * Getter of deleteDate. - * - * @return deleteDate - */ @Override public Date getDeleteDate() { return deleteDate; } - /** - * Setter of deleteDate. - * - * @param deleteDate deleteDate - */ public void setDeleteDate(Date deleteDate) { this.deleteDate = deleteDate; } - /** - * Getter de privateKey. - * @return privateKey - */ public String getPrivateKey() { return privateKey; } - /** - * Setter de privateKey. - * @param privateKey privateKey - */ public void setPrivateKey(String privateKey) { this.privateKey = privateKey; } + public Long getStorageQuota() { + return storageQuota; + } + + public void setStorageQuota(Long storageQuota) { + this.storageQuota = storageQuota; + } + + public Long getStorageCurrent() { + return storageCurrent; + } + + public void setStorageCurrent(Long storageCurrent) { + this.storageCurrent = storageCurrent; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) diff --git a/docs-core/src/main/resources/config.properties b/docs-core/src/main/resources/config.properties index 53e95e79..03d382c6 100644 --- a/docs-core/src/main/resources/config.properties +++ b/docs-core/src/main/resources/config.properties @@ -1 +1 @@ -db.version=3 \ No newline at end of file +db.version=4 \ No newline at end of file diff --git a/docs-core/src/main/resources/db/update/dbupdate-004-0.sql b/docs-core/src/main/resources/db/update/dbupdate-004-0.sql new file mode 100644 index 00000000..7e2406ba --- /dev/null +++ b/docs-core/src/main/resources/db/update/dbupdate-004-0.sql @@ -0,0 +1,3 @@ +alter table T_USER add column USE_STORAGEQUOTA_N bigint not null default 10000000000; +alter table T_USER add column USE_STORAGECURRENT_N bigint not null default 0; +update T_CONFIG set CFG_VALUE_C = '4' where CFG_ID_C = 'DB_VERSION'; diff --git a/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java b/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java index 8998cb66..0dc8d675 100644 --- a/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java +++ b/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java @@ -20,6 +20,8 @@ public class TestJpa extends BaseTransactionalTest { user.setUsername("username"); user.setEmail("toto@docs.com"); user.setRoleId("admin"); + user.setStorageCurrent(0l); + user.setStorageQuota(10l); user.setPrivateKey("AwesomePrivateKey"); String id = userDao.create(user); diff --git a/docs-web-common/src/main/java/com/sismics/rest/util/ValidationUtil.java b/docs-web-common/src/main/java/com/sismics/rest/util/ValidationUtil.java index 8bcea9ff..1d146641 100644 --- a/docs-web-common/src/main/java/com/sismics/rest/util/ValidationUtil.java +++ b/docs-web-common/src/main/java/com/sismics/rest/util/ValidationUtil.java @@ -155,7 +155,23 @@ public class ValidationUtil { try { return Integer.valueOf(s); } catch (NumberFormatException e) { - throw new ClientException("Validation Error", MessageFormat.format("{0} is not a number", name)); + throw new ClientException("ValidationError", MessageFormat.format("{0} is not a number", name)); + } + } + + /** + * Checks if the string is a number. + * + * @param s String to validate + * @param name Name of the parameter + * @return Parsed number + * @throws ClientException + */ + public static Long validateLong(String s, String name) throws ClientException { + try { + return Long.valueOf(s); + } catch (NumberFormatException e) { + throw new ClientException("ValidationError", MessageFormat.format("{0} is not a number", name)); } } diff --git a/docs-web-common/src/test/java/com/sismics/docs/rest/util/ClientUtil.java b/docs-web-common/src/test/java/com/sismics/docs/rest/util/ClientUtil.java index 92276494..3f16562c 100644 --- a/docs-web-common/src/test/java/com/sismics/docs/rest/util/ClientUtil.java +++ b/docs-web-common/src/test/java/com/sismics/docs/rest/util/ClientUtil.java @@ -40,7 +40,7 @@ public class ClientUtil { form.param("username", username); form.param("email", username + "@docs.com"); form.param("password", "12345678"); - form.param("time_zone", "Asia/Tokyo"); + form.param("storage_quota", "1000000"); // 1MB quota resource.path("/user").request() .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminAuthenticationToken) .put(Entity.form(form), JsonObject.class); diff --git a/docs-web/src/dev/resources/config.properties b/docs-web/src/dev/resources/config.properties index a7a2e43f..299540e8 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=3 \ No newline at end of file +db.version=4 \ 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 b1fe41eb..cd9dafab 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 @@ -64,7 +64,8 @@ public class UserResource extends BaseResource { public Response register( @FormParam("username") String username, @FormParam("password") String password, - @FormParam("email") String email) { + @FormParam("email") String email, + @FormParam("storage_quota") String storageQuotaStr) { if (!authenticate()) { throw new ForbiddenClientException(); @@ -76,6 +77,7 @@ public class UserResource extends BaseResource { ValidationUtil.validateAlphanumeric(username, "username"); password = ValidationUtil.validateLength(password, "password", 8, 50); email = ValidationUtil.validateLength(email, "email", 3, 50); + Long storageQuota = ValidationUtil.validateLong(storageQuotaStr, "storage_quota"); ValidationUtil.validateEmail(email, "email"); // Create the user @@ -84,6 +86,8 @@ public class UserResource extends BaseResource { user.setUsername(username); user.setPassword(password); user.setEmail(email); + user.setStorageQuota(storageQuota); + user.setStorageCurrent(0l); try { user.setPrivateKey(EncryptionUtil.generatePrivateKey()); } catch (NoSuchAlgorithmException e) { @@ -119,7 +123,8 @@ public class UserResource extends BaseResource { @POST public Response update( @FormParam("password") String password, - @FormParam("email") String email) { + @FormParam("email") String email, + @FormParam("storage_quota") String storageQuotaStr) { if (!authenticate()) { throw new ForbiddenClientException(); @@ -135,9 +140,13 @@ public class UserResource extends BaseResource { if (email != null) { user.setEmail(email); } - + if (StringUtils.isNotBlank(storageQuotaStr)) { + Long storageQuota = ValidationUtil.validateLong(storageQuotaStr, "storage_quota"); + user.setStorageQuota(storageQuota); + } user = userDao.update(user); + // Change the password if (StringUtils.isNotBlank(password)) { user.setPassword(password); userDao.updatePassword(user); @@ -162,7 +171,8 @@ public class UserResource extends BaseResource { public Response update( @PathParam("username") String username, @FormParam("password") String password, - @FormParam("email") String email) { + @FormParam("email") String email, + @FormParam("storage_quota") String storageQuotaStr) { if (!authenticate()) { throw new ForbiddenClientException(); @@ -184,11 +194,14 @@ public class UserResource extends BaseResource { if (email != null) { user.setEmail(email); } - + if (StringUtils.isNotBlank(storageQuotaStr)) { + Long storageQuota = ValidationUtil.validateLong(storageQuotaStr, "storage_quota"); + user.setStorageQuota(storageQuota); + } user = userDao.update(user); + // Change the password if (StringUtils.isNotBlank(password)) { - // Change the password user.setPassword(password); userDao.updatePassword(user); } @@ -406,7 +419,9 @@ public class UserResource extends BaseResource { UserDao userDao = new UserDao(); User user = userDao.getById(principal.getId()); response.add("username", user.getUsername()) - .add("email", user.getEmail()); + .add("email", user.getEmail()) + .add("storage_quota", user.getStorageQuota()) + .add("storage_current", user.getStorageCurrent()); JsonArrayBuilder baseFunctions = Json.createArrayBuilder(); for (String baseFunction : ((UserPrincipal) principal).getBaseFunctionSet()) { baseFunctions.add(baseFunction); @@ -441,7 +456,9 @@ public class UserResource extends BaseResource { JsonObjectBuilder response = Json.createObjectBuilder() .add("username", user.getUsername()) - .add("email", user.getEmail()); + .add("email", user.getEmail()) + .add("storage_quota", user.getStorageQuota()) + .add("storage_current", user.getStorageCurrent()); return Response.ok().entity(response.build()).build(); } diff --git a/docs-web/src/prod/resources/config.properties b/docs-web/src/prod/resources/config.properties index a7a2e43f..299540e8 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=3 \ No newline at end of file +db.version=4 \ No newline at end of file diff --git a/docs-web/src/stress/resources/config.properties b/docs-web/src/stress/resources/config.properties index a7a2e43f..299540e8 100644 --- a/docs-web/src/stress/resources/config.properties +++ b/docs-web/src/stress/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=3 \ No newline at end of file +db.version=4 \ 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 97104a2b..bf8f6328 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 @@ -55,7 +55,8 @@ public class TestUserResource extends BaseJerseyTest { .put(Entity.form(new Form() .param("username", " bb ") .param("email", "bob@docs.com") - .param("password", "12345678"))); + .param("password", "12345678") + .param("storage_quota", "10"))); Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus())); json = response.readEntity(JsonObject.class); Assert.assertEquals("ValidationError", json.getString("type")); @@ -67,11 +68,25 @@ public class TestUserResource extends BaseJerseyTest { .put(Entity.form(new Form() .param("username", "bob-") .param("email", "bob@docs.com") - .param("password", "12345678"))); + .param("password", "12345678") + .param("storage_quota", "10"))); Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus())); json = response.readEntity(JsonObject.class); Assert.assertEquals("ValidationError", json.getString("type")); Assert.assertTrue(json.getString("message"), json.getString("message").contains("alphanumeric")); + + // Create a user KO (invalid quota) + response = target().path("/user").request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminAuthenticationToken) + .put(Entity.form(new Form() + .param("username", "bob") + .param("email", "bob@docs.com") + .param("password", "12345678") + .param("storage_quota", "nope"))); + Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus())); + json = response.readEntity(JsonObject.class); + Assert.assertEquals("ValidationError", json.getString("type")); + Assert.assertTrue(json.getString("message"), json.getString("message").contains("number")); // Create a user KO (email format validation) response = target().path("/user").request() @@ -79,7 +94,8 @@ public class TestUserResource extends BaseJerseyTest { .put(Entity.form(new Form() .param("username", "bob") .param("email", "bobdocs.com") - .param("password", "12345678"))); + .param("password", "12345678") + .param("storage_quota", "10"))); Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus())); json = response.readEntity(JsonObject.class); Assert.assertEquals("ValidationError", json.getString("type")); @@ -89,7 +105,8 @@ public class TestUserResource extends BaseJerseyTest { Form form = new Form() .param("username", " bob ") .param("email", " bob@docs.com ") - .param("password", " 12345678 "); + .param("password", " 12345678 ") + .param("storage_quota", "10"); json = target().path("/user").request() .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminAuthenticationToken) .put(Entity.form(form), JsonObject.class); @@ -154,6 +171,8 @@ public class TestUserResource extends BaseJerseyTest { .get(JsonObject.class); Assert.assertEquals("alice@docs.com", json.getString("email")); Assert.assertFalse(json.getBoolean("is_default_password")); + Assert.assertEquals(0l, json.getJsonNumber("storage_current").longValue()); + Assert.assertEquals(1000000l, json.getJsonNumber("storage_quota").longValue()); // Check bob user information json = target().path("/user").request() @@ -219,6 +238,8 @@ public class TestUserResource extends BaseJerseyTest { .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminAuthenticationToken) .get(JsonObject.class); Assert.assertTrue(json.getBoolean("is_default_password")); + Assert.assertEquals(0l, json.getJsonNumber("storage_current").longValue()); + Assert.assertEquals(10000000000l, json.getJsonNumber("storage_quota").longValue()); // User admin updates his information json = target().path("/user").request()