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