CourseSecurity.java

1
package edu.ucsb.cs156.frontiers.config;
2
3
import edu.ucsb.cs156.frontiers.entities.Course;
4
import edu.ucsb.cs156.frontiers.models.CurrentUser;
5
import edu.ucsb.cs156.frontiers.repositories.CourseRepository;
6
import edu.ucsb.cs156.frontiers.repositories.DownloadRequestRepository;
7
import edu.ucsb.cs156.frontiers.repositories.RosterStudentRepository;
8
import edu.ucsb.cs156.frontiers.services.ApiCourseKeyService;
9
import edu.ucsb.cs156.frontiers.services.CurrentUserService;
10
import java.util.Collection;
11
import java.util.Optional;
12
import lombok.extern.slf4j.Slf4j;
13
import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations;
14
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
15
import org.springframework.security.access.prepost.PreAuthorize;
16
import org.springframework.security.core.GrantedAuthority;
17
import org.springframework.stereotype.Component;
18
19
/**
20
 * CourseSecurity provides methods to check permissions for managing courses and roster students. It
21
 * uses the CurrentUserService to get the current user and RoleHierarchy to check roles.
22
 *
23
 * <p>The methods defined here are used as annotations (e.g. <code>
24
 *   @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #id)")</code>) in the
25
 * CourseController and RosterStudentController to enforce security checks.
26
 *
27
 * <p>Note that for a method with a courseId, you <em>still</em> need to verify in each method,
28
 * whether the course exists or not. These annotations will <em>only</em> check whether or not the
29
 * particular user has access to a particular course, for example.
30
 *
31
 * <p>When testing, use <code>@WithInstructorCoursePermissions</code> or <code>
32
 * @WithStaffCoursePermissions</code> to mock a user with the appropriate roles.
33
 */
34
@Slf4j
35
@Component("CourseSecurity")
36
public class CourseSecurity {
37
  private final CurrentUserService currentUserService;
38
  private final RoleHierarchy roleHierarchy;
39
  private final CourseRepository courseRepository;
40
  private final RosterStudentRepository rosterStudentRepository;
41
  private final DownloadRequestRepository downloadRequestRepository;
42
  private final ApiCourseKeyService apiCourseKeyService;
43
44
  public CourseSecurity(
45
      CurrentUserService currentUserService,
46
      RoleHierarchy roleHierarchy,
47
      CourseRepository courseRepository,
48
      RosterStudentRepository rosterStudentRepository,
49
      DownloadRequestRepository downloadRequestRepository,
50
      ApiCourseKeyService apiCourseKeyService) {
51
    this.currentUserService = currentUserService;
52
    this.roleHierarchy = roleHierarchy;
53
    this.courseRepository = courseRepository;
54
    this.rosterStudentRepository = rosterStudentRepository;
55
    this.downloadRequestRepository = downloadRequestRepository;
56
    this.apiCourseKeyService = apiCourseKeyService;
57
  }
58
59
  /**
60
   * Use this when you want to check whether the user is either a staff member, instructor or admin
61
   * for the course.
62
   *
63
   * @param operations
64
   * @param courseId
65
   * @return true if the user has manage permissions for the course, false otherwise.
66
   */
67
  @PreAuthorize("hasRole('ROLE_USER')")
68
  public Boolean hasManagePermissions(
69
      MethodSecurityExpressionOperations operations, Long courseId) {
70 2 1. hasManagePermissions : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissions → KILLED
2. hasManagePermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissions → KILLED
    return hasManagePermissionsWithoutRoleCheck(operations, courseId);
71
  }
72
73
  private Boolean hasManagePermissionsWithoutRoleCheck(
74
      MethodSecurityExpressionOperations operations, Long courseId) {
75
    Optional<Course> course = courseRepository.findById(courseId);
76 1 1. hasManagePermissionsWithoutRoleCheck : negated conditional → KILLED
    if (course.isEmpty()) {
77 1 1. hasManagePermissionsWithoutRoleCheck : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsWithoutRoleCheck → KILLED
      return true;
78
    }
79 2 1. hasManagePermissionsWithoutRoleCheck : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsWithoutRoleCheck → KILLED
2. hasManagePermissionsWithoutRoleCheck : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsWithoutRoleCheck → KILLED
    return baseHasManagePermissions(operations, course.get());
80
  }
81
82
  /**
83
   * Use this for operations that only an instructor can do, but not a staff member, such as adding
84
   * or deleting a course staff member.
85
   *
86
   * @param operations
87
   * @param courseId
88
   * @return true if the user has instructor permissions for the course, false otherwise.
89
   */
90
  @PreAuthorize("hasRole('ROLE_INSTRUCTOR')")
91
  public Boolean hasInstructorPermissions(
92
      MethodSecurityExpressionOperations operations, Long courseId) {
93
    CurrentUser currentUser = currentUserService.getCurrentUser();
94
    Collection<? extends GrantedAuthority> authorities =
95
        roleHierarchy.getReachableGrantedAuthorities(currentUser.getRoles());
96 3 1. hasInstructorPermissions : negated conditional → KILLED
2. lambda$hasInstructorPermissions$0 : replaced boolean return with false for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasInstructorPermissions$0 → KILLED
3. lambda$hasInstructorPermissions$0 : replaced boolean return with true for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasInstructorPermissions$0 → KILLED
    if (authorities.stream().anyMatch(role -> role.getAuthority().equals("ROLE_ADMIN"))) {
97 1 1. hasInstructorPermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasInstructorPermissions → KILLED
      return true;
98
    } else {
99
      Optional<Course> course = courseRepository.findById(courseId);
100 1 1. hasInstructorPermissions : negated conditional → KILLED
      if (course.isEmpty()) {
101 1 1. hasInstructorPermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasInstructorPermissions → KILLED
        return true;
102
      }
103 2 1. hasInstructorPermissions : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasInstructorPermissions → KILLED
2. hasInstructorPermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasInstructorPermissions → KILLED
      return currentUser.getUser().getEmail().equals(course.get().getInstructorEmail());
104
    }
105
  }
106
107
  /**
108
   * This method checks if the current user has management permissions for the course associated
109
   * with the given rosterStudent. This allows us to create endpoints that just take a roster
110
   * student id, not a course id, and still check permissions. This one works for both staff and
111
   * instructor permissions.
112
   *
113
   * @param operations
114
   * @param rosterStudentId
115
   * @return
116
   */
117
  @PreAuthorize("hasRole('ROLE_USER')")
118
  public Boolean hasRosterStudentManagementPermissions(
119
      MethodSecurityExpressionOperations operations, Long rosterStudentId) {
120 2 1. hasRosterStudentManagementPermissions : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasRosterStudentManagementPermissions → KILLED
2. hasRosterStudentManagementPermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasRosterStudentManagementPermissions → KILLED
    return rosterStudentRepository
121
        .findById(rosterStudentId)
122 2 1. lambda$hasRosterStudentManagementPermissions$1 : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasRosterStudentManagementPermissions$1 → KILLED
2. lambda$hasRosterStudentManagementPermissions$1 : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasRosterStudentManagementPermissions$1 → KILLED
        .map(rosterStudent -> baseHasManagePermissions(operations, rosterStudent.getCourse()))
123
        .orElse(true);
124
  }
125
126
  /**
127
   * This is a helper method that checks if the current user has management permissions for the
128
   * given course.
129
   *
130
   * @param operations
131
   * @param course
132
   * @return
133
   */
134
  public Boolean baseHasManagePermissions(
135
      MethodSecurityExpressionOperations operations, Course course) {
136
    CurrentUser currentUser = currentUserService.getCurrentUser();
137 2 1. baseHasManagePermissions : negated conditional → KILLED
2. baseHasManagePermissions : negated conditional → KILLED
    if (currentUser == null || currentUser.getUser() == null) {
138 1 1. baseHasManagePermissions : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED
      return false;
139
    }
140
    Collection<? extends GrantedAuthority> authorities =
141
        roleHierarchy.getReachableGrantedAuthorities(currentUser.getRoles());
142 3 1. lambda$baseHasManagePermissions$2 : replaced boolean return with true for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$baseHasManagePermissions$2 → KILLED
2. lambda$baseHasManagePermissions$2 : replaced boolean return with false for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$baseHasManagePermissions$2 → KILLED
3. baseHasManagePermissions : negated conditional → KILLED
    if (authorities.stream().anyMatch(role -> role.getAuthority().equals("ROLE_ADMIN"))) {
143 1 1. baseHasManagePermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED
      return true;
144
    } else {
145
      if (course.getCourseStaff().stream()
146 3 1. baseHasManagePermissions : negated conditional → KILLED
2. lambda$baseHasManagePermissions$3 : replaced boolean return with false for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$baseHasManagePermissions$3 → KILLED
3. lambda$baseHasManagePermissions$3 : replaced boolean return with true for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$baseHasManagePermissions$3 → KILLED
          .anyMatch(staff -> staff.getEmail().equals(currentUser.getUser().getEmail()))) {
147 1 1. baseHasManagePermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED
        return true;
148
      }
149 2 1. baseHasManagePermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED
2. baseHasManagePermissions : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED
      return currentUser.getUser().getEmail().equals(course.getInstructorEmail());
150
    }
151
  }
152
153
  public Boolean hasManagePermissionsOrApiKeyAccess(
154
      MethodSecurityExpressionOperations operations, Long courseId) {
155 1 1. hasManagePermissionsOrApiKeyAccess : negated conditional → KILLED
    if (apiCourseKeyService.authenticateFromRequestForCourse(courseId)) {
156 1 1. hasManagePermissionsOrApiKeyAccess : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsOrApiKeyAccess → KILLED
      return true;
157
    }
158 2 1. hasManagePermissionsOrApiKeyAccess : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsOrApiKeyAccess → KILLED
2. hasManagePermissionsOrApiKeyAccess : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsOrApiKeyAccess → KILLED
    return hasManagePermissionsWithoutRoleCheck(operations, courseId);
159
  }
160
161
  @PreAuthorize("hasRole('ROLE_USER')")
162
  public Boolean hasDownloadPermissions(
163
      MethodSecurityExpressionOperations operations, Long downloadId) {
164 2 1. hasDownloadPermissions : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasDownloadPermissions → KILLED
2. hasDownloadPermissions : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasDownloadPermissions → KILLED
    return downloadRequestRepository
165
        .findById(downloadId)
166 2 1. lambda$hasDownloadPermissions$4 : replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasDownloadPermissions$4 → KILLED
2. lambda$hasDownloadPermissions$4 : replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasDownloadPermissions$4 → KILLED
        .map(downloadRequest -> baseHasManagePermissions(operations, downloadRequest.getCourse()))
167
        .orElse(true);
168
  }
169
}

Mutations

70

1.1
Location : hasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:UnsuccessfulInstructor]/[method:instructor_cant_load_non_owned_course()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissions → KILLED

2.2
Location : hasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFound]/[method:null_on_null()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissions → KILLED

76

1.1
Location : hasManagePermissionsWithoutRoleCheck
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFound]/[method:null_on_null()]
negated conditional → KILLED

77

1.1
Location : hasManagePermissionsWithoutRoleCheck
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFound]/[method:null_on_null()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsWithoutRoleCheck → KILLED

79

1.1
Location : hasManagePermissionsWithoutRoleCheck
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFound]/[nested-class:ApiKeyAccess]/[method:no_api_key_and_no_user_denies_access()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsWithoutRoleCheck → KILLED

2.2
Location : hasManagePermissionsWithoutRoleCheck
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdmin]/[method:instructor_can_load_owned_course()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsWithoutRoleCheck → KILLED

96

1.1
Location : hasInstructorPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdminPerms]/[method:instructor_can_load_owned_course()]
negated conditional → KILLED

2.2
Location : lambda$hasInstructorPermissions$0
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdminPerms]/[method:instructor_can_load_owned_course()]
replaced boolean return with false for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasInstructorPermissions$0 → KILLED

3.3
Location : lambda$hasInstructorPermissions$0
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:UnsuccessfulInstructorPerms]/[method:instructor_cant_load_non_owned_course()]
replaced boolean return with true for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasInstructorPermissions$0 → KILLED

97

1.1
Location : hasInstructorPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdminPerms]/[method:instructor_can_load_owned_course()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasInstructorPermissions → KILLED

100

1.1
Location : hasInstructorPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFoundInstructor]/[method:null_on_null()]
negated conditional → KILLED

101

1.1
Location : hasInstructorPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFoundInstructor]/[method:null_on_null()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasInstructorPermissions → KILLED

103

1.1
Location : hasInstructorPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:UnsuccessfulInstructorPerms]/[method:instructor_cant_load_non_owned_course()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasInstructorPermissions → KILLED

2.2
Location : hasInstructorPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulInstructorPerms]/[method:instructor_can_load_owned_course()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasInstructorPermissions → KILLED

120

1.1
Location : hasRosterStudentManagementPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:CorrectPassRosterStudent]/[method:returns_properly()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasRosterStudentManagementPermissions → KILLED

2.2
Location : hasRosterStudentManagementPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFoundRosterStudent]/[method:null_on_null()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasRosterStudentManagementPermissions → KILLED

122

1.1
Location : lambda$hasRosterStudentManagementPermissions$1
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:CorrectPassRosterStudent]/[method:returns_properly()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasRosterStudentManagementPermissions$1 → KILLED

2.2
Location : lambda$hasRosterStudentManagementPermissions$1
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:FalseButExistsRosterStudent]/[method:returns_properly()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasRosterStudentManagementPermissions$1 → KILLED

137

1.1
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdmin]/[method:instructor_can_load_owned_course()]
negated conditional → KILLED

2.2
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdmin]/[method:instructor_can_load_owned_course()]
negated conditional → KILLED

138

1.1
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFound]/[nested-class:ApiKeyAccess]/[method:no_api_key_and_no_user_denies_access()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED

142

1.1
Location : lambda$baseHasManagePermissions$2
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:CorrectPassRosterStudent]/[method:returns_properly()]
replaced boolean return with true for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$baseHasManagePermissions$2 → KILLED

2.2
Location : lambda$baseHasManagePermissions$2
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdmin]/[method:instructor_can_load_owned_course()]
replaced boolean return with false for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$baseHasManagePermissions$2 → KILLED

3.3
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdmin]/[method:instructor_can_load_owned_course()]
negated conditional → KILLED

143

1.1
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulAdmin]/[method:instructor_can_load_owned_course()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED

146

1.1
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulCourseStaff]/[method:instructor_can_load_owned_course()]
negated conditional → KILLED

2.2
Location : lambda$baseHasManagePermissions$3
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulCourseStaff]/[method:instructor_can_load_owned_course()]
replaced boolean return with false for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$baseHasManagePermissions$3 → KILLED

3.3
Location : lambda$baseHasManagePermissions$3
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:UnsuccessfulInstructor]/[method:instructor_cant_load_non_owned_course()]
replaced boolean return with true for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$baseHasManagePermissions$3 → KILLED

147

1.1
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulCourseStaff]/[method:instructor_can_load_owned_course()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED

149

1.1
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:SuccessfulInstructor]/[method:instructor_can_load_owned_course()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED

2.2
Location : baseHasManagePermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:CorrectPassRosterStudent]/[method:returns_properly()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::baseHasManagePermissions → KILLED

155

1.1
Location : hasManagePermissionsOrApiKeyAccess
Killed by : edu.ucsb.cs156.frontiers.config.CourseSecurityUnitTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.config.CourseSecurityUnitTests]/[method:hasManagePermissionsOrApiKeyAccess_falls_back_to_manage_permissions()]
negated conditional → KILLED

156

1.1
Location : hasManagePermissionsOrApiKeyAccess
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFound]/[nested-class:ApiKeyAccess]/[method:api_key_allows_access_without_logged_in_user()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsOrApiKeyAccess → KILLED

158

1.1
Location : hasManagePermissionsOrApiKeyAccess
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFound]/[nested-class:ApiKeyAccess]/[method:no_api_key_and_no_user_denies_access()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsOrApiKeyAccess → KILLED

2.2
Location : hasManagePermissionsOrApiKeyAccess
Killed by : edu.ucsb.cs156.frontiers.config.CourseSecurityUnitTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.config.CourseSecurityUnitTests]/[method:hasManagePermissionsOrApiKeyAccess_falls_back_to_manage_permissions()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasManagePermissionsOrApiKeyAccess → KILLED

164

1.1
Location : hasDownloadPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:NotFoundDownloadRequest]/[method:null_on_null()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasDownloadPermissions → KILLED

2.2
Location : hasDownloadPermissions
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:CorrectPassDownloadRequest]/[method:returns_properly()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::hasDownloadPermissions → KILLED

166

1.1
Location : lambda$hasDownloadPermissions$4
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:FalseButExistsDownloadRequest]/[method:returns_properly()]
replaced Boolean return with False for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasDownloadPermissions$4 → KILLED

2.2
Location : lambda$hasDownloadPermissions$4
Killed by : edu.ucsb.cs156.frontiers.security.CourseSecurityTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.security.CourseSecurityTests]/[nested-class:CorrectPassDownloadRequest]/[method:returns_properly()]
replaced Boolean return with True for edu/ucsb/cs156/frontiers/config/CourseSecurity::lambda$hasDownloadPermissions$4 → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0