Skip to content

Commit 5823e5b

Browse files
committed
Add AccessControlServiceTest
1 parent ef9ad99 commit 5823e5b

2 files changed

Lines changed: 199 additions & 12 deletions

File tree

src/main/java/eu/openanalytics/containerproxy/service/AccessControlService.java

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,51 @@
2929
import org.springframework.security.core.Authentication;
3030
import org.springframework.stereotype.Service;
3131

32-
import javax.inject.Inject;
33-
3432
@Service
3533
public class AccessControlService {
3634

37-
@Lazy
38-
@Inject
39-
private IAuthenticationBackend authBackend;
40-
41-
@Inject
42-
private UserService userService;
35+
private final IAuthenticationBackend authBackend;
36+
private final UserService userService;
37+
private final IProxySpecProvider specProvider;
4338

44-
@Inject
45-
private IProxySpecProvider specProvider;
39+
public AccessControlService(@Lazy IAuthenticationBackend authBackend, UserService userService, IProxySpecProvider specProvider) {
40+
this.authBackend = authBackend;
41+
this.userService = userService;
42+
this.specProvider = specProvider;
43+
}
4644

4745
public boolean canAccess(Authentication auth, String specId) {
4846
return canAccess(auth, specProvider.getSpec(specId));
4947
}
5048

5149
public boolean canAccess(Authentication auth, ProxySpec spec) {
50+
Optional<String> sessionId = getSessionId();
51+
if (!sessionId.isPresent()) {
52+
return checkAccess(auth, spec);
53+
}
54+
// we got a sessionId -> use the cache
55+
return authorizationCache.computeIfAbsent(
56+
Pair.of(sessionId.get(), spec.getId()),
57+
(k) -> checkAccess(auth, spec));
58+
}
59+
60+
/**
61+
* @return the sessionId if the RequestContext is present
62+
*/
63+
private Optional<String> getSessionId() {
64+
return Optional
65+
.ofNullable(RequestContextHolder.getRequestAttributes())
66+
.map(RequestAttributes::getSessionId);
67+
}
68+
69+
private boolean checkAccess(Authentication auth, ProxySpec spec) {
5270
if (auth == null || spec == null) {
5371
return false;
5472
}
5573

56-
if (auth instanceof AnonymousAuthenticationToken && !authBackend.hasAuthorization()) {
57-
return true;
74+
if (auth instanceof AnonymousAuthenticationToken) {
75+
// if anonymous -> only allow access if we the backend has no authorization enabled
76+
return !authBackend.hasAuthorization();
5877
}
5978

6079
if (specHasNoAccessControl(spec.getAccessControl())) {
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package eu.openanalytics.containerproxy.test.auth;
2+
3+
import eu.openanalytics.containerproxy.auth.IAuthenticationBackend;
4+
import eu.openanalytics.containerproxy.model.spec.ProxyAccessControl;
5+
import eu.openanalytics.containerproxy.model.spec.ProxySpec;
6+
import eu.openanalytics.containerproxy.service.AccessControlService;
7+
import eu.openanalytics.containerproxy.service.UserService;
8+
import eu.openanalytics.containerproxy.spec.IProxySpecProvider;
9+
import org.junit.jupiter.api.Assertions;
10+
import org.junit.jupiter.api.Test;
11+
import org.springframework.security.authentication.AnonymousAuthenticationToken;
12+
import org.springframework.security.core.Authentication;
13+
14+
import static org.mockito.Mockito.mock;
15+
import static org.mockito.Mockito.when;
16+
17+
public class AccessControlServiceTest {
18+
19+
private final IAuthenticationBackend authBackend;
20+
private final UserService userService;
21+
private final IProxySpecProvider specProvider;
22+
private final AccessControlService accessControlService;
23+
24+
public AccessControlServiceTest() {
25+
authBackend = mock(IAuthenticationBackend.class);
26+
userService = mock(UserService.class);
27+
specProvider = mock(IProxySpecProvider.class);
28+
accessControlService = new AccessControlService(authBackend, userService, specProvider);
29+
}
30+
31+
@Test
32+
public void authOrSpecIsNull() {
33+
Authentication auth = mock(Authentication.class);
34+
Authentication nullAuth = null;
35+
ProxySpec nullSpec = null;
36+
37+
Assertions.assertFalse(accessControlService.canAccess(nullAuth, createProxySpec(null)));
38+
Assertions.assertFalse(accessControlService.canAccess(auth, nullSpec));
39+
Assertions.assertFalse(accessControlService.canAccess(nullAuth, nullSpec));
40+
}
41+
42+
@Test
43+
public void usingSpecId() {
44+
when(authBackend.hasAuthorization()).thenReturn(true);
45+
ProxyAccessControl proxyAccessControl = new ProxyAccessControl();
46+
when(specProvider.getSpec("myId")).thenReturn(createProxySpec(proxyAccessControl));
47+
48+
Authentication auth = mock(Authentication.class);
49+
50+
Assertions.assertTrue(accessControlService.canAccess(auth, "myId"));
51+
}
52+
53+
@Test
54+
public void specHasNoAccessControlTest() {
55+
when(authBackend.hasAuthorization()).thenReturn(true);
56+
Authentication auth = mock(Authentication.class);
57+
ProxyAccessControl proxyAccessControl = new ProxyAccessControl();
58+
59+
Assertions.assertTrue(accessControlService.canAccess(auth, createProxySpec(proxyAccessControl)));
60+
}
61+
62+
@Test
63+
public void specHasNullAccessControlTest() {
64+
when(authBackend.hasAuthorization()).thenReturn(true);
65+
Authentication auth = mock(Authentication.class);
66+
67+
Assertions.assertTrue(accessControlService.canAccess(auth, createProxySpec(null)));
68+
}
69+
70+
@Test
71+
public void anonymousAccessTest() {
72+
when(authBackend.hasAuthorization()).thenReturn(false);
73+
74+
ProxyAccessControl proxyAccessControl = new ProxyAccessControl();
75+
proxyAccessControl.setGroups(new String[]{"myGroup"});
76+
77+
// when anonymous -> has access
78+
Authentication anonymousAuth = mock(AnonymousAuthenticationToken.class);
79+
Assertions.assertTrue(accessControlService.canAccess(anonymousAuth, createProxySpec(proxyAccessControl)));
80+
81+
// when not-anonymous -> has no access
82+
Authentication auth = mock(Authentication.class);
83+
Assertions.assertFalse(accessControlService.canAccess(auth, createProxySpec(proxyAccessControl)));
84+
85+
// when spec has no Access Control -> has access
86+
Assertions.assertTrue(accessControlService.canAccess(anonymousAuth, createProxySpec(null)));
87+
}
88+
89+
@Test
90+
public void hasGroupAccessTest() {
91+
when(authBackend.hasAuthorization()).thenReturn(true);
92+
ProxyAccessControl proxyAccessControl = new ProxyAccessControl();
93+
proxyAccessControl.setGroups(new String[]{"myGroup1", "myGroupAbc", "xxy"});
94+
95+
// user is not part of any group -> no access
96+
Authentication auth1 = mock(Authentication.class);
97+
Assertions.assertFalse(accessControlService.canAccess(auth1, createProxySpec(proxyAccessControl)));
98+
99+
// user is part of group, but not the correct group -> no access
100+
when(userService.isMember(auth1, "myGroup1")).thenReturn(false);
101+
Assertions.assertFalse(accessControlService.canAccess(auth1, createProxySpec(proxyAccessControl)));
102+
103+
// user is part of the correct -> hass access
104+
Authentication auth2 = mock(Authentication.class);
105+
when(userService.isMember(auth2, "myGroup1")).thenReturn(true);
106+
Assertions.assertTrue(accessControlService.canAccess(auth2, createProxySpec(proxyAccessControl)));
107+
}
108+
109+
@Test
110+
public void hasUserAccessTest() {
111+
when(authBackend.hasAuthorization()).thenReturn(true);
112+
ProxyAccessControl proxyAccessControl = new ProxyAccessControl();
113+
proxyAccessControl.setUsers(new String[]{"myUser1", "myUser2"});
114+
115+
// user is not part of the user access list -> no access
116+
Authentication auth1 = mock(Authentication.class);
117+
when(auth1.getName()).thenReturn("Bart");
118+
Assertions.assertFalse(accessControlService.canAccess(auth1, createProxySpec(proxyAccessControl)));
119+
120+
// user is part of the user access list -> hass access
121+
Authentication auth2 = mock(Authentication.class);
122+
when(auth2.getName()).thenReturn("myUser1");
123+
when(userService.isMember(auth2, "myGroup1")).thenReturn(true);
124+
Assertions.assertTrue(accessControlService.canAccess(auth2, createProxySpec(proxyAccessControl)));
125+
}
126+
127+
@Test
128+
public void combinationOfGroupAndUserTest() {
129+
when(authBackend.hasAuthorization()).thenReturn(true);
130+
ProxyAccessControl proxyAccessControl = new ProxyAccessControl();
131+
proxyAccessControl.setUsers(new String[]{"myUser1", "myUser2"});
132+
proxyAccessControl.setGroups(new String[]{"myGroup1", "myGroupAbc", "xxy"});
133+
134+
// user is not part of any group and not on the user access list -> no access
135+
Authentication auth1 = mock(Authentication.class);
136+
when(auth1.getName()).thenReturn("Bart");
137+
Assertions.assertFalse(accessControlService.canAccess(auth1, createProxySpec(proxyAccessControl)));
138+
139+
// user is not part of any group, but it is on the user access list -> has access
140+
Authentication auth2 = mock(Authentication.class);
141+
when(auth2.getName()).thenReturn("myUser1");
142+
Assertions.assertTrue(accessControlService.canAccess(auth2, createProxySpec(proxyAccessControl)));
143+
144+
// user is part of group and not on the user access list -> has access
145+
Authentication auth3 = mock(Authentication.class);
146+
when(auth3.getName()).thenReturn("Bart");
147+
when(userService.isMember(auth3, "myGroup1")).thenReturn(false);
148+
when(userService.isMember(auth3, "myGroupAbc")).thenReturn(true);
149+
when(userService.isMember(auth3, "xxy")).thenReturn(false);
150+
Assertions.assertTrue(accessControlService.canAccess(auth3, createProxySpec(proxyAccessControl)));
151+
152+
// user is part of group and also on the user access list -> has access
153+
Authentication auth4 = mock(Authentication.class);
154+
when(auth4.getName()).thenReturn("myUser1");
155+
when(userService.isMember(auth4, "myGroup1")).thenReturn(false);
156+
when(userService.isMember(auth4, "myGroupAbc")).thenReturn(true);
157+
when(userService.isMember(auth4, "xxy")).thenReturn(false);
158+
Assertions.assertTrue(accessControlService.canAccess(auth4, createProxySpec(proxyAccessControl)));
159+
}
160+
161+
private ProxySpec createProxySpec(ProxyAccessControl proxyAccessControl) {
162+
ProxySpec proxySpec = new ProxySpec();
163+
proxySpec.setId("myId");
164+
proxySpec.setAccessControl(proxyAccessControl);
165+
return proxySpec;
166+
}
167+
168+
}

0 commit comments

Comments
 (0)