blob: 5c36e5ca82dcb2c38100f38f7faca024396dccce [file] [log] [blame]
package de.ids_mannheim.korap.security.ac;
import de.ids_mannheim.korap.resources.KustvaktResource;
import de.ids_mannheim.korap.resources.ResourceFactory;
import de.ids_mannheim.korap.security.PolicyCondition;
import de.ids_mannheim.korap.security.PolicyContext;
import de.ids_mannheim.korap.security.SecurityPolicy;
import de.ids_mannheim.korap.utils.PrefixTreeMap;
import lombok.Data;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
/**
* @author hanl
* @date 03/03/2014
*/
public class SecurityRowMappers {
public static class PolicyRowMapper implements RowMapper<SecurityPolicy> {
@Override
public SecurityPolicy mapRow (ResultSet rs, int rowNum)
throws SQLException {
String perms = rs.getString("perm");
SecurityPolicy p = new SecurityPolicy();
p.setID(rs.getInt("pid")).setTarget(rs.getString("persistent_id"))
.setPOSIX(perms);
PolicyContext context = new PolicyContext();
context.setIPMask(rs.getString("iprange"));
long enable = rs.getLong("enable");
long expire = rs.getLong("expire");
if (enable != -1)
context.setEnableTime(enable);
if (expire != -1)
context.setExpirationTime(expire);
// context.addFlag("export", rs.getBoolean("export"));
// context.addFlag("sym_use", rs.getInt("sym_use"));
p.setContext(context);
return p;
}
}
@Data
public static class FlagContext extends PolicyContext {
private Map<String, Object> flags;
public FlagContext () {
this.flags = new HashMap<>();
}
public FlagContext addFlag (String key, Object value) {
this.flags.put(key, value);
return this;
}
public FlagContext removeFlag (String key) {
this.flags.remove(key);
return this;
}
public FlagContext clearFlags () {
this.flags.clear();
return this;
}
}
@SuppressWarnings(value = "all")
public static List<SecurityPolicy>[] mapResourcePolicies (ResultSet rs)
throws SQLException {
List<SecurityPolicy>[] policyArray = null;
List<Integer>[] idx = null;
loop: while (rs.next()) {
// user has no permission here, thus skip
if (rs.getInt("allowed") == 0)
continue loop;
if (policyArray == null) {
int v = rs.getInt("max_depth") + 1;
policyArray = new List[v];
idx = new List[v];
}
int depth = rs.getInt("depth");
if (policyArray[depth] == null) {
policyArray[depth] = new ArrayList<>();
idx[depth] = new ArrayList<>();
}
Integer pid = rs.getInt("pid");
String grouping = rs.getString("group_id");
Integer index = idx[depth].indexOf(pid);
SecurityPolicy policy;
if (index == -1) {
if (pid == -1 && grouping.equalsIgnoreCase("self")) {
policy = new SecurityPolicy.OwnerPolicy(
rs.getString("persistent_id"), rs.getInt("creator"));
policyArray[depth].add(0, policy);
idx[depth].add(0, pid);
}
else {
policy = new SecurityRowMappers.PolicyRowMapper().mapRow(
rs, 0);
policyArray[depth].add(policy);
idx[depth].add(pid);
//todo:
// if (policy.isActive(user)) {
// policyArray[depth].add(policy);
// idx[depth].add(pid);
// }
}
}
else
policy = policyArray[depth].get(index);
PolicyCondition c = new PolicyCondition(rs.getString("group_id"));
if (!policy.contains(c))
policy.addCondition(c);
}
return policyArray;
}
public static List<SecurityPolicy> mapConditionPolicies (ResultSet rs)
throws SQLException {
Map<Integer, SecurityPolicy> policyMap = new HashMap<>();
while (rs.next()) {
if (rs.getInt("allowed") == 0)
continue;
Integer pid = rs.getInt("pid");
SecurityPolicy policy;
if ((policy = policyMap.get(pid)) == null) {
policy = new SecurityRowMappers.PolicyRowMapper().mapRow(rs, 0);
policyMap.put(pid, policy);
}
PolicyCondition c = new PolicyCondition(rs.getString("group_id"));
if (!policy.contains(c))
policy.addNewCondition(c);
}
return new ArrayList<>(policyMap.values());
}
@Deprecated
public static List<SecurityPolicy>[] map (ResultSet rs) throws SQLException {
Map<Integer, SecurityPolicy>[] policyArray = null;
while (rs.next()) {
// user has no permission here!
if (rs.getInt("allowed") == 0)
continue;
if (policyArray == null)
policyArray = new Map[rs.getInt("max_depth") + 1];
int depth = rs.getInt("depth");
Map<Integer, SecurityPolicy> cursor = policyArray[depth];
if (cursor == null)
cursor = new HashMap<>();
Integer pid = rs.getInt("pid");
SecurityPolicy policy = cursor.get(pid);
if (policy == null) {
policy = new SecurityRowMappers.PolicyRowMapper().mapRow(rs, 0);
cursor.put(pid, policy);
}
PolicyCondition c = new PolicyCondition(rs.getString("group_id"));
if (!policy.contains(c))
policy.addNewCondition(c);
}
List<SecurityPolicy>[] results;
if (policyArray == null) {
results = new List[1];
results[0] = new ArrayList<>();
}
else {
results = new List[policyArray.length];
for (int idx = 0; idx < policyArray.length; idx++) {
if (policyArray[idx] != null)
results[idx] = new ArrayList<>(policyArray[idx].values());
else
results[idx] = new ArrayList<>();
}
}
return results;
}
public static class HierarchicalResultExtractor implements
ResultSetExtractor<List<KustvaktResource.Container>> {
private boolean _withpid;
// public HierarchicalResultExtractor(boolean wpid) {
// this._withpid = wpid;
// }
// todo: in order for this to work, all parent flags need to be matched in sql!
public List<KustvaktResource.Container> extractData (ResultSet rs)
throws SQLException, DataAccessException {
// contains the container with the highest available name_path to retrieve partial matches!
PrefixTreeMap<KustvaktResource.Container[]> containerMap = new PrefixTreeMap<>();
Map<Integer, SecurityPolicy> trace = new HashMap<>();
while (rs.next()) {
KustvaktResource.Container[] cursor;
Integer pid = rs.getInt("pid");
SecurityPolicy policy = trace.get(pid);
if (policy == null | pid == -1) {
// Integer id = rs.getInt("id");
String persistentId = rs.getString("persistent_id");
int depth = rs.getInt("depth");
String namePath = rs.getString("name_path");
policy = new SecurityRowMappers.PolicyRowMapper().mapRow(
rs, 0);
//todo: put active status here!
trace.put(pid, policy);
//fixme: since leaves are mentioned first, maybe retrieve
SortedMap<String, KustvaktResource.Container[]> submatch;
if ((submatch = containerMap.getPrefixSubMap(namePath)) == null) {
//create container for last child node
cursor = new KustvaktResource.Container[depth + 1];
cursor[depth] = new KustvaktResource.Container(
persistentId, ResourceFactory.getResource(
rs.getInt("type")).getClass());
containerMap.put(namePath, cursor);
}
else {
KustvaktResource.Container[] values = submatch
.get(submatch.firstKey());
values[depth] = new KustvaktResource.Container(
persistentId, ResourceFactory.getResource(
rs.getInt("type")).getClass());
}
}
}
List<KustvaktResource.Container> result = new ArrayList<>();
for (KustvaktResource.Container[] values : containerMap.values()) {
for (KustvaktResource.Container container : values)
if (container == null)
containerMap.remove(values);
result.add(values[values.length - 1]);
}
return result;
}
}
}