Skip to content

Commit

Permalink
feat: email-based authentication codes for MFA/2FA
Browse files Browse the repository at this point in the history
Signed-off-by: Morten Svanaes <[email protected]>
  • Loading branch information
netroms committed Dec 2, 2024
1 parent ae2f970 commit e3aae1d
Show file tree
Hide file tree
Showing 8 changed files with 13 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public void enrollTOTP2FA(User user) {
}

/**
* Enroll user in email based two-factor authentication.
* Enroll user in email-based two-factor authentication.
*
* @param user The user object that is being enrolled.
*/
Expand All @@ -134,7 +134,7 @@ public void enrollEmail2FA(User user) {
*
* @param user The user to enable 2FA authentication.
* @param code The TOTP code that the user generated with the authenticator app, or the email code
* that was sent to the user.
* sent to the user.
*/
@Transactional
public void enable2FA(User user, String code) {
Expand All @@ -158,15 +158,6 @@ public void setEnabled2FA(User user, UserDetails actingUser) {
userService.updateUser(user, actingUser);
}

public void setEnabled2FA(UserDetails userDetails, UserDetails actingUser) {
User user = userService.getUserByUsername(userDetails.getUsername());
if (!user.getTwoFactorType().isEnrolling()) {
throw new IllegalStateException("Two factor type is not enrolling");
}
user.setTwoFactorType(user.getTwoFactorType().getEnabledType());
userService.updateUser(user, actingUser);
}

/**
* If the user has 2FA authentication enabled, and the code is valid, then disable 2FA
* authentication.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ private TwoFactorAuthUtils() {
* @param qrContent content to be used for generating the QR code.
* @param width width of the generated PNG image.
* @param height height of the generated PNG image.
* @return PNG image as byte array.
* @return PNG image as a byte array.
*/
public static byte[] generateQRCode(
String qrContent, int width, int height, Consumer<ErrorCode> errorCode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1456,12 +1456,6 @@ public boolean sendEmailVerificationToken(User user, String token, String reques
@Override
@Transactional
public boolean verifyEmail(String token) {

List<User> all = userStore.getAll();
for (User user : all) {
log.error("User: " + user.getUsername() + " " + user.getEmailVerificationToken());
}

User user = getUserByEmailVerificationToken(token);
if (user == null) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,10 +661,10 @@ public List<User> getUsersWithOrgUnit(
@Nonnull UserOrgUnitProperty orgUnitProperty, @Nonnull UID uid) {
return getQuery(
"""
select distinct u from User u
left join fetch u.%s ous
where ous.uid = :uid
"""
select distinct u from User u
left join fetch u.%s ous
where ous.uid = :uid
"""
.formatted(orgUnitProperty.getValue()))
.setParameter("uid", uid.getValue())
.getResultList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public class UserObjectBundleHook extends AbstractObjectBundleHook<User> {
public static final String PRE_UPDATE_USER_KEY = "preUpdateUser";

private final UserService userService;

private final TwoFactorAuthService validateTwoFactorUpdate;

private final FileResourceService fileResourceService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,21 +210,13 @@ private static Authentication createAuthenticationToken(

private void saveContext(
HttpServletRequest request, HttpServletResponse response, Authentication authentication) {

SecurityContext context = this.securityContextHolderStrategy.createEmptyContext();
context.setAuthentication(authentication);

// Get or create the session explicitly
HttpSession session = request.getSession(true);

// Set the security context in session
// session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
// context);

this.securityContextHolderStrategy.setContext(context);
this.securityContextRepository.saveContext(context, request, response);

// Notify the session registry
HttpSession session = request.getSession(true);
httpSessionEventPublisher.sessionCreated(new HttpSessionEvent(session));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public boolean isEnabled(@CurrentUser(required = true) User currentUser) {
}

/**
* Enable 2FA authentication for the current user, if the user is the enrollment mode and the code
* Enable 2FA authentication for the current user if the user is the enrollment mode and the code
* is valid.
*
* @param body The body of the request.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ public RedisIndexedSessionRepository sessionRepository(
public CookieHttpSessionIdResolver httpSessionIdResolver() {
CookieHttpSessionIdResolver resolver = new CookieHttpSessionIdResolver();
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setCookieName("JSESSIONID"); // Use the traditional name
cookieSerializer.setSameSite("Lax"); // Match your security requirements
cookieSerializer.setCookieName("JSESSIONID");
cookieSerializer.setSameSite("Lax");
cookieSerializer.setUseSecureCookie(false);
cookieSerializer.setUseHttpOnlyCookie(true);
resolver.setCookieSerializer(cookieSerializer);
return resolver;
}

@Bean
public SpringSessionBackedSessionRegistry<?> sessionRegistry(
public SpringSessionBackedSessionRegistry sessionRegistry(
RedisIndexedSessionRepository sessionRepository) {
return new SpringSessionBackedSessionRegistry<>(sessionRepository);
}
Expand Down

0 comments on commit e3aae1d

Please sign in to comment.