Skip to content

Commit

Permalink
refactor : Modified to allow multiple permissions to be entered
Browse files Browse the repository at this point in the history
  • Loading branch information
wwan13 committed Jun 4, 2024
1 parent 8a7d75c commit 748c3cc
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

import org.springframework.http.HttpMethod;

import java.util.Set;

public interface RequestAccessManager {

void manageWithAuthentication(HttpMethod method, String uri, String role);
void manageWithAuthentication(HttpMethod method, String uri, Set<String> roles);

void manageWithoutAuthentication(HttpMethod method, String uri);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,23 @@
import org.springframework.http.HttpMethod;

import java.util.Map;
import java.util.Set;

public record AuthorizedRequest(
Map<Requests, Permissions> registered,
boolean isElseRequestPermit
) {

public boolean isAccessibleRequest(HttpMethod httpMethod, String requestUri, String role) {
public boolean isAccessibleRequest(
HttpMethod httpMethod,
String requestUri,
Set<String> roles
) {
return registered.keySet().stream()
.filter(requests -> requests.isRegistered(httpMethod, requestUri))
.map(registered::get)
.findFirst()
.map(permissions -> permissions.canAccess(role))
.map(permissions -> permissions.canAccess(roles))
.orElse(isElseRequestPermit);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,34 @@

import io.wwan13.wintersecurity.constant.DefaultAuthPattern;

import java.util.Optional;
import java.util.Set;

public record Permissions(
Set<String> roles
) {

public boolean canAccess(String enteredRole) {
public boolean canAccess(Set<String> enteredRoles) {
return roles.stream()
.anyMatch(role -> checkPermitAll(role) ||
checkAuthenticated(role, enteredRole) || hasRole(role, enteredRole));
checkAuthenticated(role, enteredRoles) || hasRole(role, enteredRoles));
}

private boolean checkPermitAll(String registeredRole) {
return registeredRole.equals(DefaultAuthPattern.PERMIT_ALL);
}

private boolean checkAuthenticated(String registeredRole, String enteredRole) {
private boolean checkAuthenticated(String registeredRole, Set<String> enteredRoles) {
Optional<String> anonymousRole = enteredRoles.stream()
.filter(DefaultAuthPattern.ANONYMOUS_ROLE::equals)
.findAny();

return registeredRole.equals(DefaultAuthPattern.AUTHENTICATED) &&
!enteredRole.equals(DefaultAuthPattern.ANONYMOUS_ROLE);
anonymousRole.isEmpty();
}

private boolean hasRole(String registeredRole, String enteredRole) {
return registeredRole.equals(enteredRole);
private boolean hasRole(String registeredRole, Set<String> enteredRoles) {
return enteredRoles.stream()
.anyMatch(registeredRole::equals);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.wwan13.wintersecurity.auth.TokenExtractor;
import io.wwan13.wintersecurity.constant.Constants;
import io.wwan13.wintersecurity.jwt.TokenDecoder;
import io.wwan13.wintersecurity.jwt.payload.util.RoleSerializer;
import org.springframework.http.HttpMethod;

import javax.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -57,12 +58,12 @@ private void actionIfTokenPresent(
RequestStorage storage
) {
Map<String, Object> claims = tokenDecoder.decode(token);
String role = (String) claims.get(Constants.PAYLOAD_KEY_USER_ROLE);
String rawRoles = (String) claims.get(Constants.PAYLOAD_KEY_USER_ROLE);

accessManager.manageWithAuthentication(
HttpMethod.resolve(request.getMethod()),
request.getRequestURI(),
role
RoleSerializer.deserialize(rawRoles)
);

storage.saveAll(claims);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import io.wwan13.wintersecurity.exception.unauthirized.UnauthorizedException;
import org.springframework.http.HttpMethod;

import java.util.Collections;
import java.util.Set;

public class HttpRequestAccessManager implements RequestAccessManager {

private final AuthorizedRequest authorizedRequest;
Expand All @@ -31,14 +34,18 @@ public HttpRequestAccessManager(AuthorizedRequest authorizedRequest) {
this.authorizedRequest = authorizedRequest;
}

public void manageWithAuthentication(HttpMethod method, String uri, String role) {
if (!authorizedRequest.isAccessibleRequest(method, uri, role)) {
public void manageWithAuthentication(
HttpMethod method,
String uri,
Set<String> roles
) {
if (!authorizedRequest.isAccessibleRequest(method, uri, roles)) {
throw new ForbiddenException();
}
}

public void manageWithoutAuthentication(HttpMethod method, String uri) {
String role = DefaultAuthPattern.ANONYMOUS_ROLE;
Set<String> role = Collections.singleton(DefaultAuthPattern.ANONYMOUS_ROLE);

if (!authorizedRequest.isAccessibleRequest(method, uri, role)) {
throw new UnauthorizedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.junit.jupiter.params.provider.CsvSource;
import org.springframework.http.HttpMethod;

import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
Expand Down Expand Up @@ -74,7 +76,7 @@ void should_JudgeRequestIsAccessible(

// when
boolean result = authorizedRequest
.isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, requestRole);
.isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, Set.of(requestRole));

// then
assertThat(result).isEqualTo(expected);
Expand Down Expand Up @@ -107,7 +109,7 @@ void should_AcceptUnregisteredRequest_when_AnyRequestPermitAll(

// when
boolean result = authorizedRequest
.isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, requestRole);
.isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, Set.of(requestRole));

// then
assertThat(result).isEqualTo(expected);
Expand Down Expand Up @@ -141,7 +143,7 @@ void should_BlockUnregisteredRequest_when_AnyRequestAuthenticated(

// when
boolean result = authorizedRequest
.isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, requestRole);
.isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, Set.of(requestRole));

// then
assertThat(result).isEqualTo(expected);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void should_AcceptOnlyRegisteredRoles_when_SomeRolesRegistered(
Permissions permissions = new Permissions(roles);

// when
boolean result = permissions.canAccess(enteredRole);
boolean result = permissions.canAccess(Set.of(enteredRole));

// then
assertThat(result).isEqualTo(expected);
Expand All @@ -72,7 +72,7 @@ void should_AcceptAll_when_RegisteredIsPermitAll(
Permissions permissions = new Permissions(roles);

// when
boolean result = permissions.canAccess(enteredRole);
boolean result = permissions.canAccess(Set.of(enteredRole));

// then
assertThat(result).isEqualTo(expected);
Expand All @@ -89,7 +89,7 @@ void should_AcceptAllValidRolesWithoutAnonymous_when_RegisteredIsAuthenticated(
Permissions permissions = new Permissions(roles);

// when
boolean result = permissions.canAccess(enteredRole);
boolean result = permissions.canAccess(Set.of(enteredRole));

// then
assertThat(result).isEqualTo(expected);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpMethod;

import java.util.Set;

import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

Expand Down Expand Up @@ -52,7 +54,7 @@ void should_PassWithoutException_when_ValidRequestEnteredWithAuthentication() {

// when, then
assertThatNoException()
.isThrownBy(() -> accessManager.manageWithAuthentication(method, uri, role));
.isThrownBy(() -> accessManager.manageWithAuthentication(method, uri, Set.of(role)));
}

@Test
Expand All @@ -63,7 +65,7 @@ void should_ThrowForbiddenException_when_InvalidRequestEnteredWithAuthentication
final String role = "ROLE_ADMIN";

// when, then
assertThatThrownBy(() -> accessManager.manageWithAuthentication(method, uri, role))
assertThatThrownBy(() -> accessManager.manageWithAuthentication(method, uri, Set.of(role)))
.isInstanceOf(ForbiddenException.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpMethod;

import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;

@Import({TestContextConfig.class})
Expand All @@ -46,7 +48,7 @@ void should_RegisteredInSpringIocWithEnteredValue_when_ContextLoaded(
) {
// given, when
boolean result = authorizedRequest
.isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, requestRole);
.isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, Set.of(requestRole));

// then
assertThat(result).isEqualTo(expected);
Expand Down

0 comments on commit 748c3cc

Please sign in to comment.