Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
docker start FileFighterDB
-
name: Run Tests and update Sonar
run: mvn clean test sonar:sonar -s ./settings.xml
run: mvn clean verify sonar:sonar -s ./settings.xml
env:
SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }}
SONAR_PASSWORD: ${{ secrets.SONAR_PASSWORD }}
32 changes: 32 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,38 @@
<goal>report</goal>
</goals>
</execution>
<!-- attached to Maven verify phase -->
<execution>
<id>check</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>CLASS</element>
<includes>
<include>*BusinessService</include>
<include>*Controller</include>
<include>*Service</include>
</includes>
<excludes>
<!-- NOT IMPLEMENTED YET -->
<exclude>*FileSystemRestService</exclude>
<exclude>*PermissionRestService</exclude>
</excludes>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>95%</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package de.filefighter.rest.domain.common;

import de.filefighter.rest.rest.exceptions.RequestDidntMeetFormalRequirementsException;
import org.springframework.stereotype.Service;

@Service
public class InputSanitizerService {

public static boolean stringIsValid(String s) {
return !(null == s || s.isEmpty() || s.isBlank());
}

/**
*
* Sanitizes a String, so it can be used.
* @param string String that needs to be sanitized.
* @return string without whitespaces and without illegal characters.
* @throws RequestDidntMeetFormalRequirementsException when string was empty.
*/
public static String sanitizeString(String string) {
if(!InputSanitizerService.stringIsValid(string))
throw new RequestDidntMeetFormalRequirementsException("String was empty");
return string.replaceAll("\\s", "");
}

public String sanitizeRequestHeader(String header, String testString) {
if (!(stringIsValid(testString) && stringIsValid(header)))
throw new RequestDidntMeetFormalRequirementsException("Header does not contain a valid String.");

if (!testString.matches("^" + header + "[^\\s](.*)$"))
throw new RequestDidntMeetFormalRequirementsException("Header does not contain '" + header + "', or format is invalid.");
String[] split = testString.split(header);
return split[1];
}

public String sanitizeTokenValue(String tokenValue){
return InputSanitizerService.sanitizeString(tokenValue);
}
}
28 changes: 0 additions & 28 deletions src/main/java/de/filefighter/rest/domain/common/Utils.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@
import de.filefighter.rest.domain.user.data.dto.User;
import de.filefighter.rest.domain.user.exceptions.UserNotAuthenticatedException;
import de.filefighter.rest.rest.exceptions.FileFighterDataException;
import de.filefighter.rest.rest.exceptions.RequestDidntMeetFormalRequirementsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.UUID;

import static de.filefighter.rest.configuration.RestConfiguration.AUTHORIZATION_BEARER_PREFIX;
import static de.filefighter.rest.domain.common.Utils.stringIsValid;
import static de.filefighter.rest.domain.common.Utils.validateAuthorizationHeader;

@Service
public class AccessTokenBusinessService {

Expand Down Expand Up @@ -67,9 +62,6 @@ public AccessToken getValidAccessTokenForUser(User user) {
}

public AccessToken findAccessTokenByValueAndUserId(String accessTokenValue, long userId) {
if (!stringIsValid(accessTokenValue))
throw new RequestDidntMeetFormalRequirementsException("Value of AccessToken was not valid.");

AccessTokenEntity accessTokenEntity = accessTokenRepository.findByUserIdAndValue(userId, accessTokenValue);
if (null == accessTokenEntity)
throw new UserNotAuthenticatedException(userId);
Expand All @@ -78,26 +70,13 @@ public AccessToken findAccessTokenByValueAndUserId(String accessTokenValue, long
}

public AccessToken findAccessTokenByValue(String accessTokenValue) {
if (!stringIsValid(accessTokenValue))
throw new RequestDidntMeetFormalRequirementsException("Value of AccessToken was not valid.");

AccessTokenEntity accessTokenEntity = accessTokenRepository.findByValue(accessTokenValue);
if (null == accessTokenEntity)
throw new UserNotAuthenticatedException("AccessToken not found.");

return accessTokenDtoService.createDto(accessTokenEntity);
}


public AccessToken validateAccessTokenValueWithHeader(String accessTokenValue) {
String cleanValue = validateAuthorizationHeader(AUTHORIZATION_BEARER_PREFIX, accessTokenValue);
AccessTokenEntity accessTokenEntity = accessTokenRepository.findByValue(cleanValue);
if (null == accessTokenEntity)
throw new UserNotAuthenticatedException("AccessToken not found.");

return accessTokenDtoService.createDto(accessTokenEntity);
}

public static String generateRandomTokenValue() {
return UUID.randomUUID().toString();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package de.filefighter.rest.domain.user.business;

import de.filefighter.rest.domain.common.Utils;
import de.filefighter.rest.domain.common.InputSanitizerService;
import de.filefighter.rest.domain.token.data.dto.AccessToken;
import de.filefighter.rest.domain.user.data.dto.User;
import de.filefighter.rest.domain.user.data.persistance.UserEntity;
Expand All @@ -15,10 +15,6 @@
import java.nio.charset.StandardCharsets;
import java.util.Base64;

import static de.filefighter.rest.configuration.RestConfiguration.AUTHORIZATION_BASIC_PREFIX;
import static de.filefighter.rest.configuration.RestConfiguration.AUTHORIZATION_BEARER_PREFIX;
import static de.filefighter.rest.domain.common.Utils.removeWhiteSpaces;

@Service
public class UserAuthorizationService {

Expand All @@ -32,9 +28,7 @@ public UserAuthorizationService(UserRepository userRepository, UserDtoService us
this.userDtoService = userDtoService;
}

public User authenticateUserWithUsernameAndPassword(String base64encodedUserAndPasswordWithHeader) {
String base64encodedUserAndPassword = Utils.validateAuthorizationHeader(AUTHORIZATION_BASIC_PREFIX, base64encodedUserAndPasswordWithHeader);

public User authenticateUserWithUsernameAndPassword(String base64encodedUserAndPassword) {
String decodedUsernameAndPassword = "";
try {
byte[] decodedValue = Base64.getDecoder().decode(base64encodedUserAndPassword);
Expand All @@ -49,8 +43,8 @@ public User authenticateUserWithUsernameAndPassword(String base64encodedUserAndP
if (split.length != 2)
throw new RequestDidntMeetFormalRequirementsException("Credentials didnt meet formal requirements.");

String lowerCaseUsername = removeWhiteSpaces(split[0].toLowerCase()); //no nullPointerException possible here.
String password = split[1];
String lowerCaseUsername = InputSanitizerService.sanitizeString(split[0].toLowerCase());
String password = InputSanitizerService.sanitizeString(split[1]);

UserEntity userEntity = userRepository.findByLowercaseUsernameAndPassword(lowerCaseUsername, password);
if (null == userEntity)
Expand All @@ -60,8 +54,7 @@ public User authenticateUserWithUsernameAndPassword(String base64encodedUserAndP
}

public User authenticateUserWithRefreshToken(String refreshToken) {
String cleanValue = Utils.validateAuthorizationHeader(AUTHORIZATION_BEARER_PREFIX, refreshToken);
UserEntity userEntity = userRepository.findByRefreshToken(cleanValue);
UserEntity userEntity = userRepository.findByRefreshToken(refreshToken);
if (null == userEntity)
throw new UserNotAuthenticatedException("No user found for this Refresh Token.");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.filefighter.rest.domain.user.business;

import de.filefighter.rest.domain.common.Utils;
import de.filefighter.rest.domain.token.business.AccessTokenBusinessService;
import de.filefighter.rest.domain.token.data.dto.RefreshToken;
import de.filefighter.rest.domain.user.data.dto.User;
Expand All @@ -26,8 +25,8 @@
import java.util.Arrays;
import java.util.regex.Pattern;

import static de.filefighter.rest.domain.common.Utils.removeWhiteSpaces;
import static de.filefighter.rest.domain.common.Utils.stringIsValid;
import static de.filefighter.rest.domain.common.InputSanitizerService.sanitizeString;
import static de.filefighter.rest.domain.common.InputSanitizerService.stringIsValid;

@Service
public class UserBusinessService {
Expand All @@ -37,7 +36,6 @@ public class UserBusinessService {
private final GroupRepository groupRepository;
private final MongoTemplate mongoTemplate;


private static final Logger LOG = LoggerFactory.getLogger(UserBusinessService.class);
public static final int USER_ID_MAX = 99999999;

Expand Down Expand Up @@ -86,7 +84,7 @@ public User findUserByUsername(String username) {
if (!stringIsValid(username))
throw new RequestDidntMeetFormalRequirementsException("Username was not valid.");

String lowercaseUsername = removeWhiteSpaces(username.toLowerCase());
String lowercaseUsername = sanitizeString(username.toLowerCase());

UserEntity entity = userRepository.findByLowercaseUsername(lowercaseUsername);
if (null == entity)
Expand Down Expand Up @@ -146,7 +144,7 @@ public void registerNewUser(UserRegisterForm newUser) {
}

public boolean passwordIsValid(String password) {
if (!Utils.stringIsValid(password))
if (!stringIsValid(password))
return false;

if (this.passwordCheckDisabled) return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.filefighter.rest.domain.user.rest;

import de.filefighter.rest.domain.common.InputSanitizerService;
import de.filefighter.rest.domain.token.business.AccessTokenBusinessService;
import de.filefighter.rest.domain.token.data.dto.AccessToken;
import de.filefighter.rest.domain.token.data.dto.RefreshToken;
Expand All @@ -12,6 +13,8 @@
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import static de.filefighter.rest.configuration.RestConfiguration.AUTHORIZATION_BASIC_PREFIX;
import static de.filefighter.rest.configuration.RestConfiguration.AUTHORIZATION_BEARER_PREFIX;
import static de.filefighter.rest.domain.user.group.Groups.ADMIN;


Expand All @@ -21,56 +24,75 @@ public class UserRestService implements UserRestServiceInterface {
private final UserBusinessService userBusinessService;
private final UserAuthorizationService userAuthorizationService;
private final AccessTokenBusinessService accessTokenBusinessService;
private final InputSanitizerService inputSanitizerService;

public UserRestService(UserBusinessService userBusinessService, UserAuthorizationService userAuthorizationService, AccessTokenBusinessService accessTokenBusinessService) {
public UserRestService(UserBusinessService userBusinessService, UserAuthorizationService userAuthorizationService, AccessTokenBusinessService accessTokenBusinessService, InputSanitizerService inputSanitizerService) {
this.userBusinessService = userBusinessService;
this.userAuthorizationService = userAuthorizationService;
this.accessTokenBusinessService = accessTokenBusinessService;
this.inputSanitizerService = inputSanitizerService;
}

@Override
public ResponseEntity<User> getUserByUserIdAuthenticateWithAccessToken(String accessToken, long userId) {
AccessToken validAccessToken = accessTokenBusinessService.validateAccessTokenValueWithHeader(accessToken);
public ResponseEntity<User> getUserByUserIdAuthenticateWithAccessToken(String accessTokenWithHeader, long userId) {
String sanitizedHeaderValue = inputSanitizerService.sanitizeRequestHeader(AUTHORIZATION_BEARER_PREFIX, accessTokenWithHeader);
String sanitizedTokenString = inputSanitizerService.sanitizeTokenValue(sanitizedHeaderValue);

AccessToken validAccessToken = accessTokenBusinessService.findAccessTokenByValue(sanitizedTokenString);
userAuthorizationService.authenticateUserWithAccessToken(validAccessToken);
User user = userBusinessService.getUserById(userId);
return new ResponseEntity<>(user, HttpStatus.OK);
}

@Override
public ResponseEntity<RefreshToken> getRefreshTokenWithUsernameAndPassword(String base64encodedUserAndPasswordWithHeader) {
User authenticatedUser = userAuthorizationService.authenticateUserWithUsernameAndPassword(base64encodedUserAndPasswordWithHeader);
String sanitizedHeaderValue = inputSanitizerService.sanitizeRequestHeader(AUTHORIZATION_BASIC_PREFIX, base64encodedUserAndPasswordWithHeader);

User authenticatedUser = userAuthorizationService.authenticateUserWithUsernameAndPassword(sanitizedHeaderValue);
RefreshToken refreshToken = userBusinessService.getRefreshTokenForUser(authenticatedUser);
return new ResponseEntity<>(refreshToken, HttpStatus.OK);
}

@Override
public ResponseEntity<AccessToken> getAccessTokenByRefreshToken(String refreshTokenWithHeader) {
User user = userAuthorizationService.authenticateUserWithRefreshToken(refreshTokenWithHeader);
String sanitizedHeaderValue = inputSanitizerService.sanitizeRequestHeader(AUTHORIZATION_BEARER_PREFIX, refreshTokenWithHeader);
String sanitizedTokenString = inputSanitizerService.sanitizeTokenValue(sanitizedHeaderValue);

User user = userAuthorizationService.authenticateUserWithRefreshToken(sanitizedTokenString);
AccessToken accessToken = accessTokenBusinessService.getValidAccessTokenForUser(user);
return new ResponseEntity<>(accessToken, HttpStatus.OK);
}

@Override
public ResponseEntity<ServerResponse> updateUserByUserIdAuthenticateWithAccessToken(UserRegisterForm updatedUser, long userId, String accessTokenValue) {
AccessToken accessToken = accessTokenBusinessService.validateAccessTokenValueWithHeader(accessTokenValue);
public ResponseEntity<ServerResponse> updateUserByUserIdAuthenticateWithAccessToken(UserRegisterForm updatedUser, long userId, String accessTokenHeader) {
String sanitizedHeaderValue = inputSanitizerService.sanitizeRequestHeader(AUTHORIZATION_BEARER_PREFIX, accessTokenHeader);
String sanitizedTokenString = inputSanitizerService.sanitizeTokenValue(sanitizedHeaderValue);

AccessToken accessToken = accessTokenBusinessService.findAccessTokenByValue(sanitizedTokenString);
User authenticatedUser = userAuthorizationService.authenticateUserWithAccessToken(accessToken);
userBusinessService.updateUser(userId, updatedUser, authenticatedUser);
ServerResponse response = new ServerResponse(HttpStatus.CREATED, "User successfully updated.");
return new ResponseEntity<>(response, HttpStatus.CREATED);
}

@Override
public ResponseEntity<ServerResponse> registerNewUserWithAccessToken(UserRegisterForm newUser, String accessToken) {
AccessToken validAccessToken = accessTokenBusinessService.validateAccessTokenValueWithHeader(accessToken);
public ResponseEntity<ServerResponse> registerNewUserWithAccessToken(UserRegisterForm newUser, String accessTokenHeader) {
String sanitizedHeaderValue = inputSanitizerService.sanitizeRequestHeader(AUTHORIZATION_BEARER_PREFIX, accessTokenHeader);
String sanitizedTokenString = inputSanitizerService.sanitizeTokenValue(sanitizedHeaderValue);

AccessToken validAccessToken = accessTokenBusinessService.findAccessTokenByValue(sanitizedTokenString);
userAuthorizationService.authenticateUserWithAccessTokenAndGroup(validAccessToken, ADMIN);
userBusinessService.registerNewUser(newUser);
return new ResponseEntity<>(new ServerResponse(HttpStatus.CREATED, "User successfully created."), HttpStatus.CREATED);
}

@Override
public ResponseEntity<User> findUserByUsernameAndAccessToken(String username, String accessToken) {
AccessToken token = accessTokenBusinessService.validateAccessTokenValueWithHeader(accessToken);
userAuthorizationService.authenticateUserWithAccessToken(token);
public ResponseEntity<User> findUserByUsernameAndAccessToken(String username, String accessTokenHeader) {
String sanitizedHeaderValue = inputSanitizerService.sanitizeRequestHeader(AUTHORIZATION_BEARER_PREFIX, accessTokenHeader);
String sanitizedTokenString = inputSanitizerService.sanitizeTokenValue(sanitizedHeaderValue);

AccessToken accessToken = accessTokenBusinessService.findAccessTokenByValue(sanitizedTokenString);
userAuthorizationService.authenticateUserWithAccessToken(accessToken);
User foundUser = userBusinessService.findUserByUsername(username);
return new ResponseEntity<>(foundUser, HttpStatus.OK);
}
Expand Down
Loading