| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 1 | package de.ids_mannheim.korap.security.ac; |
| 2 | |
| 3 | import de.ids_mannheim.korap.exceptions.NotAuthorizedException; |
| 4 | import de.ids_mannheim.korap.exceptions.StatusCodes; |
| 5 | import de.ids_mannheim.korap.resources.KustvaktResource; |
| 6 | import de.ids_mannheim.korap.resources.Permissions; |
| 7 | import de.ids_mannheim.korap.security.PermissionsBuffer; |
| 8 | import de.ids_mannheim.korap.security.SecurityPolicy; |
| 9 | import de.ids_mannheim.korap.user.KorAPUser; |
| 10 | import de.ids_mannheim.korap.user.User; |
| 11 | import edu.emory.mathcs.backport.java.util.Collections; |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 12 | import org.slf4j.Logger; |
| Michael Hanl | ac113e5 | 2016-01-19 15:49:20 +0100 | [diff] [blame] | 13 | import org.slf4j.LoggerFactory; |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 14 | |
| 15 | import java.util.HashMap; |
| 16 | import java.util.List; |
| 17 | import java.util.Map; |
| 18 | |
| 19 | /** |
| 20 | * Created by hanl on 5/22/14. |
| 21 | */ |
| Michael Hanl | 99cb963 | 2016-06-29 16:24:40 +0200 | [diff] [blame^] | 22 | @Deprecated |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 23 | public class PolicyEvaluator { |
| 24 | |
| Michael Hanl | ac113e5 | 2016-01-19 15:49:20 +0100 | [diff] [blame] | 25 | private static final Logger jlog = LoggerFactory |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 26 | .getLogger(PolicyEvaluator.class); |
| 27 | |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 28 | private final User user; |
| 29 | private final List<SecurityPolicy>[] policies; |
| 30 | private String resourceID; |
| 31 | private PermissionsBuffer permissions; |
| 32 | private boolean processed; |
| 33 | private int relationError = -1; |
| Michael Hanl | 1939065 | 2016-01-16 11:01:24 +0100 | [diff] [blame] | 34 | @Deprecated |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 35 | private Map<String, Object> flags; |
| 36 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 37 | |
| 38 | public PolicyEvaluator (User user, List<SecurityPolicy>[] policies) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 39 | this.user = user; |
| 40 | this.policies = policies; |
| 41 | this.permissions = new PermissionsBuffer(); |
| 42 | this.flags = new HashMap<>(); |
| 43 | } |
| 44 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 45 | |
| 46 | private PolicyEvaluator (User user, KustvaktResource resource) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 47 | this.user = user; |
| 48 | this.resourceID = resource.getPersistentID(); |
| 49 | this.permissions = new PermissionsBuffer(); |
| 50 | this.flags = new HashMap<>(); |
| 51 | this.policies = null; |
| 52 | } |
| 53 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 54 | |
| 55 | public String getResourceID () { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 56 | if (this.resourceID == null && policies[0] != null |
| 57 | && policies[0].get(0) != null) |
| 58 | this.resourceID = policies[0].get(0).getTarget(); |
| 59 | return this.resourceID; |
| 60 | } |
| 61 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 62 | |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 63 | // todo: test benchmarks |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 64 | private List<SecurityPolicy> evaluate (List<SecurityPolicy>[] policies, |
| Michael Hanl | 88b49db | 2016-02-16 17:15:43 +0100 | [diff] [blame] | 65 | Permissions.Permission perm) throws NotAuthorizedException { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 66 | //fixme: what happens in case a parent relation does not allow changing a resource, but the owner of child per default |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 67 | //todo: receives all rights? --> test casing |
| 68 | if (isOwner()) { |
| 69 | jlog.debug("Resource is owned by the user!"); |
| 70 | return policies[0]; |
| 71 | } |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 72 | if (!processed && policies != null) { |
| 73 | for (int i = policies.length - 1; i >= 0; i--) { |
| 74 | int idx = 0; |
| 75 | if (policies[i] != null) { |
| 76 | int ow = getOwner(policies[i]); |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 77 | for (int internal = 0; internal < policies[i].size(); internal++) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 78 | SecurityPolicy s = policies[i].get(internal); |
| 79 | if (i == policies.length - 1) { |
| 80 | if (ow == user.getId()) |
| 81 | this.permissions.addPermission(127); |
| 82 | else if (!(s instanceof SecurityPolicy.OwnerPolicy)) |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 83 | this.permissions.addPermission(s |
| 84 | .getPermissionByte()); |
| 85 | } |
| 86 | else { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 87 | if (ow == user.getId()) |
| 88 | this.permissions.retain(127); |
| 89 | else if (!(s instanceof SecurityPolicy.OwnerPolicy)) |
| 90 | this.permissions.retain(s.getPermissionByte()); |
| 91 | } |
| 92 | idx++; |
| 93 | } |
| 94 | } |
| Michael Hanl | 99cb963 | 2016-06-29 16:24:40 +0200 | [diff] [blame^] | 95 | // checks that there are valid policies on higher level resources, so that user is |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 96 | if (idx == 0) { |
| 97 | relationError = i; |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 98 | throw new NotAuthorizedException( |
| Michael Hanl | 99cb963 | 2016-06-29 16:24:40 +0200 | [diff] [blame^] | 99 | StatusCodes.ACCESS_DENIED, this.getResourceID()); |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 100 | } |
| 101 | } |
| 102 | this.processed = true; |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 103 | if (this.permissions.containsPermission(perm)) |
| 104 | return policies[0]; |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 105 | } |
| 106 | else if (processed && relationError == -1 |
| 107 | && this.permissions.containsPermission(perm)) { |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 108 | jlog.debug("Done processing resource policies"); |
| 109 | jlog.debug("Will return policies to security manager: " |
| 110 | + this.policies[0]); |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 111 | return this.policies[0]; |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 112 | } |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 113 | |
| 114 | return Collections.emptyList(); |
| 115 | } |
| 116 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 117 | |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 118 | /** |
| 119 | * checks read permission |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 120 | * |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 121 | * @return |
| 122 | */ |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 123 | public boolean isAllowed () { |
| Michael Hanl | 88b49db | 2016-02-16 17:15:43 +0100 | [diff] [blame] | 124 | return isAllowed(Permissions.Permission.READ); |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 125 | } |
| 126 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 127 | |
| 128 | public boolean isAllowed (Permissions.Permission perm) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 129 | try { |
| Michael Hanl | 1939065 | 2016-01-16 11:01:24 +0100 | [diff] [blame] | 130 | List s = evaluate(this.policies, perm); |
| 131 | return s != null && !s.isEmpty(); |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 132 | } |
| 133 | catch (NotAuthorizedException e) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 134 | return false; |
| 135 | } |
| 136 | } |
| 137 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 138 | |
| 139 | public boolean isOwner () { |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 140 | return policies != null && this.user.getId() != null |
| 141 | && getOwner(this.policies[0]) == this.user.getId(); |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 142 | } |
| 143 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 144 | |
| 145 | private int getOwner (List<SecurityPolicy> policies) { |
| 146 | if (policies != null && policies.get(0) != null |
| 147 | && policies.get(0) instanceof SecurityPolicy.OwnerPolicy) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 148 | return ((SecurityPolicy.OwnerPolicy) policies.get(0)).getOwner(); |
| 149 | } |
| 150 | return -1; |
| 151 | } |
| 152 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 153 | |
| Michael Hanl | f078532 | 2015-11-13 16:14:45 +0100 | [diff] [blame] | 154 | // todo: what is this supposed to do? |
| Michael Hanl | 1939065 | 2016-01-16 11:01:24 +0100 | [diff] [blame] | 155 | @Deprecated |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 156 | public static PolicyEvaluator setFlags (User user, KustvaktResource resource) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 157 | PolicyEvaluator e = new PolicyEvaluator(user, resource); |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 158 | // e.setFlag("managed", resource.getOwner() == KorAPUser.ADMINISTRATOR_ID); |
| 159 | // e.setFlag("shared", false); |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 160 | return e; |
| 161 | } |
| 162 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 163 | |
| 164 | public <V> V getFlag (String key, V value) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 165 | return (V) this.flags.get(key); |
| 166 | } |
| 167 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 168 | |
| 169 | private <V> void setFlag (String key, V value) { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 170 | this.flags.put(key, value); |
| 171 | } |
| 172 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 173 | |
| 174 | public boolean isManaged () { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 175 | return getOwner(this.policies[0]) == KorAPUser.ADMINISTRATOR_ID; |
| 176 | } |
| 177 | |
| Michael Hanl | 8abaf9e | 2016-05-23 16:46:35 +0200 | [diff] [blame] | 178 | |
| 179 | public boolean isShared () { |
| Michael Hanl | e25dea2 | 2015-09-24 19:37:56 +0200 | [diff] [blame] | 180 | return !isManaged() && !isOwner(); |
| 181 | } |
| 182 | |
| 183 | } |