mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 14:07:55 +01:00
Closes #309: store onboarding status server side
This commit is contained in:
parent
8b1c41ae1e
commit
61b12bdebd
@ -171,6 +171,26 @@ public class UserDao {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the onboarding status.
|
||||||
|
*
|
||||||
|
* @param user User to update
|
||||||
|
* @return Updated user
|
||||||
|
*/
|
||||||
|
public User updateOnboarding(User user) {
|
||||||
|
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||||
|
|
||||||
|
// Get the user
|
||||||
|
Query q = em.createQuery("select u from User u where u.id = :id and u.deleteDate is null");
|
||||||
|
q.setParameter("id", user.getId());
|
||||||
|
User userDb = (User) q.getSingleResult();
|
||||||
|
|
||||||
|
// Update the user
|
||||||
|
userDb.setOnboarding(user.isOnboarding());
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a user by its ID.
|
* Gets a user by its ID.
|
||||||
*
|
*
|
||||||
|
@ -47,6 +47,12 @@ public class User implements Loggable {
|
|||||||
@Column(name = "USE_PRIVATEKEY_C", nullable = false, length = 100)
|
@Column(name = "USE_PRIVATEKEY_C", nullable = false, length = 100)
|
||||||
private String privateKey;
|
private String privateKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* False when the user passed the onboarding.
|
||||||
|
*/
|
||||||
|
@Column(name = "USE_ONBOARDING_B", nullable = false)
|
||||||
|
private boolean onboarding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TOTP secret key.
|
* TOTP secret key.
|
||||||
*/
|
*/
|
||||||
@ -198,6 +204,15 @@ public class User implements Loggable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOnboarding() {
|
||||||
|
return onboarding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User setOnboarding(boolean onboarding) {
|
||||||
|
this.onboarding = onboarding;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
|
@ -1 +1 @@
|
|||||||
db.version=22
|
db.version=23
|
@ -0,0 +1,2 @@
|
|||||||
|
alter table T_USER add column USE_ONBOARDING_B bit not null default 1;
|
||||||
|
update T_CONFIG set CFG_VALUE_C = '23' where CFG_ID_C = 'DB_VERSION';
|
@ -1,3 +1,3 @@
|
|||||||
api.current_version=${project.version}
|
api.current_version=${project.version}
|
||||||
api.min_version=1.0
|
api.min_version=1.0
|
||||||
db.version=22
|
db.version=23
|
@ -101,6 +101,7 @@ public class UserResource extends BaseResource {
|
|||||||
user.setPassword(password);
|
user.setPassword(password);
|
||||||
user.setEmail(email);
|
user.setEmail(email);
|
||||||
user.setStorageQuota(storageQuota);
|
user.setStorageQuota(storageQuota);
|
||||||
|
user.setOnboarding(true);
|
||||||
|
|
||||||
// Create the user
|
// Create the user
|
||||||
UserDao userDao = new UserDao();
|
UserDao userDao = new UserDao();
|
||||||
@ -622,6 +623,7 @@ public class UserResource extends BaseResource {
|
|||||||
* @apiGroup User
|
* @apiGroup User
|
||||||
* @apiSuccess {Boolean} anonymous True if no user is connected
|
* @apiSuccess {Boolean} anonymous True if no user is connected
|
||||||
* @apiSuccess {Boolean} is_default_password True if the admin has the default password
|
* @apiSuccess {Boolean} is_default_password True if the admin has the default password
|
||||||
|
* @apiSuccess {Boolean} onboarding True if the UI needs to display the onboarding
|
||||||
* @apiSuccess {String} username Username
|
* @apiSuccess {String} username Username
|
||||||
* @apiSuccess {String} email E-mail
|
* @apiSuccess {String} email E-mail
|
||||||
* @apiSuccess {Number} storage_quota Storage quota (in bytes)
|
* @apiSuccess {Number} storage_quota Storage quota (in bytes)
|
||||||
@ -665,7 +667,8 @@ public class UserResource extends BaseResource {
|
|||||||
.add("email", user.getEmail())
|
.add("email", user.getEmail())
|
||||||
.add("storage_quota", user.getStorageQuota())
|
.add("storage_quota", user.getStorageQuota())
|
||||||
.add("storage_current", user.getStorageCurrent())
|
.add("storage_current", user.getStorageCurrent())
|
||||||
.add("totp_enabled", user.getTotpKey() != null);
|
.add("totp_enabled", user.getTotpKey() != null)
|
||||||
|
.add("onboarding", user.isOnboarding());
|
||||||
|
|
||||||
// Base functions
|
// Base functions
|
||||||
JsonArrayBuilder baseFunctions = Json.createArrayBuilder();
|
JsonArrayBuilder baseFunctions = Json.createArrayBuilder();
|
||||||
@ -899,6 +902,39 @@ public class UserResource extends BaseResource {
|
|||||||
return Response.ok().entity(response.build()).build();
|
return Response.ok().entity(response.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the onboarding experience as passed.
|
||||||
|
*
|
||||||
|
* @api {post} /user/onboarded Mark the onboarding experience as passed
|
||||||
|
* @apiDescription Once the onboarding experience has been passed by the user, this resource prevent it from being displayed again.
|
||||||
|
* @apiName PostUserOnboarded
|
||||||
|
* @apiGroup User
|
||||||
|
* @apiSuccess {String} status Status OK
|
||||||
|
* @apiError (client) ForbiddenError Access denied
|
||||||
|
* @apiPermission user
|
||||||
|
* @apiVersion 1.7.0
|
||||||
|
*
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("onboarded")
|
||||||
|
public Response onboarded() {
|
||||||
|
if (!authenticate()) {
|
||||||
|
throw new ForbiddenClientException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save it
|
||||||
|
UserDao userDao = new UserDao();
|
||||||
|
User user = userDao.getActiveByUsername(principal.getName());
|
||||||
|
user.setOnboarding(false);
|
||||||
|
userDao.updateOnboarding(user);
|
||||||
|
|
||||||
|
// Always return OK
|
||||||
|
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||||
|
.add("status", "ok");
|
||||||
|
return Response.ok().entity(response.build()).build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable time-based one-time password.
|
* Enable time-based one-time password.
|
||||||
*
|
*
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* Document default controller.
|
* Document default controller.
|
||||||
*/
|
*/
|
||||||
angular.module('docs').controller('DocumentDefault', function ($scope, $rootScope, $state, Restangular, Upload, $translate, $uibModal, $dialog) {
|
angular.module('docs').controller('DocumentDefault', function ($scope, $rootScope, $state, Restangular, Upload, $translate, $uibModal, $dialog, User) {
|
||||||
// Load user audit log
|
// Load user audit log
|
||||||
Restangular.one('auditlog').get().then(function (data) {
|
Restangular.one('auditlog').get().then(function (data) {
|
||||||
$scope.logs = data.logs;
|
$scope.logs = data.logs;
|
||||||
@ -145,10 +145,12 @@ angular.module('docs').controller('DocumentDefault', function ($scope, $rootScop
|
|||||||
|
|
||||||
// Onboarding
|
// Onboarding
|
||||||
$translate('onboarding.step1.title').then(function () {
|
$translate('onboarding.step1.title').then(function () {
|
||||||
if (localStorage.onboardingDisplayed || $(window).width() < 1000) {
|
User.userInfo().then(function(userData) {
|
||||||
|
if (!userData.onboarding || $(window).width() < 1000) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
localStorage.onboardingDisplayed = true;
|
Restangular.one('user').post('onboarded');
|
||||||
|
$rootScope.userInfo.onboarding = false;
|
||||||
|
|
||||||
$rootScope.onboardingEnabled = true;
|
$rootScope.onboardingEnabled = true;
|
||||||
|
|
||||||
@ -189,4 +191,5 @@ angular.module('docs').controller('DocumentDefault', function ($scope, $rootScop
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
@ -1,3 +1,3 @@
|
|||||||
api.current_version=${project.version}
|
api.current_version=${project.version}
|
||||||
api.min_version=1.0
|
api.min_version=1.0
|
||||||
db.version=22
|
db.version=23
|
@ -1,3 +1,3 @@
|
|||||||
api.current_version=${project.version}
|
api.current_version=${project.version}
|
||||||
api.min_version=1.0
|
api.min_version=1.0
|
||||||
db.version=22
|
db.version=23
|
@ -172,7 +172,7 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
.get();
|
.get();
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
json = response.readEntity(JsonObject.class);
|
json = response.readEntity(JsonObject.class);
|
||||||
Assert.assertEquals(true, json.getBoolean("anonymous"));
|
Assert.assertTrue(json.getBoolean("anonymous"));
|
||||||
|
|
||||||
// Check alice user information
|
// Check alice user information
|
||||||
json = target().path("/user").request()
|
json = target().path("/user").request()
|
||||||
@ -187,8 +187,20 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
json = target().path("/user").request()
|
json = target().path("/user").request()
|
||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, bobToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, bobToken)
|
||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
|
Assert.assertTrue(json.getBoolean("onboarding"));
|
||||||
Assert.assertEquals("bob@docs.com", json.getString("email"));
|
Assert.assertEquals("bob@docs.com", json.getString("email"));
|
||||||
|
|
||||||
|
// Pass onboarding
|
||||||
|
target().path("/user/onboarded").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, bobToken)
|
||||||
|
.post(Entity.form(new Form()), JsonObject.class);
|
||||||
|
|
||||||
|
// Check bob user information
|
||||||
|
json = target().path("/user").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, bobToken)
|
||||||
|
.get(JsonObject.class);
|
||||||
|
Assert.assertFalse(json.getBoolean("onboarding"));
|
||||||
|
|
||||||
// Test login KO (user not found)
|
// Test login KO (user not found)
|
||||||
response = target().path("/user/login").request()
|
response = target().path("/user/login").request()
|
||||||
.post(Entity.form(new Form()
|
.post(Entity.form(new Form()
|
||||||
|
Loading…
Reference in New Issue
Block a user