blob: 4dedb306d7f28839cbb07076bd0b5aea26cfbc15 [file] [log] [blame]
Michael Hanldeb3c212015-10-16 23:02:24 +02001package de.ids_mannheim.korap.security.ac;
2
Michael Hanlf21773f2015-10-16 23:02:31 +02003import de.ids_mannheim.korap.resources.KustvaktResource;
4import de.ids_mannheim.korap.resources.ResourceFactory;
5import de.ids_mannheim.korap.security.PolicyCondition;
6import de.ids_mannheim.korap.security.PolicyContext;
7import de.ids_mannheim.korap.security.SecurityPolicy;
Michael Hanldeb3c212015-10-16 23:02:24 +02008import de.ids_mannheim.korap.user.User;
9import de.ids_mannheim.korap.utils.PrefixTreeMap;
10import lombok.Data;
11import org.springframework.dao.DataAccessException;
12import org.springframework.jdbc.core.ResultSetExtractor;
13import org.springframework.jdbc.core.RowMapper;
14
15import java.sql.ResultSet;
16import java.sql.SQLException;
Michael Hanldeb3c212015-10-16 23:02:24 +020017import java.util.*;
18
19/**
20 * @author hanl
21 * @date 03/03/2014
22 */
23public class SecurityRowMappers {
24
25 public static class PolicyRowMapper implements RowMapper<SecurityPolicy> {
26
27 @Override
28 public SecurityPolicy mapRow(ResultSet rs, int rowNum)
29 throws SQLException {
30 SecurityPolicy p = new SecurityPolicy();
31 p.setID(rs.getInt("pid")).setTarget(rs.getString("persistent_id"))
32 .setPOSIX(rs.getString("perm"));
33
34 PolicyContext context = new PolicyContext();
35 context.setIPMask(rs.getString("iprange"));
Michael Hanl7368aa42016-02-05 18:15:47 +010036 long enable = rs.getLong("enable");
37 long expire = rs.getLong("expire");
38 if (enable != -1)
39 context.setEnableTime(enable);
40 if (expire != -1)
41 context.setExpirationTime(expire);
Michael Hanldeb3c212015-10-16 23:02:24 +020042 // context.addFlag("export", rs.getBoolean("export"));
43 // context.addFlag("sym_use", rs.getInt("sym_use"));
44 p.setContext(context);
45 return p;
46 }
47 }
48
49 @Data
50 public static class FlagContext extends PolicyContext {
51
52 private Map<String, Object> flags;
53
54 public FlagContext() {
55 this.flags = new HashMap<>();
56 }
57
58 public FlagContext addFlag(String key, Object value) {
59 this.flags.put(key, value);
60 return this;
61 }
62
63 public FlagContext removeFlag(String key) {
64 this.flags.remove(key);
65 return this;
66 }
67
68 public FlagContext clearFlags() {
69 this.flags.clear();
70 return this;
71 }
72 }
73
74 public static List<SecurityPolicy>[] mapping(ResultSet rs, User user)
75 throws SQLException {
76 List<SecurityPolicy>[] policyArray = null;
77 List<Integer>[] idx = null;
78 while (rs.next()) {
79 // user has no permission here --> thus skip
80 if (rs.getInt("allowed") == 0)
81 continue;
82
83 if (policyArray == null) {
84 int v = rs.getInt("max_depth") + 1;
85 policyArray = new List[v];
86 idx = new List[v];
87 }
88
89 int depth = rs.getInt("depth");
90
91 if (policyArray[depth] == null) {
92 policyArray[depth] = new ArrayList<>();
93 idx[depth] = new ArrayList<>();
94 }
95
96 Integer pid = rs.getInt("pid");
Michael Hanl19390652016-01-16 11:01:24 +010097 String grouping = rs.getString("group_id");
Michael Hanldeb3c212015-10-16 23:02:24 +020098 Integer index = idx[depth].indexOf(pid);
99
100 SecurityPolicy policy;
101 if (index == -1) {
102 if (pid == -1 && grouping.equalsIgnoreCase("self")) {
103 policy = new SecurityPolicy.OwnerPolicy(
Michael Hanlf21773f2015-10-16 23:02:31 +0200104 rs.getString("persistent_id"),
105 rs.getInt("creator"));
Michael Hanldeb3c212015-10-16 23:02:24 +0200106 policyArray[depth].add(0, policy);
107 idx[depth].add(0, pid);
108 }else {
109 policy = new SecurityRowMappers.PolicyRowMapper()
110 .mapRow(rs, 0);
111 policyArray[depth].add(policy);
112 idx[depth].add(pid);
113
114 //todo:
115 // if (policy.isActive(user)) {
116 // policyArray[depth].add(policy);
117 // idx[depth].add(pid);
118 // }
119 }
120 }else
121 policy = policyArray[depth].get(index);
122
Michael Hanl19390652016-01-16 11:01:24 +0100123 PolicyCondition c = new PolicyCondition(rs.getString("group_id"));
Michael Hanldeb3c212015-10-16 23:02:24 +0200124 if (!policy.contains(c))
125 policy.addCondition(c);
126 }
127 return policyArray;
128 }
129
130 @Deprecated
131 public static List<SecurityPolicy>[] map(ResultSet rs) throws SQLException {
132 Map<Integer, SecurityPolicy>[] policyArray = null;
133 while (rs.next()) {
134 // user has no permission here!
135 if (rs.getInt("allowed") == 0)
136 continue;
137
138 if (policyArray == null)
139 policyArray = new Map[rs.getInt("max_depth") + 1];
140
141 int depth = rs.getInt("depth");
142 Map<Integer, SecurityPolicy> cursor = policyArray[depth];
143 if (cursor == null)
144 cursor = new HashMap<>();
145
146 Integer pid = rs.getInt("pid");
147 SecurityPolicy policy = cursor.get(pid);
148 if (policy == null) {
149 policy = new SecurityRowMappers.PolicyRowMapper().mapRow(rs, 0);
150 cursor.put(pid, policy);
151 }
152 PolicyCondition c = new PolicyCondition(rs.getString("group_ref"));
153
154 if (!policy.contains(c))
155 policy.addCondition(c);
156 }
157
158 List<SecurityPolicy>[] results;
159 if (policyArray == null) {
160 results = new List[1];
161 results[0] = new ArrayList<>();
162 }else {
163 results = new List[policyArray.length];
164 for (int idx = 0; idx < policyArray.length; idx++) {
165 if (policyArray[idx] != null)
166 results[idx] = new ArrayList<>(policyArray[idx].values());
167 else
168 results[idx] = new ArrayList<>();
169 }
170 }
171 return results;
172 }
173
174 public static class HierarchicalResultExtractor
Michael Hanlf21773f2015-10-16 23:02:31 +0200175 implements ResultSetExtractor<List<KustvaktResource.Container>> {
Michael Hanldeb3c212015-10-16 23:02:24 +0200176
177 private boolean _withpid;
178
179 // public HierarchicalResultExtractor(boolean wpid) {
180 // this._withpid = wpid;
181 // }
182
183 // todo: in order for this to work, all parent flags need to be matched in sql!
Michael Hanlf21773f2015-10-16 23:02:31 +0200184 public List<KustvaktResource.Container> extractData(ResultSet rs)
Michael Hanldeb3c212015-10-16 23:02:24 +0200185 throws SQLException, DataAccessException {
186 // contains the container with the highest available name_path to retrieve partial matches!
Michael Hanlf21773f2015-10-16 23:02:31 +0200187 PrefixTreeMap<KustvaktResource.Container[]> containerMap = new PrefixTreeMap<>();
Michael Hanldeb3c212015-10-16 23:02:24 +0200188 Map<Integer, SecurityPolicy> trace = new HashMap<>();
189
190 while (rs.next()) {
Michael Hanlf21773f2015-10-16 23:02:31 +0200191 KustvaktResource.Container[] cursor;
Michael Hanldeb3c212015-10-16 23:02:24 +0200192 Integer pid = rs.getInt("pid");
193
194 SecurityPolicy policy = trace.get(pid);
195 if (policy == null | pid == -1) {
196 // Integer id = rs.getInt("id");
197 String persistentId = rs.getString("persistent_id");
198 int depth = rs.getInt("depth");
199 String namePath = rs.getString("name_path");
200 policy = new SecurityRowMappers.PolicyRowMapper()
201 .mapRow(rs, 0);
202
203 //todo: put active status here!
204 trace.put(pid, policy);
205
206 //fixme: since leaves are mentioned first, maybe retrieve
Michael Hanlf21773f2015-10-16 23:02:31 +0200207 SortedMap<String, KustvaktResource.Container[]> submatch;
Michael Hanldeb3c212015-10-16 23:02:24 +0200208 if ((submatch = containerMap.getPrefixSubMap(namePath))
209 == null) {
Michael Hanl19390652016-01-16 11:01:24 +0100210 //create container for last child node
Michael Hanlf21773f2015-10-16 23:02:31 +0200211 cursor = new KustvaktResource.Container[depth + 1];
212 cursor[depth] = new KustvaktResource.Container(
Michael Hanldeb3c212015-10-16 23:02:24 +0200213 persistentId,
214 ResourceFactory.getResource(rs.getInt("type"))
215 .getClass());
216 containerMap.put(namePath, cursor);
217 }else {
Michael Hanlf21773f2015-10-16 23:02:31 +0200218 KustvaktResource.Container[] values = submatch
Michael Hanldeb3c212015-10-16 23:02:24 +0200219 .get(submatch.firstKey());
Michael Hanlf21773f2015-10-16 23:02:31 +0200220 values[depth] = new KustvaktResource.Container(
Michael Hanldeb3c212015-10-16 23:02:24 +0200221 persistentId,
222 ResourceFactory.getResource(rs.getInt("type"))
223 .getClass());
224 }
225 }
226 }
227
Michael Hanlf21773f2015-10-16 23:02:31 +0200228 List<KustvaktResource.Container> result = new ArrayList<>();
229 for (KustvaktResource.Container[] values : containerMap.values()) {
230 for (KustvaktResource.Container container : values)
Michael Hanldeb3c212015-10-16 23:02:24 +0200231 if (container == null)
232 containerMap.remove(values);
233 result.add(values[values.length - 1]);
234 }
235 return result;
236 }
237 }
238
239}