blob: bf2de6428f3ac273b74d11eb5e275fd3707dabf8 [file] [log] [blame]
Michael Hanldeb3c212015-10-16 23:02:24 +02001package de.ids_mannheim.korap.security.ac;
2
3import de.ids_mannheim.korap.ext.resource.KorAPResource;
4import de.ids_mannheim.korap.ext.resource.ResourceFactory;
5import de.ids_mannheim.korap.ext.security.types.PolicyCondition;
6import de.ids_mannheim.korap.ext.security.types.PolicyContext;
7import de.ids_mannheim.korap.ext.security.types.SecurityPolicy;
8import 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;
17import java.sql.Timestamp;
18import java.util.*;
19
20/**
21 * @author hanl
22 * @date 03/03/2014
23 */
24public class SecurityRowMappers {
25
26 public static class PolicyRowMapper implements RowMapper<SecurityPolicy> {
27
28 @Override
29 public SecurityPolicy mapRow(ResultSet rs, int rowNum)
30 throws SQLException {
31 SecurityPolicy p = new SecurityPolicy();
32 p.setID(rs.getInt("pid")).setTarget(rs.getString("persistent_id"))
33 .setPOSIX(rs.getString("perm"));
34
35 PolicyContext context = new PolicyContext();
36 context.setIPMask(rs.getString("iprange"));
37 Timestamp date = rs.getTimestamp("enable");
38 Timestamp date2 = rs.getTimestamp("expire");
39 if (date != null)
40 context.setEnableTime(date.getTime());
41 if (date2 != null)
42 context.setExpirationTime(date2.getTime());
43 // context.addFlag("export", rs.getBoolean("export"));
44 // context.addFlag("sym_use", rs.getInt("sym_use"));
45 p.setContext(context);
46 return p;
47 }
48 }
49
50 @Data
51 public static class FlagContext extends PolicyContext {
52
53 private Map<String, Object> flags;
54
55 public FlagContext() {
56 this.flags = new HashMap<>();
57 }
58
59 public FlagContext addFlag(String key, Object value) {
60 this.flags.put(key, value);
61 return this;
62 }
63
64 public FlagContext removeFlag(String key) {
65 this.flags.remove(key);
66 return this;
67 }
68
69 public FlagContext clearFlags() {
70 this.flags.clear();
71 return this;
72 }
73 }
74
75 public static List<SecurityPolicy>[] mapping(ResultSet rs, User user)
76 throws SQLException {
77 List<SecurityPolicy>[] policyArray = null;
78 List<Integer>[] idx = null;
79 while (rs.next()) {
80 // user has no permission here --> thus skip
81 if (rs.getInt("allowed") == 0)
82 continue;
83
84 if (policyArray == null) {
85 int v = rs.getInt("max_depth") + 1;
86 policyArray = new List[v];
87 idx = new List[v];
88 }
89
90 int depth = rs.getInt("depth");
91
92 if (policyArray[depth] == null) {
93 policyArray[depth] = new ArrayList<>();
94 idx[depth] = new ArrayList<>();
95 }
96
97 Integer pid = rs.getInt("pid");
98 String grouping = rs.getString("group_ref");
99 Integer index = idx[depth].indexOf(pid);
100
101 SecurityPolicy policy;
102 if (index == -1) {
103 if (pid == -1 && grouping.equalsIgnoreCase("self")) {
104 policy = new SecurityPolicy.OwnerPolicy(
105 rs.getString("persistent_id"), rs.getInt("creator"));
106 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
123 PolicyCondition c = new PolicyCondition(rs.getString("group_ref"));
124 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
175 implements ResultSetExtractor<List<KorAPResource.Container>> {
176
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!
184 public List<KorAPResource.Container> extractData(ResultSet rs)
185 throws SQLException, DataAccessException {
186 // contains the container with the highest available name_path to retrieve partial matches!
187 PrefixTreeMap<KorAPResource.Container[]> containerMap = new PrefixTreeMap<>();
188 Map<Integer, SecurityPolicy> trace = new HashMap<>();
189
190 while (rs.next()) {
191 KorAPResource.Container[] cursor;
192 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
207 SortedMap<String, KorAPResource.Container[]> submatch;
208 if ((submatch = containerMap.getPrefixSubMap(namePath))
209 == null) {
210
211 cursor = new KorAPResource.Container[depth + 1];
212 cursor[depth] = new KorAPResource.Container(
213 persistentId,
214 ResourceFactory.getResource(rs.getInt("type"))
215 .getClass());
216 containerMap.put(namePath, cursor);
217 }else {
218 KorAPResource.Container[] values = submatch
219 .get(submatch.firstKey());
220 values[depth] = new KorAPResource.Container(
221 persistentId,
222 ResourceFactory.getResource(rs.getInt("type"))
223 .getClass());
224 }
225 }
226 }
227
228 List<KorAPResource.Container> result = new ArrayList<>();
229 for (KorAPResource.Container[] values : containerMap.values()) {
230 for (KorAPResource.Container container : values)
231 if (container == null)
232 containerMap.remove(values);
233 result.add(values[values.length - 1]);
234 }
235 return result;
236 }
237 }
238
239}