Skip to content

Commit 9d143b1

Browse files
committed
Ref #25533: access control for value sets
1 parent 5d26958 commit 9d143b1

17 files changed

Lines changed: 390 additions & 298 deletions

src/main/java/eu/openanalytics/containerproxy/model/spec/ProxyAccessControl.java renamed to src/main/java/eu/openanalytics/containerproxy/model/spec/AccessControl.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020
*/
2121
package eu.openanalytics.containerproxy.model.spec;
2222

23-
import java.util.Arrays;
24-
25-
public class ProxyAccessControl {
23+
public class AccessControl {
2624

2725
private String[] groups;
2826
private String[] users;
@@ -52,18 +50,6 @@ public void setExpression(String expression) {
5250
this.expression = expression;
5351
}
5452

55-
public void copy(ProxyAccessControl target) {
56-
if (groups != null) {
57-
target.setGroups(Arrays.copyOf(groups, groups.length));
58-
}
59-
if (users != null) {
60-
target.setUsers(Arrays.copyOf(users, users.length));
61-
}
62-
if (expression != null) {
63-
target.setExpression(expression);
64-
}
65-
}
66-
6753
public boolean hasGroupAccess() {
6854
return groups != null && groups.length > 0;
6955
}

src/main/java/eu/openanalytics/containerproxy/model/spec/Parameters.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222

2323
import java.util.List;
2424
import java.util.Map;
25+
import java.util.Set;
2526
import java.util.stream.Collectors;
2627

2728
public class Parameters {
2829

2930
private List<ParameterDefinition> definitions;
30-
private List<Map<String, List<String>>> values;
31+
private List<ValueSet> valueSets;
3132

3233
public List<ParameterDefinition> getDefinitions() {
3334
return definitions;
@@ -41,11 +42,41 @@ public void setDefinitions(List<ParameterDefinition> definitions) {
4142
this.definitions = definitions;
4243
}
4344

44-
public List<Map<String, List<String>>> getValues() {
45-
return values;
45+
public List<ValueSet> getValueSets() {
46+
return valueSets;
4647
}
4748

48-
public void setValues(List<Map<String, List<String>>> values) {
49-
this.values = values;
49+
public void setValueSets(List<ValueSet> valueSets) {
50+
this.valueSets = valueSets;
51+
}
52+
53+
public static class ValueSet {
54+
55+
private AccessControl accessControl;
56+
private Map<String, List<String>> values;
57+
58+
public void setValues(Map<String, List<String>> values) {
59+
this.values = values;
60+
}
61+
62+
public AccessControl getAccessControl() {
63+
return accessControl;
64+
}
65+
66+
public void setAccessControl(AccessControl accessControl) {
67+
this.accessControl = accessControl;
68+
}
69+
70+
public boolean containsParameter(String parameterId) {
71+
return values.containsKey(parameterId) && !values.get(parameterId).isEmpty();
72+
}
73+
74+
public List<String> getParameterValues(String parameterId) {
75+
return values.get(parameterId);
76+
}
77+
78+
public Set<String> getParameterIds() {
79+
return values.keySet();
80+
}
5081
}
5182
}

src/main/java/eu/openanalytics/containerproxy/model/spec/ProxySpec.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@
2121
package eu.openanalytics.containerproxy.model.spec;
2222

2323
import java.util.ArrayList;
24-
import java.util.HashMap;
2524
import java.util.List;
26-
import java.util.Map;
27-
import java.util.stream.Collectors;
2825

2926
public class ProxySpec {
3027

@@ -33,7 +30,7 @@ public class ProxySpec {
3330
private String description;
3431
private String logoURL;
3532

36-
private ProxyAccessControl accessControl;
33+
private AccessControl accessControl;
3734
private List<ContainerSpec> containerSpecs;
3835

3936
private String kubernetesPodPatches;
@@ -78,11 +75,11 @@ public void setLogoURL(String logoURL) {
7875
this.logoURL = logoURL;
7976
}
8077

81-
public ProxyAccessControl getAccessControl() {
78+
public AccessControl getAccessControl() {
8279
return accessControl;
8380
}
8481

85-
public void setAccessControl(ProxyAccessControl accessControl) {
82+
public void setAccessControl(AccessControl accessControl) {
8683
this.accessControl = accessControl;
8784
}
8885

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2021 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.service;
22+
23+
import eu.openanalytics.containerproxy.auth.IAuthenticationBackend;
24+
import eu.openanalytics.containerproxy.model.spec.AccessControl;
25+
import eu.openanalytics.containerproxy.model.spec.ProxySpec;
26+
import eu.openanalytics.containerproxy.spec.expression.SpecExpressionContext;
27+
import eu.openanalytics.containerproxy.spec.expression.SpecExpressionResolver;
28+
import org.springframework.context.annotation.Lazy;
29+
import org.springframework.security.authentication.AnonymousAuthenticationToken;
30+
import org.springframework.security.core.Authentication;
31+
import org.springframework.stereotype.Service;
32+
33+
@Service
34+
public class AccessControlEvaluationService {
35+
36+
private final IAuthenticationBackend authBackend;
37+
private final UserService userService;
38+
39+
private final SpecExpressionResolver specExpressionResolver;
40+
41+
public AccessControlEvaluationService(@Lazy IAuthenticationBackend authBackend, UserService userService, SpecExpressionResolver specExpressionResolver) {
42+
this.authBackend = authBackend;
43+
this.userService = userService;
44+
this.specExpressionResolver = specExpressionResolver;
45+
}
46+
47+
public boolean checkAccess(Authentication auth, ProxySpec spec, AccessControl accessControl) {
48+
if (auth instanceof AnonymousAuthenticationToken) {
49+
// TODO test with parameters
50+
// if anonymous -> only allow access if the backend has no authorization enabled
51+
return !authBackend.hasAuthorization();
52+
}
53+
54+
if (hasAccessControl(accessControl)) {
55+
return true;
56+
}
57+
58+
if (allowedByGroups(auth, accessControl)) {
59+
return true;
60+
}
61+
62+
if (allowedByUsers(auth, accessControl)) {
63+
return true;
64+
}
65+
66+
if (allowedByExpression(auth, spec, accessControl)) {
67+
return true;
68+
}
69+
70+
return false;
71+
}
72+
73+
public boolean hasAccessControl(AccessControl accessControl) {
74+
if (accessControl == null) {
75+
return true;
76+
}
77+
78+
return !accessControl.hasGroupAccess()
79+
&& !accessControl.hasUserAccess()
80+
&& !accessControl.hasExpressionAccess();
81+
}
82+
83+
public boolean allowedByGroups(Authentication auth, AccessControl accessControl) {
84+
if (!accessControl.hasGroupAccess()) {
85+
// no groups defined -> this user has no access based on the groups
86+
return false;
87+
}
88+
for (String group : accessControl.getGroups()) {
89+
if (userService.isMember(auth, group)) {
90+
return true;
91+
}
92+
}
93+
return false;
94+
}
95+
96+
public boolean allowedByUsers(Authentication auth, AccessControl accessControl) {
97+
if (!accessControl.hasUserAccess()) {
98+
// no users defined -> this user has no access based on the users
99+
return false;
100+
}
101+
for (String user : accessControl.getUsers()) {
102+
if (auth.getName().equals(user)) {
103+
return true;
104+
}
105+
}
106+
return false;
107+
}
108+
109+
public boolean allowedByExpression(Authentication auth, ProxySpec spec, AccessControl accessControl) {
110+
if (!accessControl.hasExpressionAccess()) {
111+
// no expression defined -> this user has no access based on the expression
112+
return false;
113+
}
114+
SpecExpressionContext context = SpecExpressionContext.create(auth, auth.getPrincipal(), auth.getCredentials(), spec);
115+
return specExpressionResolver.evaluateToBoolean(accessControl.getExpression(), context);
116+
}
117+
118+
}

0 commit comments

Comments
 (0)