RoleUpdateInterceptor.java

1
package edu.ucsb.cs.scaffold.interceptors;
2
3
import edu.ucsb.cs.scaffold.repository.AdminRepository;
4
import edu.ucsb.cs.scaffold.repository.InstructorRepository;
5
import jakarta.servlet.http.HttpServletRequest;
6
import jakarta.servlet.http.HttpServletResponse;
7
import java.util.Collection;
8
import java.util.HashSet;
9
import java.util.Set;
10
import org.springframework.security.core.Authentication;
11
import org.springframework.security.core.GrantedAuthority;
12
import org.springframework.security.core.authority.SimpleGrantedAuthority;
13
import org.springframework.security.core.context.SecurityContext;
14
import org.springframework.security.core.context.SecurityContextHolder;
15
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
16
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
17
import org.springframework.stereotype.Component;
18
import org.springframework.web.servlet.HandlerInterceptor;
19
20
/**
21
 * Reloads a user's security context on each request so that role changes (admin/instructor added or
22
 * removed in the database) take effect without requiring re-login.
23
 */
24
@Component
25
public class RoleUpdateInterceptor implements HandlerInterceptor {
26
27
  private final AdminRepository adminRepository;
28
  private final InstructorRepository instructorRepository;
29
30
  public RoleUpdateInterceptor(
31
      AdminRepository adminRepository, InstructorRepository instructorRepository) {
32
    this.adminRepository = adminRepository;
33
    this.instructorRepository = instructorRepository;
34
  }
35
36
  @Override
37
  public boolean preHandle(
38
      HttpServletRequest request, HttpServletResponse response, Object handler) {
39
    SecurityContext securityContext = SecurityContextHolder.getContext();
40
    Authentication authentication = securityContext.getAuthentication();
41
42 1 1. preHandle : negated conditional → KILLED
    if (authentication instanceof OAuth2AuthenticationToken oauthToken
43 1 1. preHandle : negated conditional → KILLED
        && oauthToken.getPrincipal() instanceof OidcUser oidcUser) {
44
      String email = oidcUser.getEmail();
45
      Set<GrantedAuthority> newAuthorities = new HashSet<>();
46
      Collection<? extends GrantedAuthority> current = authentication.getAuthorities();
47
48
      current.stream()
49
          .filter(
50
              a ->
51 2 1. lambda$preHandle$0 : replaced boolean return with true for edu/ucsb/cs/scaffold/interceptors/RoleUpdateInterceptor::lambda$preHandle$0 → KILLED
2. lambda$preHandle$0 : negated conditional → KILLED
                  !a.getAuthority().equals("ROLE_ADMIN")
52 1 1. lambda$preHandle$0 : negated conditional → KILLED
                      && !a.getAuthority().equals("ROLE_INSTRUCTOR"))
53 1 1. preHandle : removed call to java/util/stream/Stream::forEach → KILLED
          .forEach(newAuthorities::add);
54
55 1 1. preHandle : negated conditional → KILLED
      if (adminRepository.existsByEmail(email)) {
56
        newAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
57 1 1. preHandle : negated conditional → KILLED
      } else if (instructorRepository.existsByEmail(email)) {
58
        newAuthorities.add(new SimpleGrantedAuthority("ROLE_INSTRUCTOR"));
59
      }
60
61
      Authentication newAuth =
62
          new OAuth2AuthenticationToken(
63
              oidcUser, newAuthorities, oauthToken.getAuthorizedClientRegistrationId());
64
      SecurityContextHolder.getContext().setAuthentication(newAuth);
65
    }
66
67 1 1. preHandle : replaced boolean return with false for edu/ucsb/cs/scaffold/interceptors/RoleUpdateInterceptor::preHandle → KILLED
    return true;
68
  }
69
}

Mutations

42

1.1
Location : preHandle
Killed by : edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests]/[method:non_oauth_authentication_passes_through_unchanged()]
negated conditional → KILLED

43

1.1
Location : preHandle
Killed by : edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests]/[method:oauth2_non_oidc_authentication_passes_through_unchanged()]
negated conditional → KILLED

51

1.1
Location : lambda$preHandle$0
Killed by : edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests]/[method:instructor_role_removed_when_user_loses_instructor_status()]
replaced boolean return with true for edu/ucsb/cs/scaffold/interceptors/RoleUpdateInterceptor::lambda$preHandle$0 → KILLED

2.2
Location : lambda$preHandle$0
Killed by : edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests]/[method:instructor_role_removed_when_user_loses_instructor_status()]
negated conditional → KILLED

52

1.1
Location : lambda$preHandle$0
Killed by : edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests]/[method:instructor_role_removed_when_user_loses_instructor_status()]
negated conditional → KILLED

53

1.1
Location : preHandle
Killed by : edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests]/[method:instructor_role_removed_when_user_loses_instructor_status()]
removed call to java/util/stream/Stream::forEach → KILLED

55

1.1
Location : preHandle
Killed by : edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests]/[method:instructor_role_removed_when_user_loses_instructor_status()]
negated conditional → KILLED

57

1.1
Location : preHandle
Killed by : edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.interceptors.RoleUpdateInterceptorTests]/[method:instructor_role_removed_when_user_loses_instructor_status()]
negated conditional → KILLED

67

1.1
Location : preHandle
Killed by : edu.ucsb.cs.scaffold.ScaffoldApplicationTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.ScaffoldApplicationTests]/[method:insertUserActivityWithNullEventTypeReturnsBadRequest()]
replaced boolean return with false for edu/ucsb/cs/scaffold/interceptors/RoleUpdateInterceptor::preHandle → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0