From 4dd3723fc5a4db31e53c8c816265d783b862850e Mon Sep 17 00:00:00 2001 From: "lucio.lelii" Date: Fri, 5 Feb 2016 18:14:35 +0000 Subject: [PATCH] git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/Common/authorization-common-library@122881 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../AuthorizationInvocationHandler.java | 66 ------------------ .../library/GenericProxyFactory.java | 15 ---- .../library/ResourceAuthorizationProxy.java | 19 ------ .../annotations/AuthorizationControl.java | 4 +- .../policies/{Mode.java => Action.java} | 4 +- .../library/policies/Policy.java | 2 +- .../authorization/library/policies/Role.java | 24 ++++++- .../authorization/library/policies/Roles.java | 14 ++++ .../policies/Service2ServicePolicy.java | 8 +-- .../library/policies/ServiceAccess.java | 26 +++++++ .../authorization/library/policies/User.java | 12 +++- .../library/policies/User2ServicePolicy.java | 11 ++- .../library/policies/UserEntity.java | 53 +++++++++++---- .../authorization/library/policies/Users.java | 14 ++++ .../library/binder/SubsetTest.java | 68 +++++++++++++++++++ .../library/policies/SerializationTest.java | 2 +- 16 files changed, 209 insertions(+), 133 deletions(-) delete mode 100644 src/main/java/org/gcube/common/authorization/library/AuthorizationInvocationHandler.java delete mode 100644 src/main/java/org/gcube/common/authorization/library/GenericProxyFactory.java delete mode 100644 src/main/java/org/gcube/common/authorization/library/ResourceAuthorizationProxy.java rename src/main/java/org/gcube/common/authorization/library/policies/{Mode.java => Action.java} (50%) create mode 100644 src/main/java/org/gcube/common/authorization/library/policies/Roles.java create mode 100644 src/main/java/org/gcube/common/authorization/library/policies/Users.java create mode 100644 src/test/java/org/gcube/common/authorization/library/binder/SubsetTest.java diff --git a/src/main/java/org/gcube/common/authorization/library/AuthorizationInvocationHandler.java b/src/main/java/org/gcube/common/authorization/library/AuthorizationInvocationHandler.java deleted file mode 100644 index 7dd37ad..0000000 --- a/src/main/java/org/gcube/common/authorization/library/AuthorizationInvocationHandler.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.gcube.common.authorization.library; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; - -import org.gcube.common.authorization.library.provider.AuthorizationProvider; -import org.gcube.common.authorization.library.provider.ClientInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class AuthorizationInvocationHandler implements InvocationHandler{ - - public static Logger log = LoggerFactory.getLogger(AuthorizationInvocationHandler.class); - - private String handledClass; - - private Object obj; - - ResourceAuthorizationProxy resourceAuthorizationProxy; - - protected AuthorizationInvocationHandler(I obj, String className, ResourceAuthorizationProxy resourceAuthorizationProxy) { - handledClass = className; - this.obj = obj; - this.resourceAuthorizationProxy = resourceAuthorizationProxy; - } - - public Object invoke(Object proxy, Method method, - Object[] args) throws Throwable { - log.trace("calling proxed method "+method.getName()+" on "+handledClass); - ClientInfo info = AuthorizationProvider.instance.get(); - //checkSubjectToQuota(info, method); - //checkIsAllowedFor(info, method); - return method.invoke(obj, args); - } -/* - private static boolean isOneElementContainedinRoles(List elements, String[] allowedRoles){ - for (String role: allowedRoles ) - if (elements.contains(role)) - return true; - return false; - } - - private void checkSubjectToQuota(ClientInfo info, Method method){ - if(method.isAnnotationPresent(SubjectToQuota.class)){ - BannedService service = new BannedService(resourceAuthorizationProxy.getServiceClass(), resourceAuthorizationProxy.getServiceName()); - log.debug("subjectToQuota annotation present, checking for service {} in bannedServices {}",service, info.getBannedServices()); - if (info.getPolicies().contains(service)){ - String message = "blocking method "+method.getName()+" for user "+info.getUserName()+": overquota reached"; - log.warn(message); - throw new SecurityException(message); - } - } else log.debug("is subjectToQuota not present in "+method.getName()); - } - - private void checkIsAllowedFor(ClientInfo info, Method method){ - if(method.isAnnotationPresent(IsAllowedFor.class)){ - IsAllowedFor allowed = method.getAnnotation(IsAllowedFor.class); - if (allowed.roles().length>0 && !isOneElementContainedinRoles(info.getRoles(), allowed.roles())){ - String message = "blocking method "+method.getName()+" for user "+info.getUserName()+": only roles "+Arrays.toString(allowed.roles()) +" can access"; - log.warn(message); - throw new SecurityException(message); - } - } else log.debug("is allowedFor not present in "+method.getName()); - } - */ -} diff --git a/src/main/java/org/gcube/common/authorization/library/GenericProxyFactory.java b/src/main/java/org/gcube/common/authorization/library/GenericProxyFactory.java deleted file mode 100644 index 3fef4e1..0000000 --- a/src/main/java/org/gcube/common/authorization/library/GenericProxyFactory.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.gcube.common.authorization.library; - -import java.lang.reflect.Proxy; - -public class GenericProxyFactory { - - @SuppressWarnings("unchecked") - public static T getProxy(Class intf, - final I obj, ResourceAuthorizationProxy resourceAuthorizationProxy) { - return (T) - Proxy.newProxyInstance(obj.getClass().getClassLoader(), - new Class[] { intf }, - new AuthorizationInvocationHandler(obj, intf.getSimpleName(), resourceAuthorizationProxy)); - } -} \ No newline at end of file diff --git a/src/main/java/org/gcube/common/authorization/library/ResourceAuthorizationProxy.java b/src/main/java/org/gcube/common/authorization/library/ResourceAuthorizationProxy.java deleted file mode 100644 index 07d958e..0000000 --- a/src/main/java/org/gcube/common/authorization/library/ResourceAuthorizationProxy.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.gcube.common.authorization.library; - -public abstract class ResourceAuthorizationProxy { - - private I delegate; - - public ResourceAuthorizationProxy(Class classIntrface, T wrapped){ - delegate = GenericProxyFactory.getProxy(classIntrface,wrapped, this ); - } - - public I getDelegate() { - return delegate; - } - - public abstract String getServiceClass(); - - public abstract String getServiceName(); - -} diff --git a/src/main/java/org/gcube/common/authorization/library/annotations/AuthorizationControl.java b/src/main/java/org/gcube/common/authorization/library/annotations/AuthorizationControl.java index 65a7018..f9cfeb2 100644 --- a/src/main/java/org/gcube/common/authorization/library/annotations/AuthorizationControl.java +++ b/src/main/java/org/gcube/common/authorization/library/annotations/AuthorizationControl.java @@ -6,12 +6,12 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.gcube.common.authorization.library.policies.Mode; +import org.gcube.common.authorization.library.policies.Action; @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface AuthorizationControl { - Mode[] check() default {Mode.ALL}; + Action[] check() default {Action.ALL}; } diff --git a/src/main/java/org/gcube/common/authorization/library/policies/Mode.java b/src/main/java/org/gcube/common/authorization/library/policies/Action.java similarity index 50% rename from src/main/java/org/gcube/common/authorization/library/policies/Mode.java rename to src/main/java/org/gcube/common/authorization/library/policies/Action.java index 78fac8f..dc5e1b3 100644 --- a/src/main/java/org/gcube/common/authorization/library/policies/Mode.java +++ b/src/main/java/org/gcube/common/authorization/library/policies/Action.java @@ -1,6 +1,6 @@ package org.gcube.common.authorization.library.policies; -public enum Mode { +public enum Action { - ALL, ACCESS, WRITE, EXECUTE; + ALL, ACCESS, WRITE, DELETE, EXECUTE; } diff --git a/src/main/java/org/gcube/common/authorization/library/policies/Policy.java b/src/main/java/org/gcube/common/authorization/library/policies/Policy.java index b41215f..8e38520 100644 --- a/src/main/java/org/gcube/common/authorization/library/policies/Policy.java +++ b/src/main/java/org/gcube/common/authorization/library/policies/Policy.java @@ -22,7 +22,7 @@ public abstract class Policy { public abstract String getContext(); - public abstract Mode getMode(); + public abstract Action getMode(); public long getId() { return id; diff --git a/src/main/java/org/gcube/common/authorization/library/policies/Role.java b/src/main/java/org/gcube/common/authorization/library/policies/Role.java index 86af854..aa612bc 100644 --- a/src/main/java/org/gcube/common/authorization/library/policies/Role.java +++ b/src/main/java/org/gcube/common/authorization/library/policies/Role.java @@ -1,5 +1,7 @@ package org.gcube.common.authorization.library.policies; +import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; @@ -8,17 +10,37 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlAccessorType(XmlAccessType.FIELD) public class Role extends UserEntity { + protected Role() { super(); } - public Role(String identifier) { + protected Role(String identifier) { super(identifier); } + + protected Role(List excludes) { + super(excludes); + } @Override public UserEntityType getType() { return UserEntityType.ROLE; } + @Override + public boolean isSubsetOf(UserEntity entity) { + if (entity.getType()==UserEntityType.ROLE){ + if (this.getIdentifier()==null) + return entity.getIdentifier()==null && entity.getExcludes().containsAll(this.getExcludes()); + else { + if (entity.getIdentifier()!=null) + return entity.getIdentifier().equals(this.getIdentifier()); + else + return !entity.getExcludes().contains(this.getIdentifier()); + } + + } else return entity.getIdentifier()==null; + } + } diff --git a/src/main/java/org/gcube/common/authorization/library/policies/Roles.java b/src/main/java/org/gcube/common/authorization/library/policies/Roles.java new file mode 100644 index 0000000..84725f6 --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/library/policies/Roles.java @@ -0,0 +1,14 @@ +package org.gcube.common.authorization.library.policies; + +import java.util.Arrays; + +public class Roles { + + public static Role one(String identifier){ + return new Role(identifier); + } + + public static Role allExcept(String ... identifiers){ + return new Role(Arrays.asList(identifiers)); + } +} diff --git a/src/main/java/org/gcube/common/authorization/library/policies/Service2ServicePolicy.java b/src/main/java/org/gcube/common/authorization/library/policies/Service2ServicePolicy.java index 4b75498..738cf34 100644 --- a/src/main/java/org/gcube/common/authorization/library/policies/Service2ServicePolicy.java +++ b/src/main/java/org/gcube/common/authorization/library/policies/Service2ServicePolicy.java @@ -11,7 +11,7 @@ public class Service2ServicePolicy extends Policy{ private ServiceAccess client; private String context; private ServiceAccess serviceAccess; - private Mode mode = Mode.ALL; + private Action mode = Action.ALL; protected Service2ServicePolicy(){} @@ -23,7 +23,7 @@ public class Service2ServicePolicy extends Policy{ } public Service2ServicePolicy(String context, ServiceAccess serviceAccess, - ServiceAccess client, Mode mode) { + ServiceAccess client, Action mode) { this(context, serviceAccess, client); this.mode = mode; } @@ -35,7 +35,7 @@ public class Service2ServicePolicy extends Policy{ @Override public String getPolicyAsString() { - return this.context+","+serviceAccess.getAsString()+","+serviceAccess.getAsString()+"["+mode.toString()+"]"; + return this.context+","+serviceAccess.getAsString()+","+serviceAccess.getAsString()+","+mode.toString(); } public ServiceAccess getClient() { @@ -99,7 +99,7 @@ public class Service2ServicePolicy extends Policy{ } @Override - public Mode getMode() { + public Action getMode() { return this.mode; } diff --git a/src/main/java/org/gcube/common/authorization/library/policies/ServiceAccess.java b/src/main/java/org/gcube/common/authorization/library/policies/ServiceAccess.java index 96d6361..b205957 100644 --- a/src/main/java/org/gcube/common/authorization/library/policies/ServiceAccess.java +++ b/src/main/java/org/gcube/common/authorization/library/policies/ServiceAccess.java @@ -40,6 +40,8 @@ public class ServiceAccess { this.serviceSpecificPolices = serviceSpecificPolices; }*/ + + public String getAsString(){ if (serviceClass == null) return "*"; @@ -60,6 +62,30 @@ public class ServiceAccess { return toReturn.toString(); } + public String getServiceClass() { + return serviceClass; + } + + public String getName() { + return name; + } + + public String getServiceId() { + return serviceId; + } + + public boolean isSubsetOf(ServiceAccess access){ + if (this.equals(access)) return true; + if (access.getServiceClass()==null) return true; + + if (access.getServiceClass().equals(this.serviceClass)){ + if (access.getName()==null) return true; + if (access.getName().equals(this.name) && access.getServiceId()==null) + return true; + } + return false; + } + @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/org/gcube/common/authorization/library/policies/User.java b/src/main/java/org/gcube/common/authorization/library/policies/User.java index c27275f..5176236 100644 --- a/src/main/java/org/gcube/common/authorization/library/policies/User.java +++ b/src/main/java/org/gcube/common/authorization/library/policies/User.java @@ -12,13 +12,21 @@ public class User extends UserEntity { super(); } - public User(String identifier) { + protected User(String identifier) { super(identifier); } - + @Override public UserEntityType getType() { return UserEntityType.USER; } + @Override + public boolean isSubsetOf(UserEntity entity) { + if (entity.getType()== UserEntityType.USER) + return entity.getIdentifier() ==null || this.getIdentifier().equals(entity.getIdentifier()); + else return false; + } + + } diff --git a/src/main/java/org/gcube/common/authorization/library/policies/User2ServicePolicy.java b/src/main/java/org/gcube/common/authorization/library/policies/User2ServicePolicy.java index 83a2bfb..c492d4f 100644 --- a/src/main/java/org/gcube/common/authorization/library/policies/User2ServicePolicy.java +++ b/src/main/java/org/gcube/common/authorization/library/policies/User2ServicePolicy.java @@ -18,7 +18,7 @@ public class User2ServicePolicy extends Policy { private String context; private ServiceAccess serviceAccess; - private Mode mode = Mode.ALL; + private Action mode = Action.ALL; protected User2ServicePolicy(){} @@ -28,12 +28,11 @@ public class User2ServicePolicy extends Policy { this.entity = entity; } - public User2ServicePolicy(String context, ServiceAccess serviceAccess, UserEntity entity, Mode mode) { + public User2ServicePolicy(String context, ServiceAccess serviceAccess, UserEntity entity, Action mode) { this(context, serviceAccess, entity); this.mode = mode; } - public UserEntity getEntity() { return entity; } @@ -49,15 +48,13 @@ public class User2ServicePolicy extends Policy { @Override public String getPolicyAsString() { - return this.context+","+serviceAccess.getAsString()+","+entity.getAsString()+"["+mode.toString()+"]"; + return this.context+","+serviceAccess.getAsString()+","+entity.getAsString()+","+mode.toString(); } public String getContext() { return context; } - - @Override public int hashCode() { final int prime = 31; @@ -106,7 +103,7 @@ public class User2ServicePolicy extends Policy { } @Override - public Mode getMode() { + public Action getMode() { return this.mode; } diff --git a/src/main/java/org/gcube/common/authorization/library/policies/UserEntity.java b/src/main/java/org/gcube/common/authorization/library/policies/UserEntity.java index ebaa631..13303d7 100644 --- a/src/main/java/org/gcube/common/authorization/library/policies/UserEntity.java +++ b/src/main/java/org/gcube/common/authorization/library/policies/UserEntity.java @@ -1,5 +1,8 @@ package org.gcube.common.authorization.library.policies; +import java.util.ArrayList; +import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; @@ -10,35 +13,54 @@ import javax.xml.bind.annotation.XmlSeeAlso; @XmlSeeAlso({User.class,Role.class}) public abstract class UserEntity { - private String identifier; - + private String identifier = null; + + private List excludes = new ArrayList(); + public enum UserEntityType { ROLE , USER } - + protected UserEntity() { super(); } - public UserEntity(String identifier) { - super(); + protected UserEntity(String identifier) { this.identifier = identifier; } + protected UserEntity(List excludes) { + if (excludes==null || excludes.isEmpty()) throw new IllegalArgumentException("list of excludes cannot be empty"); + this.excludes = excludes; + } + + public String getIdentifier(){ return identifier; } - public abstract UserEntityType getType(); - - public final String getAsString() { - return this.getType()+":"+this.identifier; + public List getExcludes() { + return excludes; } - + + public abstract UserEntityType getType(); + + public final String getAsString() { + if (identifier!=null ) + return this.getType()+":"+this.identifier; + else { + if (excludes !=null && !excludes.isEmpty()) + return this.getType()+":allExcept"+this.excludes; + else return this.getType()+":*"; + } + } + @Override public int hashCode() { final int prime = 31; int result = 1; + result = prime * result + + ((excludes == null) ? 0 : excludes.hashCode()); result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); return result; @@ -53,6 +75,11 @@ public abstract class UserEntity { if (getClass() != obj.getClass()) return false; UserEntity other = (UserEntity) obj; + if (excludes == null) { + if (other.excludes != null) + return false; + } else if (!excludes.equals(other.excludes)) + return false; if (identifier == null) { if (other.identifier != null) return false; @@ -66,7 +93,7 @@ public abstract class UserEntity { return "UserEntity [ "+getAsString()+" ]"; } - - - + public abstract boolean isSubsetOf(UserEntity entity); + + } diff --git a/src/main/java/org/gcube/common/authorization/library/policies/Users.java b/src/main/java/org/gcube/common/authorization/library/policies/Users.java new file mode 100644 index 0000000..d281dd2 --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/library/policies/Users.java @@ -0,0 +1,14 @@ +package org.gcube.common.authorization.library.policies; + + +public class Users { + + public static User one(String identifier){ + return new User(identifier); + } + + public static User all(){ + return new User(); + } + +} diff --git a/src/test/java/org/gcube/common/authorization/library/binder/SubsetTest.java b/src/test/java/org/gcube/common/authorization/library/binder/SubsetTest.java new file mode 100644 index 0000000..27770c5 --- /dev/null +++ b/src/test/java/org/gcube/common/authorization/library/binder/SubsetTest.java @@ -0,0 +1,68 @@ +package org.gcube.common.authorization.library.binder; + + +import org.gcube.common.authorization.library.policies.Role; +import org.gcube.common.authorization.library.policies.Roles; +import org.gcube.common.authorization.library.policies.ServiceAccess; +import org.gcube.common.authorization.library.policies.User; +import org.gcube.common.authorization.library.policies.Users; +import org.junit.Assert; +import org.junit.Test; + +public class SubsetTest { + + @Test + public void serviceAccess(){ + ServiceAccess sa1 = new ServiceAccess(); + ServiceAccess sa2 = new ServiceAccess("C1"); + ServiceAccess sa3 = new ServiceAccess("S1", "C1"); + ServiceAccess sa4 = new ServiceAccess("S1", "C1", "I1"); + ServiceAccess sa5 = new ServiceAccess("S1", "C1", "I1"); + ServiceAccess sa6 = new ServiceAccess("S1", "C1", "I2"); + ServiceAccess sa7 = new ServiceAccess("S2", "C1", "I1"); + ServiceAccess sa8 = new ServiceAccess("S2", "C2", "I1"); + + Assert.assertTrue(sa2.isSubsetOf(sa1)); + Assert.assertFalse(sa1.isSubsetOf(sa2)); + Assert.assertTrue(sa3.isSubsetOf(sa1)); + Assert.assertTrue(sa3.isSubsetOf(sa2)); + + Assert.assertTrue(sa4.isSubsetOf(sa1)); + Assert.assertTrue(sa4.isSubsetOf(sa2)); + Assert.assertTrue(sa4.isSubsetOf(sa3)); + Assert.assertTrue(sa4.isSubsetOf(sa4)); + Assert.assertTrue(sa4.isSubsetOf(sa5)); + + Assert.assertTrue(sa5.isSubsetOf(sa4)); + Assert.assertFalse(sa5.isSubsetOf(sa6)); + Assert.assertFalse(sa7.isSubsetOf(sa3)); + Assert.assertFalse(sa8.isSubsetOf(sa2)); + Assert.assertFalse(sa8.isSubsetOf(sa3)); + Assert.assertTrue(sa8.isSubsetOf(sa1)); + + } + + @Test + public void users(){ + User u1 = Users.one("u1"); + User u2 = Users.one("u2"); + User u3 = Users.all(); + + Assert.assertTrue(u1.isSubsetOf(u3)); + Assert.assertTrue(u2.isSubsetOf(u3)); + Assert.assertFalse(u1.isSubsetOf(u2)); + Assert.assertFalse(u2.isSubsetOf(u1)); + + Role r1 = Roles.one("VREManager"); + Role r2 = Roles.allExcept("VREManager"); + Role r3 = Roles.allExcept("VOManager"); + Role r4 = Roles.allExcept("VOManager", "VREManager"); + + Assert.assertTrue(r1.isSubsetOf(r3)); + Assert.assertFalse(r2.isSubsetOf(r3)); + Assert.assertTrue(r2.isSubsetOf(r4)); + Assert.assertTrue(r3.isSubsetOf(r4)); + Assert.assertFalse(r4.isSubsetOf(r3)); + + } +} diff --git a/src/test/java/org/gcube/common/authorization/library/policies/SerializationTest.java b/src/test/java/org/gcube/common/authorization/library/policies/SerializationTest.java index 038846e..acebc21 100644 --- a/src/test/java/org/gcube/common/authorization/library/policies/SerializationTest.java +++ b/src/test/java/org/gcube/common/authorization/library/policies/SerializationTest.java @@ -20,7 +20,7 @@ public class SerializationTest { @Test public void serializeUserPolicy() throws Exception{ - User2ServicePolicy up = new User2ServicePolicy("/gcube", new ServiceAccess("ServiceName", "ServiceClass","serviceID"), new User("userID")); + User2ServicePolicy up = new User2ServicePolicy("/gcube", new ServiceAccess("ServiceName", "ServiceClass","serviceID"), Roles.allExcept("VREManager", "VOManager")); StringWriter sw = new StringWriter(); context.createMarshaller().marshal(up, sw); User2ServicePolicy upCopy = (User2ServicePolicy)context.createUnmarshaller().unmarshal(new StringReader(sw.toString()));