normalize line endings

This commit is contained in:
Athou
2025-03-10 08:38:21 +01:00
parent ec4554c76e
commit fb7f041454
223 changed files with 18091 additions and 18093 deletions

View File

@@ -1,30 +1,30 @@
package com.commafeed.security;
import jakarta.inject.Singleton;
import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.model.User;
import io.quarkus.security.identity.SecurityIdentity;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Singleton
public class AuthenticationContext {
private final SecurityIdentity securityIdentity;
private final UserDAO userDAO;
public User getCurrentUser() {
if (securityIdentity.isAnonymous()) {
return null;
}
String userId = securityIdentity.getPrincipal().getName();
if (userId == null) {
return null;
}
return userDAO.findById(Long.valueOf(userId));
}
}
package com.commafeed.security;
import jakarta.inject.Singleton;
import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.model.User;
import io.quarkus.security.identity.SecurityIdentity;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Singleton
public class AuthenticationContext {
private final SecurityIdentity securityIdentity;
private final UserDAO userDAO;
public User getCurrentUser() {
if (securityIdentity.isAnonymous()) {
return null;
}
String userId = securityIdentity.getPrincipal().getName();
if (userId == null) {
return null;
}
return userDAO.findById(Long.valueOf(userId));
}
}

View File

@@ -1,6 +1,6 @@
package com.commafeed.security;
public class Roles {
public static final String USER = "USER";
public static final String ADMIN = "ADMIN";
}
package com.commafeed.security;
public class Roles {
public static final String USER = "USER";
public static final String ADMIN = "ADMIN";
}

View File

@@ -1,51 +1,51 @@
package com.commafeed.security.identity;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.inject.Singleton;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.service.UserService;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.TokenAuthenticationRequest;
import io.quarkus.security.runtime.QuarkusPrincipal;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Singleton
public class DatabaseApiKeyIdentityProvider implements IdentityProvider<TokenAuthenticationRequest> {
private final UnitOfWork unitOfWork;
private final UserService userService;
@Override
public Class<TokenAuthenticationRequest> getRequestType() {
return TokenAuthenticationRequest.class;
}
@Override
public Uni<SecurityIdentity> authenticate(TokenAuthenticationRequest request, AuthenticationRequestContext context) {
return context.runBlocking(() -> {
Optional<User> user = unitOfWork.call(() -> userService.login(request.getToken().getToken()));
if (user.isEmpty()) {
throw new AuthenticationFailedException("could not find a user with this api key");
}
Set<Role> roles = unitOfWork.call(() -> userService.getRoles(user.get()));
return QuarkusSecurityIdentity.builder()
.setPrincipal(new QuarkusPrincipal(String.valueOf(user.get().getId())))
.addRoles(roles.stream().map(Enum::name).collect(Collectors.toSet()))
.build();
});
}
}
package com.commafeed.security.identity;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.inject.Singleton;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.service.UserService;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.TokenAuthenticationRequest;
import io.quarkus.security.runtime.QuarkusPrincipal;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Singleton
public class DatabaseApiKeyIdentityProvider implements IdentityProvider<TokenAuthenticationRequest> {
private final UnitOfWork unitOfWork;
private final UserService userService;
@Override
public Class<TokenAuthenticationRequest> getRequestType() {
return TokenAuthenticationRequest.class;
}
@Override
public Uni<SecurityIdentity> authenticate(TokenAuthenticationRequest request, AuthenticationRequestContext context) {
return context.runBlocking(() -> {
Optional<User> user = unitOfWork.call(() -> userService.login(request.getToken().getToken()));
if (user.isEmpty()) {
throw new AuthenticationFailedException("could not find a user with this api key");
}
Set<Role> roles = unitOfWork.call(() -> userService.getRoles(user.get()));
return QuarkusSecurityIdentity.builder()
.setPrincipal(new QuarkusPrincipal(String.valueOf(user.get().getId())))
.addRoles(roles.stream().map(Enum::name).collect(Collectors.toSet()))
.build();
});
}
}

View File

@@ -1,52 +1,52 @@
package com.commafeed.security.identity;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.inject.Singleton;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.service.UserService;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest;
import io.quarkus.security.runtime.QuarkusPrincipal;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Singleton
public class DatabaseUsernamePasswordIdentityProvider implements IdentityProvider<UsernamePasswordAuthenticationRequest> {
private final UnitOfWork unitOfWork;
private final UserService userService;
@Override
public Class<UsernamePasswordAuthenticationRequest> getRequestType() {
return UsernamePasswordAuthenticationRequest.class;
}
@Override
public Uni<SecurityIdentity> authenticate(UsernamePasswordAuthenticationRequest request, AuthenticationRequestContext context) {
return context.runBlocking(() -> {
Optional<User> user = unitOfWork
.call(() -> userService.login(request.getUsername(), new String(request.getPassword().getPassword())));
if (user.isEmpty()) {
throw new AuthenticationFailedException("wrong username or password");
}
Set<Role> roles = unitOfWork.call(() -> userService.getRoles(user.get()));
return QuarkusSecurityIdentity.builder()
.setPrincipal(new QuarkusPrincipal(String.valueOf(user.get().getId())))
.addRoles(roles.stream().map(Enum::name).collect(Collectors.toSet()))
.build();
});
}
}
package com.commafeed.security.identity;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.inject.Singleton;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.service.UserService;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest;
import io.quarkus.security.runtime.QuarkusPrincipal;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Singleton
public class DatabaseUsernamePasswordIdentityProvider implements IdentityProvider<UsernamePasswordAuthenticationRequest> {
private final UnitOfWork unitOfWork;
private final UserService userService;
@Override
public Class<UsernamePasswordAuthenticationRequest> getRequestType() {
return UsernamePasswordAuthenticationRequest.class;
}
@Override
public Uni<SecurityIdentity> authenticate(UsernamePasswordAuthenticationRequest request, AuthenticationRequestContext context) {
return context.runBlocking(() -> {
Optional<User> user = unitOfWork
.call(() -> userService.login(request.getUsername(), new String(request.getPassword().getPassword())));
if (user.isEmpty()) {
throw new AuthenticationFailedException("wrong username or password");
}
Set<Role> roles = unitOfWork.call(() -> userService.getRoles(user.get()));
return QuarkusSecurityIdentity.builder()
.setPrincipal(new QuarkusPrincipal(String.valueOf(user.get().getId())))
.addRoles(roles.stream().map(Enum::name).collect(Collectors.toSet()))
.build();
});
}
}

View File

@@ -1,58 +1,58 @@
package com.commafeed.security.identity;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.inject.Singleton;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.service.UserService;
import com.commafeed.backend.service.internal.PostLoginActivities;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.TrustedAuthenticationRequest;
import io.quarkus.security.runtime.QuarkusPrincipal;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Singleton
public class TrustedIdentityProvider implements IdentityProvider<TrustedAuthenticationRequest> {
private final UnitOfWork unitOfWork;
private final UserService userService;
private final UserDAO userDAO;
private final PostLoginActivities postLoginActivities;
@Override
public Class<TrustedAuthenticationRequest> getRequestType() {
return TrustedAuthenticationRequest.class;
}
@Override
public Uni<SecurityIdentity> authenticate(TrustedAuthenticationRequest request, AuthenticationRequestContext context) {
return context.runBlocking(() -> {
Long userId = Long.valueOf(request.getPrincipal());
User user = unitOfWork.call(() -> userDAO.findById(userId));
if (user == null) {
throw new AuthenticationFailedException("user not found");
}
// execute post login activities manually because we didn't call login() since we received a trusted authentication request
unitOfWork.run(() -> postLoginActivities.executeFor(user));
Set<Role> roles = unitOfWork.call(() -> userService.getRoles(user));
return QuarkusSecurityIdentity.builder()
.setPrincipal(new QuarkusPrincipal(String.valueOf(userId)))
.addRoles(roles.stream().map(Enum::name).collect(Collectors.toSet()))
.build();
});
}
}
package com.commafeed.security.identity;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.inject.Singleton;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.service.UserService;
import com.commafeed.backend.service.internal.PostLoginActivities;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.TrustedAuthenticationRequest;
import io.quarkus.security.runtime.QuarkusPrincipal;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Singleton
public class TrustedIdentityProvider implements IdentityProvider<TrustedAuthenticationRequest> {
private final UnitOfWork unitOfWork;
private final UserService userService;
private final UserDAO userDAO;
private final PostLoginActivities postLoginActivities;
@Override
public Class<TrustedAuthenticationRequest> getRequestType() {
return TrustedAuthenticationRequest.class;
}
@Override
public Uni<SecurityIdentity> authenticate(TrustedAuthenticationRequest request, AuthenticationRequestContext context) {
return context.runBlocking(() -> {
Long userId = Long.valueOf(request.getPrincipal());
User user = unitOfWork.call(() -> userDAO.findById(userId));
if (user == null) {
throw new AuthenticationFailedException("user not found");
}
// execute post login activities manually because we didn't call login() since we received a trusted authentication request
unitOfWork.run(() -> postLoginActivities.executeFor(user));
Set<Role> roles = unitOfWork.call(() -> userService.getRoles(user));
return QuarkusSecurityIdentity.builder()
.setPrincipal(new QuarkusPrincipal(String.valueOf(userId)))
.addRoles(roles.stream().map(Enum::name).collect(Collectors.toSet()))
.build();
});
}
}

View File

@@ -1,47 +1,47 @@
package com.commafeed.security.mechanism;
import java.util.Optional;
import java.util.Set;
import jakarta.inject.Singleton;
import io.quarkus.security.credential.TokenCredential;
import io.quarkus.security.identity.IdentityProviderManager;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.AuthenticationRequest;
import io.quarkus.security.identity.request.TokenAuthenticationRequest;
import io.quarkus.vertx.http.runtime.security.ChallengeData;
import io.quarkus.vertx.http.runtime.security.HttpAuthenticationMechanism;
import io.smallrye.mutiny.Uni;
import io.vertx.ext.web.RoutingContext;
@Singleton
public class ApiKeyAuthenticationMecanism implements HttpAuthenticationMechanism {
@Override
public Uni<SecurityIdentity> authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
// only authorize api key for GET requests
if (!context.request().method().name().equals("GET")) {
return Uni.createFrom().optional(Optional.empty());
}
String apiKey = context.request().getParam("apiKey");
if (apiKey == null) {
return Uni.createFrom().optional(Optional.empty());
}
TokenCredential token = new TokenCredential(apiKey, "apiKey");
TokenAuthenticationRequest request = new TokenAuthenticationRequest(token);
return identityProviderManager.authenticate(request);
}
@Override
public Uni<ChallengeData> getChallenge(RoutingContext context) {
return Uni.createFrom().optional(Optional.empty());
}
@Override
public Set<Class<? extends AuthenticationRequest>> getCredentialTypes() {
return Set.of(TokenAuthenticationRequest.class);
}
}
package com.commafeed.security.mechanism;
import java.util.Optional;
import java.util.Set;
import jakarta.inject.Singleton;
import io.quarkus.security.credential.TokenCredential;
import io.quarkus.security.identity.IdentityProviderManager;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.AuthenticationRequest;
import io.quarkus.security.identity.request.TokenAuthenticationRequest;
import io.quarkus.vertx.http.runtime.security.ChallengeData;
import io.quarkus.vertx.http.runtime.security.HttpAuthenticationMechanism;
import io.smallrye.mutiny.Uni;
import io.vertx.ext.web.RoutingContext;
@Singleton
public class ApiKeyAuthenticationMecanism implements HttpAuthenticationMechanism {
@Override
public Uni<SecurityIdentity> authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
// only authorize api key for GET requests
if (!context.request().method().name().equals("GET")) {
return Uni.createFrom().optional(Optional.empty());
}
String apiKey = context.request().getParam("apiKey");
if (apiKey == null) {
return Uni.createFrom().optional(Optional.empty());
}
TokenCredential token = new TokenCredential(apiKey, "apiKey");
TokenAuthenticationRequest request = new TokenAuthenticationRequest(token);
return identityProviderManager.authenticate(request);
}
@Override
public Uni<ChallengeData> getChallenge(RoutingContext context) {
return Uni.createFrom().optional(Optional.empty());
}
@Override
public Set<Class<? extends AuthenticationRequest>> getCredentialTypes() {
return Set.of(TokenAuthenticationRequest.class);
}
}

View File

@@ -1,72 +1,72 @@
package com.commafeed.security.password;
import java.util.List;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.apache.commons.lang3.StringUtils;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
import org.passay.LengthRule;
import org.passay.PasswordData;
import org.passay.PasswordValidator;
import org.passay.RuleResult;
import org.passay.WhitespaceRule;
import lombok.Setter;
public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword, String> {
@Setter
private static boolean strict = true;
@Override
public void initialize(ValidPassword constraintAnnotation) {
// nothing to do
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (StringUtils.isBlank(value)) {
return true;
}
PasswordValidator validator = strict ? buildStrictPasswordValidator() : buildLoosePasswordValidator();
RuleResult result = validator.validate(new PasswordData(value));
if (result.isValid()) {
return true;
}
List<String> messages = validator.getMessages(result);
String message = String.join(System.lineSeparator(), messages);
context.buildConstraintViolationWithTemplate(message).addConstraintViolation().disableDefaultConstraintViolation();
return false;
}
private PasswordValidator buildStrictPasswordValidator() {
return new PasswordValidator(
// length
new LengthRule(8, 256),
// 1 uppercase char
new CharacterRule(EnglishCharacterData.UpperCase, 1),
// 1 lowercase char
new CharacterRule(EnglishCharacterData.LowerCase, 1),
// 1 digit
new CharacterRule(EnglishCharacterData.Digit, 1),
// 1 special char
new CharacterRule(EnglishCharacterData.Special, 1),
// no whitespace
new WhitespaceRule());
}
private PasswordValidator buildLoosePasswordValidator() {
return new PasswordValidator(
// length
new LengthRule(6, 256),
// no whitespace
new WhitespaceRule());
}
}
package com.commafeed.security.password;
import java.util.List;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.apache.commons.lang3.StringUtils;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
import org.passay.LengthRule;
import org.passay.PasswordData;
import org.passay.PasswordValidator;
import org.passay.RuleResult;
import org.passay.WhitespaceRule;
import lombok.Setter;
public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword, String> {
@Setter
private static boolean strict = true;
@Override
public void initialize(ValidPassword constraintAnnotation) {
// nothing to do
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (StringUtils.isBlank(value)) {
return true;
}
PasswordValidator validator = strict ? buildStrictPasswordValidator() : buildLoosePasswordValidator();
RuleResult result = validator.validate(new PasswordData(value));
if (result.isValid()) {
return true;
}
List<String> messages = validator.getMessages(result);
String message = String.join(System.lineSeparator(), messages);
context.buildConstraintViolationWithTemplate(message).addConstraintViolation().disableDefaultConstraintViolation();
return false;
}
private PasswordValidator buildStrictPasswordValidator() {
return new PasswordValidator(
// length
new LengthRule(8, 256),
// 1 uppercase char
new CharacterRule(EnglishCharacterData.UpperCase, 1),
// 1 lowercase char
new CharacterRule(EnglishCharacterData.LowerCase, 1),
// 1 digit
new CharacterRule(EnglishCharacterData.Digit, 1),
// 1 special char
new CharacterRule(EnglishCharacterData.Special, 1),
// no whitespace
new WhitespaceRule());
}
private PasswordValidator buildLoosePasswordValidator() {
return new PasswordValidator(
// length
new LengthRule(6, 256),
// no whitespace
new WhitespaceRule());
}
}

View File

@@ -1,23 +1,23 @@
package com.commafeed.security.password;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
@Documented
@Constraint(validatedBy = PasswordConstraintValidator.class)
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPassword {
String message() default "Invalid Password";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
package com.commafeed.security.password;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
@Documented
@Constraint(validatedBy = PasswordConstraintValidator.class)
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPassword {
String message() default "Invalid Password";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}