-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathAdminRoleAccessControlTest.java
More file actions
241 lines (203 loc) · 10.7 KB
/
Copy pathAdminRoleAccessControlTest.java
File metadata and controls
241 lines (203 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
package com.digitalsanctuary.spring.user.concurrent;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.digitalsanctuary.spring.demo.UserDemoApplication;
import java.time.LocalDate;
import com.digitalsanctuary.spring.user.persistence.model.Role;
import com.digitalsanctuary.spring.user.persistence.repository.RoleRepository;
import com.digitalsanctuary.spring.user.test.annotations.IntegrationTest;
/**
* Admin Role Access Control Test - Phase 3 of Task 4.3 (Simplified)
*
* Tests role-based access control and admin privileges: - Admin vs User permission verification - Role hierarchy validation - Multi-user permission
* scenarios
*
* This simplified version focuses on working functionality.
*/
@SpringBootTest(classes = UserDemoApplication.class)
@AutoConfigureMockMvc
@IntegrationTest
@ActiveProfiles("test")
@DisplayName("Admin Role Access Control Tests")
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class AdminRoleAccessControlTest {
@Autowired
private MultiUserTestUtilities testUtilities;
@Autowired
private MockMvc mockMvc;
@Autowired
private RoleRepository roleRepository;
private TestUserManager userManager;
private static final String TEST_PREFIX = "role.access";
/** Returns a date one year in the future to satisfy @FutureOrPresent validation */
private static String futureDate() {
return LocalDate.now().plusYears(1).toString();
}
@BeforeEach
void setUp() {
String uniquePrefix = TEST_PREFIX + "." + System.currentTimeMillis();
userManager = testUtilities.createTestUserManager(uniquePrefix);
testUtilities.ensureRolesExist();
}
@AfterEach
void tearDown() {
if (userManager != null) {
userManager.cleanup();
}
}
@Nested
@DisplayName("Role Privilege Verification")
class RolePrivilegeTests {
@Test
@DisplayName("Admin role should have comprehensive privileges")
@Transactional
void testAdminRolePrivileges() {
Role adminRole = roleRepository.findByName("ROLE_ADMIN");
assertThat(adminRole).isNotNull();
// Verify admin has key privileges
assertThat(adminRole.getPrivileges()).extracting("name").contains("ADMIN_PRIVILEGE", "READ_USER_PRIVILEGE",
"RESET_ANY_USER_PASSWORD_PRIVILEGE", "CREATE_EVENT_PRIVILEGE", "DELETE_EVENT_PRIVILEGE", "UPDATE_EVENT_PRIVILEGE");
}
@Test
@DisplayName("Manager role should have limited privileges")
@Transactional
void testManagerRolePrivileges() {
Role managerRole = roleRepository.findByName("ROLE_MANAGER");
assertThat(managerRole).isNotNull();
// Manager should have specific privileges
assertThat(managerRole.getPrivileges()).extracting("name").contains("ADD_USER_TO_TEAM_PRIVILEGE", "REMOVE_USER_FROM_TEAM_PRIVILEGE",
"RESET_TEAM_PASSWORD_PRIVILEGE");
// Manager should NOT have admin privileges
assertThat(managerRole.getPrivileges()).extracting("name").doesNotContain("ADMIN_PRIVILEGE", "RESET_ANY_USER_PASSWORD_PRIVILEGE");
}
@Test
@DisplayName("User role should have basic privileges only")
@Transactional
void testUserRolePrivileges() {
Role userRole = roleRepository.findByName("ROLE_USER");
assertThat(userRole).isNotNull();
// User should have basic privileges
assertThat(userRole.getPrivileges()).extracting("name").contains("LOGIN_PRIVILEGE", "UPDATE_OWN_USER_PRIVILEGE",
"RESET_OWN_PASSWORD_PRIVILEGE", "REGISTER_FOR_EVENT_PRIVILEGE");
// User should NOT have admin or manager privileges
assertThat(userRole.getPrivileges()).extracting("name").doesNotContain("ADMIN_PRIVILEGE", "READ_USER_PRIVILEGE",
"ADD_USER_TO_TEAM_PRIVILEGE");
}
}
@Nested
@DisplayName("Event Management Access Control")
class EventAccessControlTests {
@Test
@WithMockUser(authorities = {"CREATE_EVENT_PRIVILEGE", "UPDATE_EVENT_PRIVILEGE", "DELETE_EVENT_PRIVILEGE"})
@DisplayName("Admin can perform all event operations")
void testAdminEventOperations() throws Exception {
// Admin can create events
String validEventJson = "{\"name\": \"Admin Event\", \"description\": \"Created by admin\", \"location\": \"Test Location\", \"date\": \"" + futureDate() + "\", \"time\": \"14:30\"}";
mockMvc.perform(post("/api/events").contentType(MediaType.APPLICATION_JSON)
.content(validEventJson).with(csrf())).andExpect(status().isOk());
}
@Test
@WithMockUser(authorities = {"REGISTER_FOR_EVENT_PRIVILEGE"})
@DisplayName("Regular user can only register for events")
void testUserEventLimitations() throws Exception {
// User CANNOT create events
String validEventJson = "{\"name\": \"User Event\", \"description\": \"Should fail\", \"location\": \"Test Location\", \"date\": \"" + futureDate() + "\", \"time\": \"14:30\"}";
mockMvc.perform(post("/api/events").contentType(MediaType.APPLICATION_JSON)
.content(validEventJson).with(csrf())).andExpect(status().isForbidden());
}
@Test
@WithMockUser(authorities = {})
@DisplayName("No authorities should deny access")
void testNoAuthoritiesAccess() throws Exception {
String validEventJson = "{\"name\": \"Unauthorized\", \"description\": \"Should fail\", \"location\": \"Test Location\", \"date\": \"" + futureDate() + "\", \"time\": \"14:30\"}";
mockMvc.perform(post("/api/events").contentType(MediaType.APPLICATION_JSON)
.content(validEventJson).with(csrf())).andExpect(status().isForbidden());
}
}
@Nested
@DisplayName("Multi-User Permission Scenarios")
class MultiUserPermissionTests {
@Test
@DisplayName("Multiple permission levels should work independently")
void testMultiplePermissionLevels() {
// Test that different permission combinations work as expected
testUtilities.ensureRolesExist();
// Verify roles exist and have correct privileges
Role adminRole = roleRepository.findByName("ROLE_ADMIN");
Role managerRole = roleRepository.findByName("ROLE_MANAGER");
Role userRole = roleRepository.findByName("ROLE_USER");
assertThat(adminRole).isNotNull();
assertThat(managerRole).isNotNull();
assertThat(userRole).isNotNull();
// Admin should have more privileges than manager
assertThat(adminRole.getPrivileges().size()).isGreaterThan(managerRole.getPrivileges().size());
// All roles should have at least one privilege
assertThat(adminRole.getPrivileges().size()).isGreaterThan(0);
assertThat(managerRole.getPrivileges().size()).isGreaterThan(0);
assertThat(userRole.getPrivileges().size()).isGreaterThan(0);
}
@Test
@WithMockUser(authorities = {"CREATE_EVENT_PRIVILEGE", "REGISTER_FOR_EVENT_PRIVILEGE"})
@DisplayName("Partial admin permissions should work correctly")
void testPartialAdminPermissions() throws Exception {
// User with some admin privileges can create events
String validEventJson = "{\"name\": \"Partial Admin Event\", \"description\": \"Test\", \"location\": \"Test Location\", \"date\": \"" + futureDate() + "\", \"time\": \"14:30\"}";
mockMvc.perform(post("/api/events").contentType(MediaType.APPLICATION_JSON)
.content(validEventJson).with(csrf())).andExpect(status().isOk());
}
@Test
@WithMockUser(authorities = {"ADMIN_PRIVILEGE", "READ_USER_PRIVILEGE"})
@DisplayName("Admin privileges should allow user management access")
void testAdminUserManagementAccess() throws Exception {
// This would test admin-specific endpoints if they existed
// For now, verify the privileges are correctly configured
Role adminRole = roleRepository.findByName("ROLE_ADMIN");
assertThat(adminRole.getPrivileges()).extracting("name").contains("ADMIN_PRIVILEGE", "READ_USER_PRIVILEGE");
}
}
@Nested
@DisplayName("Concurrent Permission Tests")
class ConcurrentPermissionTests {
@Test
@DisplayName("Multiple users with different roles should access appropriately")
void testConcurrentRoleAccess() {
final int threadCount = 5;
// Test concurrent role checks
Runnable roleCheckTask = () -> {
try {
// Each thread verifies role configuration
Role adminRole = roleRepository.findByName("ROLE_ADMIN");
Role userRole = roleRepository.findByName("ROLE_USER");
assertThat(adminRole).isNotNull();
assertThat(userRole).isNotNull();
// Admin should have more privileges
assertThat(adminRole.getPrivileges().size()).isGreaterThan(userRole.getPrivileges().size());
} catch (Exception e) {
throw new AssertionError("Concurrent role check failed", e);
}
};
// Execute concurrent role checks
MultiUserTestUtilities.ConcurrentExecutionResult result = testUtilities.executeConcurrently(threadCount, roleCheckTask, 30);
// Verify all checks passed
assertThat(result.completedWithinTimeout()).isTrue();
assertThat(result.errorCount()).isEqualTo(0);
assertThat(result.successCount()).isEqualTo(threadCount);
}
}
}