Skip to content

Commit

Permalink
feat: integrate anonymous authority
Browse files Browse the repository at this point in the history
  • Loading branch information
mebo4b committed May 20, 2021
1 parent e2fc992 commit ea2cb45
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 153 deletions.
8 changes: 4 additions & 4 deletions api/messageservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ paths:
post:
tags:
- message-controller
summary: 'Add new Rocket.Chat message [Authorization: Role: user, consultant,
summary: 'Add new Rocket.Chat message [Authorization: Role: user, anonymous, consultant,
technical]'
operationId: createMessage
parameters:
Expand Down Expand Up @@ -130,7 +130,7 @@ paths:
tags:
- message-controller
summary: 'Add new Rocket.Chat system video call event message [Authorization: Role: user,
consultant]'
anonymous, consultant]'
operationId: createVideoHintMessage
parameters:
- name: rcGroupId
Expand Down Expand Up @@ -161,7 +161,7 @@ paths:
get:
tags:
- message-controller
summary: 'Get Rocket.Chat message stream [Authorization: Role: user, consultant]'
summary: 'Get Rocket.Chat message stream [Authorization: Role: user, anonymous, consultant]'
operationId: getMessageStream
parameters:
- name: rcToken
Expand Down Expand Up @@ -248,7 +248,7 @@ paths:
post:
tags:
- message-controller
summary: 'Save a draft message [Authorization: Role: user, consultant]'
summary: 'Save a draft message [Authorization: Role: user, anonymous, consultant]'
operationId: saveDraftMessage
parameters:
- name: rcGroupId
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package de.caritas.cob.messageservice.api.authorization;

import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.ANONYMOUS_DEFAULT;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.ASSIGN_CONSULTANT_TO_ENQUIRY;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.ASSIGN_CONSULTANT_TO_SESSION;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.CONSULTANT_DEFAULT;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.TECHNICAL_DEFAULT;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.USER_DEFAULT;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.USE_FEEDBACK;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.VIEW_AGENCY_CONSULTANTS;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.VIEW_ALL_FEEDBACK_SESSIONS;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.VIEW_ALL_PEER_SESSIONS;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;

import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* Definition of all authorities and of the role-authority-mapping.
*/
@Getter
@AllArgsConstructor
public enum Authorities {

ANONYMOUS(Role.ANONYMOUS, singletonList(ANONYMOUS_DEFAULT)),
USER(Role.USER, singletonList(USER_DEFAULT)),
CONSULTANT(Role.CONSULTANT, singletonList(CONSULTANT_DEFAULT)),
U25_CONSULTANT(Role.U25_CONSULTANT, singletonList(USE_FEEDBACK)),
U25_MAIN_CONSULTANT(Role.U25_MAIN_CONSULTANT,
asList(VIEW_ALL_FEEDBACK_SESSIONS, VIEW_ALL_PEER_SESSIONS, ASSIGN_CONSULTANT_TO_SESSION,
ASSIGN_CONSULTANT_TO_ENQUIRY, VIEW_AGENCY_CONSULTANTS)),
TECHNICAL(Role.TECHNICAL, singletonList(TECHNICAL_DEFAULT));

private final Role userRole;
private final List<String> grantedAuthorities;

/**
* Get all authorities for a specific role.
*
* @param userRole the user role
* @return the related authorities
*/
public static List<String> getAuthoritiesByUserRole(Role userRole) {
Optional<Authorities> authorityByUserRole = Stream.of(values())
.filter(authority -> authority.userRole.equals(userRole))
.findFirst();

return authorityByUserRole.isPresent() ? authorityByUserRole.get().getGrantedAuthorities()
: emptyList();
}

public static class Authority {

private Authority() {
}

public static final String PREFIX = "AUTHORIZATION_";

public static final String CONSULTANT_DEFAULT = PREFIX + "CONSULTANT_DEFAULT";
public static final String USER_DEFAULT = PREFIX + "USER_DEFAULT";
public static final String USE_FEEDBACK = PREFIX + "USE_FEEDBACK";
public static final String VIEW_ALL_FEEDBACK_SESSIONS = PREFIX + "VIEW_ALL_FEEDBACK_SESSIONS";
public static final String VIEW_ALL_PEER_SESSIONS = PREFIX + "VIEW_ALL_PEER_SESSIONS";
public static final String ASSIGN_CONSULTANT_TO_SESSION =
PREFIX + "ASSIGN_CONSULTANT_TO_SESSION";
public static final String ASSIGN_CONSULTANT_TO_ENQUIRY =
PREFIX + "ASSIGN_CONSULTANT_TO_ENQUIRY";
public static final String VIEW_AGENCY_CONSULTANTS = PREFIX + "VIEW_AGENCY_CONSULTANTS";
public static final String TECHNICAL_DEFAULT = PREFIX + "TECHNICAL_DEFAULT";
public static final String ANONYMOUS_DEFAULT = PREFIX + "ANONYMOUS_DEFAULT";

}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
package de.caritas.cob.messageservice.api.authorization;

import java.util.Arrays;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
*
* All used Keycloak roles
*
* All used Keycloak roles.
*/
@Getter
@AllArgsConstructor
public enum Role {

TECHNICAL("technical"),
USER("user"),
CONSULTANT("consultant"),
U25_CONSULTANT("u25-consultant"),
U25_MAIN_CONSULTANT("u25-main-consultant"),
ANONYMOUS("anonymous");

public class Role {
private final String roleName;

public static String TECHNICAL = "technical";
public static String USER = "user";
public static String CONSULTANT = "consultant";
public static String U25_CONSULTANT = "u25-consultant";
public static String U25_MAIN_CONSULTANT = "u25-main-consultant";
public static Optional<Role> getRoleByName(String roleName) {
return Arrays.stream(values())
.filter(userRole -> userRole.roleName.equals(roleName))
.findFirst();
}

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package de.caritas.cob.messageservice.api.authorization;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.security.core.GrantedAuthority;
Expand All @@ -12,32 +10,31 @@
import org.springframework.stereotype.Component;

/**
*
* Own implementation of the Spring GrantedAuthoritiesMapper
*
* Own implementation of the Spring GrantedAuthoritiesMapper.
*/
@Component
public class RoleAuthorizationAuthorityMapper implements GrantedAuthoritiesMapper {

@Override
public Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities) {
Set<String> roleNames = authorities.stream().map(GrantedAuthority::getAuthority)
.map(String::toLowerCase).collect(Collectors.toSet());
Set<String> roleNames = authorities.stream()
.map(GrantedAuthority::getAuthority)
.map(String::toLowerCase)
.collect(Collectors.toSet());

HashSet<GrantedAuthority> mapped = new HashSet<>();
mapped.addAll(mapAuthorities(roleNames));

return mapped;
return mapAuthorities(roleNames);
}

private Set<GrantedAuthority> mapAuthorities(Set<String> roleNames) {
List<SimpleGrantedAuthority> grantendAuthorities = new ArrayList<SimpleGrantedAuthority>();
roleNames.forEach(roleName -> {
grantendAuthorities.addAll(Authority.getAuthoritiesByRoleName(roleName).stream()
.map(authority -> new SimpleGrantedAuthority(authority)).collect(Collectors.toList()));
});
return new HashSet<>(grantendAuthorities);
return roleNames.parallelStream()
.map(Role::getRoleByName)
.filter(Optional::isPresent)
.map(Optional::get)
.map(Authorities::getAuthoritiesByUserRole)
.flatMap(Collection::parallelStream)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toSet());
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.caritas.cob.messageservice.config;

import de.caritas.cob.messageservice.api.authorization.Authorities.Authority;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
Expand All @@ -13,19 +14,17 @@
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.config.core.GrantedAuthorityDefaults;
import de.caritas.cob.messageservice.api.authorization.Authority;

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {

@Override
protected AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters =
new ArrayList<AccessDecisionVoter<? extends Object>>();
ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
List<AccessDecisionVoter<?>> decisionVoters = new ArrayList<>();
var expressionAdvice = new ExpressionBasedPreInvocationAdvice();
expressionAdvice.setExpressionHandler(getExpressionHandler());
RoleVoter roleVoter = new RoleVoter();
var roleVoter = new RoleVoter();
roleVoter.setRolePrefix("");
decisionVoters.add(roleVoter);
decisionVoters.add(new AuthenticatedVoter());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package de.caritas.cob.messageservice.config;

import de.caritas.cob.messageservice.api.authorization.Authority;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.ANONYMOUS_DEFAULT;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.CONSULTANT_DEFAULT;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.TECHNICAL_DEFAULT;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.USER_DEFAULT;
import static de.caritas.cob.messageservice.api.authorization.Authorities.Authority.USE_FEEDBACK;

import de.caritas.cob.messageservice.api.authorization.RoleAuthorizationAuthorityMapper;
import de.caritas.cob.messageservice.filter.StatelessCsrfFilter;
import org.keycloak.adapters.KeycloakConfigResolver;
Expand Down Expand Up @@ -65,16 +70,15 @@ protected void configure(HttpSecurity http) throws Exception {
.sessionAuthenticationStrategy(sessionAuthenticationStrategy()).and().authorizeRequests()
.antMatchers(SpringFoxConfig.WHITE_LIST).permitAll()
.antMatchers("/messages/key")
.hasAuthority(Authority.TECHNICAL_DEFAULT)
.hasAuthority(TECHNICAL_DEFAULT)
.antMatchers("/messages", "/messages/draft", "/messages/videohint/new")
.hasAnyAuthority(Authority.USER_DEFAULT, Authority.CONSULTANT_DEFAULT)
.hasAnyAuthority(USER_DEFAULT, CONSULTANT_DEFAULT, ANONYMOUS_DEFAULT)
.antMatchers("/messages/new")
.hasAnyAuthority(Authority.USER_DEFAULT, Authority.CONSULTANT_DEFAULT,
Authority.TECHNICAL_DEFAULT)
.hasAnyAuthority(USER_DEFAULT, CONSULTANT_DEFAULT, TECHNICAL_DEFAULT, ANONYMOUS_DEFAULT)
.antMatchers("/messages/forward", "/messages/feedback/new")
.hasAnyAuthority(Authority.USE_FEEDBACK)
.hasAnyAuthority(USE_FEEDBACK)
.antMatchers("/messages/aliasonly/new")
.hasAuthority(Authority.USER_DEFAULT)
.hasAuthority(USER_DEFAULT)
.anyRequest()
.denyAll();
}
Expand Down Expand Up @@ -105,7 +109,7 @@ protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth,
RoleAuthorizationAuthorityMapper authorityMapper) {
KeycloakAuthenticationProvider keyCloakAuthProvider = keycloakAuthenticationProvider();
var keyCloakAuthProvider = keycloakAuthenticationProvider();
keyCloakAuthProvider.setGrantedAuthoritiesMapper(authorityMapper);
auth.authenticationProvider(keyCloakAuthProvider);
}
Expand All @@ -124,7 +128,7 @@ public void configureGlobal(final AuthenticationManagerBuilder auth,
@Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
KeycloakAuthenticationProcessingFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
var registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
Expand All @@ -136,7 +140,7 @@ public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistration
@Bean
public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
KeycloakPreAuthActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
var registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
Expand All @@ -148,7 +152,7 @@ public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
@Bean
public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(
KeycloakAuthenticatedActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
var registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
Expand All @@ -160,7 +164,7 @@ public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(
@Bean
public FilterRegistrationBean keycloakSecurityContextRequestFilterBean(
KeycloakSecurityContextRequestFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
var registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
Expand Down
Loading

0 comments on commit ea2cb45

Please sign in to comment.