1
2
3
4
5
6 package org.tailormap.api.security;
7
8 import java.util.HashSet;
9 import java.util.List;
10 import java.util.Optional;
11 import java.util.Set;
12 import org.springframework.security.authentication.AnonymousAuthenticationToken;
13 import org.springframework.security.core.Authentication;
14 import org.springframework.security.core.GrantedAuthority;
15 import org.springframework.security.core.context.SecurityContextHolder;
16 import org.springframework.stereotype.Service;
17 import org.tailormap.api.persistence.Application;
18 import org.tailormap.api.persistence.GeoService;
19 import org.tailormap.api.persistence.Group;
20 import org.tailormap.api.persistence.json.AuthorizationRule;
21 import org.tailormap.api.persistence.json.AuthorizationRuleDecision;
22 import org.tailormap.api.persistence.json.GeoServiceLayer;
23 import org.tailormap.api.persistence.json.GeoServiceLayerSettings;
24
25
26
27
28
29 @Service
30 public class AuthorizationService {
31 public static final String ACCESS_TYPE_READ = "read";
32
33 private Optional<AuthorizationRuleDecision> isAuthorizedByRules(List<AuthorizationRule> rules, String type) {
34 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
35 Set<String> groups;
36
37 if (auth == null || auth instanceof AnonymousAuthenticationToken) {
38 groups = Set.of(Group.ANONYMOUS);
39 } else {
40 groups = new HashSet<>();
41 groups.add(Group.ANONYMOUS);
42 groups.add(Group.AUTHENTICATED);
43
44 for (GrantedAuthority authority : auth.getAuthorities()) {
45 groups.add(authority.getAuthority());
46 }
47 }
48
49
50 if (groups.contains(Group.ADMIN)) {
51 return Optional.of(AuthorizationRuleDecision.ALLOW);
52 }
53
54 boolean hasValidRule = false;
55
56 for (AuthorizationRule rule : rules) {
57 boolean matchesGroup = groups.contains(rule.getGroupName());
58 if (!matchesGroup) {
59 continue;
60 }
61
62 hasValidRule = true;
63
64 AuthorizationRuleDecision value = rule.getDecisions().get(type);
65 if (value == null) {
66 return Optional.empty();
67 }
68
69 if (value.equals(AuthorizationRuleDecision.ALLOW)) {
70 return Optional.of(value);
71 }
72 }
73
74 if (hasValidRule) {
75 return Optional.of(AuthorizationRuleDecision.DENY);
76 }
77
78 return Optional.empty();
79 }
80
81
82
83
84
85
86
87 public boolean mayUserRead(Application application) {
88 return isAuthorizedByRules(application.getAuthorizationRules(), ACCESS_TYPE_READ)
89 .equals(Optional.of(AuthorizationRuleDecision.ALLOW));
90 }
91
92
93
94
95
96
97
98 public boolean mayUserRead(GeoService geoService) {
99 return isAuthorizedByRules(geoService.getAuthorizationRules(), ACCESS_TYPE_READ)
100 .equals(Optional.of(AuthorizationRuleDecision.ALLOW));
101 }
102
103
104
105
106
107
108
109
110 public boolean mayUserRead(GeoService geoService, GeoServiceLayer layer) {
111 Optional<AuthorizationRuleDecision> geoserviceDecision =
112 isAuthorizedByRules(geoService.getAuthorizationRules(), ACCESS_TYPE_READ);
113
114 if (geoserviceDecision.equals(Optional.of(AuthorizationRuleDecision.DENY))) {
115 return false;
116 }
117
118 GeoServiceLayerSettings settings =
119 geoService.getSettings().getLayerSettings().get(layer.getName());
120 if (settings != null && settings.getAuthorizationRules() != null) {
121 Optional<AuthorizationRuleDecision> decision =
122 isAuthorizedByRules(settings.getAuthorizationRules(), ACCESS_TYPE_READ);
123
124 if (decision.isPresent() || !settings.getAuthorizationRules().isEmpty()) {
125 return decision.equals(Optional.of(AuthorizationRuleDecision.ALLOW));
126 }
127 }
128
129 return geoserviceDecision.equals(Optional.of(AuthorizationRuleDecision.ALLOW));
130 }
131
132
133
134
135
136
137
138
139
140
141 public boolean mustDenyAccessForSecuredProxy(Application application, GeoService geoService) {
142 if (!Boolean.TRUE.equals(geoService.getSettings().getUseProxy())) {
143 return false;
144 }
145 if (geoService.getAuthentication() == null) {
146 return false;
147 }
148 return application.getAuthorizationRules().stream()
149 .anyMatch(rule -> Group.ANONYMOUS.equals(rule.getGroupName())
150 && AuthorizationRuleDecision.ALLOW.equals(
151 rule.getDecisions().get(ACCESS_TYPE_READ)));
152 }
153 }