@@ -136,8 +136,7 @@ public User assertAndGetUser(Long userId) {
136136 * @return the user or null if user not exist or current user has not right to read the user
137137 */
138138 public User getUserById (Long id ) {
139- User user = userDao .findUser (id );
140- return user ;
139+ return userDao .findUser (id );
141140 }
142141
143142 /**
@@ -160,13 +159,13 @@ public List<User> getUsersForProject(Long projectId) {
160159 * LocalAccount of the user is used.
161160 * <p>
162161 * In case no LocalAccount has been found, authentication method with random parameters is
163- * returned. Such parameters may be used by clients to create brand new account. This behavior
162+ * returned. Such parameters may be used by clients to create brand- new account. This behavior
164163 * prevents to easy account existence leaks.
165164 *
166165 * @param identifier {@link LocalAccount } email address or {@link User} username
167166 *
168167 * @return authentication method to use to authentication as email owner or new random one which
169- * can be use to create a brand new localAccount
168+ * can be used to create a brand new localAccount
170169 *
171170 * @throws HttpErrorMessage badRequest if there is no identifier
172171 */
@@ -180,8 +179,8 @@ public AuthMethod getAuthenticationMethod(String identifier) {
180179
181180 if (account != null ) {
182181 return new AuthMethod (account .getCurrentClientHashMethod (),
183- account .getClientSalt (),
184- account .getNextClientHashMethod (), account .getNewClientSalt ());
182+ account .getClientSalt (),
183+ account .getNextClientHashMethod (), account .getNewClientSalt ());
185184 } else {
186185 // no account found, return random method
187186 // TODO: store it in a tmp cache
@@ -201,90 +200,90 @@ public AuthMethod getAuthenticationMethod(String identifier) {
201200 */
202201 public AuthMethod getDefaultRandomAuthenticationMethod () {
203202 return new AuthMethod (Helper .getDefaultHashMethod (), Helper
204- .generateHexSalt (SALT_LENGTH ), null , null );
203+ .generateHexSalt (SALT_LENGTH ), null , null );
205204 }
206205
207206 /**
208- * Create a brand new user, which can authenticate with a {@link LocalAccount}.First,
209- * plainPassword will be hashed as any client should do. Then the
210- * {@link #signup(ch.colabproject.colab.api.model.user.SignUpInfo) signup} method is called.
207+ * {@link #createAdminUser(String, String, String)} within a brand-new transaction.
211208 *
212209 * @param username username
213210 * @param email email address
214211 * @param plainPassword plain text password
215212 *
216- * @return a brand new user
217- *
218- * @throws HttpErrorMessage if username is already taken
219- */
220- public User createUser (String username , String email , String plainPassword ) {
221- AuthMethod method = getDefaultRandomAuthenticationMethod ();
222- SignUpInfo signUpinfo = new SignUpInfo ();
223-
224- signUpinfo .setUsername (username );
225- signUpinfo .setEmail (email );
226- signUpinfo .setHashMethod (method .getMandatoryMethod ());
227-
228- signUpinfo .setSalt (method .getSalt ());
229-
230- byte [] hash = method .getMandatoryMethod ().hash (plainPassword , method .getSalt ());
231-
232- signUpinfo .setHash (Helper .bytesToHex (hash ));
233-
234- return this .signup (signUpinfo );
235- }
236-
237- /**
238- * {@link #createAdminUser(java.lang.String, java.lang.String, java.lang.String)
239- * createAdminUser} within a brand new transaction.
240- *
241- * @param username username
242- * @param email email address
243- * @param plainPassword plain text password
244- *
245- * @return a brand new user
213+ * @return a brand-new user to rule them all
246214 */
247215 @ TransactionAttribute (TransactionAttributeType .REQUIRES_NEW )
248216 public User createAdminUserTx (String username , String email , String plainPassword ) {
249217 return this .createAdminUser (username , email , plainPassword );
250218 }
251219
252220 /**
253- * Create a brand new admin user, which can authenticate with a {@link LocalAccount}. First,
254- * plainPassword will be hashed as any client should do. Then the
255- * {@link #signup(ch.colabproject.colab.api.model. user.SignUpInfo) signup} method is called .
221+ * Create a brand- new admin user, which can authenticate with a {@link LocalAccount}.
222+ * <p>
223+ * First create the user and the local account, then authenticate and grant admin rights .
256224 *
257225 * @param username username
258226 * @param email email address
259227 * @param plainPassword plain text password
260228 *
261- * @return a brand new user
229+ * @return a brand- new user to rule them all
262230 *
263231 * @throws HttpErrorMessage if username is already taken
264232 */
265- public User createAdminUser (String username , String email , String plainPassword ) {
266- User admin = this .createUser (username , email , plainPassword );
233+ private User createAdminUser (String username , String email , String plainPassword ) {
234+ User admin = this .createUserWithLocalAccount (username , username /* username is also used as firstname */ , email , plainPassword );
235+
267236 LocalAccount account = (LocalAccount ) admin .getAccounts ().get (0 );
268237
269238 AuthInfo authInfo = new AuthInfo ();
270239 authInfo .setIdentifier (username );
271240 authInfo .setMandatoryHash (
272- Helper .bytesToHex (
273- account .getCurrentClientHashMethod ().hash (
274- plainPassword ,
275- account .getClientSalt ())));
241+ Helper .bytesToHex (
242+ account .getCurrentClientHashMethod ().hash (
243+ plainPassword ,
244+ account .getClientSalt ())));
276245 this .authenticate (authInfo );
277246
278247 this .grantAdminRight (admin .getId ());
279248 return admin ;
280249 }
281250
251+ /**
252+ * Create a brand-new user, which can authenticate with a {@link LocalAccount}.First,
253+ * plainPassword will be hashed as any client should do. Then the
254+ * {@link #signup(SignUpInfo) signup} method is called.
255+ *
256+ * @param username username
257+ * @param firstname first name
258+ * @param email email address
259+ * @param plainPassword plain text password
260+ *
261+ * @return a brand-new user
262+ *
263+ * @throws HttpErrorMessage if username is already taken
264+ */
265+ private User createUserWithLocalAccount (String username , String firstname , String email , String plainPassword ) {
266+ AuthMethod method = getDefaultRandomAuthenticationMethod ();
267+ byte [] hash = method .getMandatoryMethod ().hash (plainPassword , method .getSalt ());
268+
269+ SignUpInfo signUpInfo = new SignUpInfo ();
270+
271+ signUpInfo .setUsername (username );
272+ signUpInfo .setFirstname (firstname );
273+ signUpInfo .setEmail (email );
274+ signUpInfo .setHashMethod (method .getMandatoryMethod ());
275+ signUpInfo .setSalt (method .getSalt ());
276+ signUpInfo .setHash (Helper .bytesToHex (hash ));
277+
278+ return this .signup (signUpInfo );
279+ }
280+
282281 /**
283282 * Create a new user with local account. An e-mail will be sent to user to verify its account
284283 *
285284 * @param signup all info to create a new account
286285 *
287- * @return brand new user embedding an LocalAccount
286+ * @return brand- new user embedding an LocalAccount
288287 *
289288 * @throws HttpErrorMessage if username is already taken
290289 */
@@ -315,6 +314,10 @@ public User signup(SignUpInfo signup) {
315314 account .setUser (user );
316315
317316 user .setUsername (signup .getUsername ());
317+ user .setFirstname (signup .getFirstname ());
318+ user .setLastname (signup .getLastname ());
319+ user .setAffiliation (signup .getAffiliation ());
320+ user .setAgreedTime (OffsetDateTime .now ());
318321
319322 validationManager .assertValid (user );
320323 validationManager .assertValid (account );
@@ -363,20 +366,20 @@ public User authenticate(AuthInfo authInfo) {
363366
364367 AuthenticationFailure aa = sessionManager .getAuthenticationAttempt (account );
365368 if (aa != null ) {
366- logger .warn ("Attmpt : {}" , aa .getCounter ());
369+ logger .warn ("Attempt : {}" , aa .getCounter ());
367370 if (aa .getCounter () >= AUTHENTICATION_ATTEMPT_MAX ) {
368371 // max number of failed attempts reached
369372 OffsetDateTime lastAttempt = aa .getTimestamp ();
370373 OffsetDateTime delay = lastAttempt
371- .plusSeconds (AUTHENTICATION_ATTEMPT_RESET_DELAY_SEC );
374+ .plusSeconds (AUTHENTICATION_ATTEMPT_RESET_DELAY_SEC );
372375 if (OffsetDateTime .now ().isAfter (delay )) {
373376 // delay has been reached, user may try again
374377 sessionManager .resetAuthenticationAttemptHistory (account );
375378 } else {
376379 // user have to wait some time before any new attempt
377380 logger .warn (
378- "Account {} reached the max number of failed authentication" ,
379- account );
381+ "Account {} reached the max number of failed authentication" ,
382+ account );
380383 throw HttpErrorMessage .tooManyAttempts ();
381384 }
382385 }
@@ -394,7 +397,7 @@ public User authenticate(AuthInfo authInfo) {
394397
395398 // should rotate client method ?
396399 if (account .getNextClientHashMethod () != null
397- && authInfo .getOptionalHash () != null ) {
400+ && authInfo .getOptionalHash () != null ) {
398401 // rotate method
399402 account .setClientSalt (account .getNewClientSalt ());
400403 account .setNewClientSalt (null );
@@ -470,7 +473,7 @@ public void updatePassword(AuthInfo authInfo) {
470473 * hash given client-side hash to dbHash and store it
471474 *
472475 * @param account account to update the hash in
473- * @param password hash (ie account.clientMethod.hash(clientSalt + plain_password))
476+ * @param hash hash (ie account.clientMethod.hash(clientSalt + plain_password))
474477 */
475478 private void shadowHash (LocalAccount account , String hash ) {
476479 // use a new salt
@@ -498,9 +501,7 @@ public void forceLogout(Long sessionId) {
498501 HttpSession currentSession = requestManager .getHttpSession ();
499502 if (httpSession != null ) {
500503 if (!httpSession .equals (currentSession )) {
501- requestManager .sudo (() -> {
502- sessionManager .deleteHttpSession (httpSession );
503- });
504+ requestManager .sudo (() -> sessionManager .deleteHttpSession (httpSession ));
504505 } else {
505506 throw HttpErrorMessage .badRequest ();
506507 }
@@ -510,7 +511,7 @@ public void forceLogout(Long sessionId) {
510511 /**
511512 * Grant admin right to a user.
512513 *
513- * @param user user who will became an admin
514+ * @param user user who will become an admin
514515 */
515516 public void grantAdminRight (User user ) {
516517 user .setAdmin (true );
@@ -519,7 +520,7 @@ public void grantAdminRight(User user) {
519520 /**
520521 * Grant admin right to a user.
521522 *
522- * @param id id of user who will became an admin
523+ * @param id id of user who will become an admin
523524 */
524525 public void grantAdminRight (Long id ) {
525526 this .grantAdminRight (userDao .findUser (id ));
@@ -598,8 +599,8 @@ public LocalAccount findLocalAccountByIdentifier(String identifier) {
598599 // User found, as authenticationMethod is only available for LocalAccount,
599600 // try to find one
600601 Optional <Account > optAccount = user .getAccounts ().stream ()
601- .filter (a -> a instanceof LocalAccount )
602- .findFirst ();
602+ .filter (a -> a instanceof LocalAccount )
603+ .findFirst ();
603604 if (optAccount .isPresent ()) {
604605 account = (LocalAccount ) optAccount .get ();
605606 }
@@ -635,7 +636,7 @@ public void requestPasswordReset(String email) {
635636 * @throws ColabMergeException if something went wrong
636637 */
637638 public LocalAccount updateLocalAccountEmailAddress (LocalAccount account )
638- throws ColabMergeException {
639+ throws ColabMergeException {
639640 logger .debug ("Update LocalAccount email address: {}" , account );
640641 LocalAccount managedAccount = (LocalAccount ) accountDao .findAccount (account .getId ());
641642
@@ -655,7 +656,7 @@ public LocalAccount updateLocalAccountEmailAddress(LocalAccount account)
655656 tokenManager .requestEmailAddressVerification (account , false );
656657 } catch (Exception e ) {
657658 // address already used, do not send any email to this address
658- logger .error ("Execption " , e );
659+ logger .error ("Exception " , e );
659660 }
660661 }
661662
@@ -671,15 +672,24 @@ public void setLocalAccountAsVerified(LocalAccount account) {
671672 account .setVerified (Boolean .TRUE );
672673 }
673674
675+ /**
676+ * Update the user agreedTime to now
677+ *
678+ * @param userId id of the user to update
679+ */
680+ public void updateUserAgreedTime (Long userId ) {
681+ User user = assertAndGetUser (userId );
682+ OffsetDateTime now = OffsetDateTime .now ();
683+ user .setAgreedTime (now );
684+ }
685+
674686 /**
675687 * Get all session linked to the current user
676688 *
677689 * @return list of all active sessions
678690 */
679691 public List <HttpSession > getCurrentUserActiveHttpSessions () {
680692 return requestManager .getCurrentUser ().getAccounts ().stream ()
681- .flatMap (account -> {
682- return account .getHttpSessions ().stream ();
683- }).collect (Collectors .toList ());
693+ .flatMap (account -> account .getHttpSessions ().stream ()).collect (Collectors .toList ());
684694 }
685695}
0 commit comments