From b0917974aa3fd70a6ddcf858810da4afc837fdec Mon Sep 17 00:00:00 2001 From: Lucio Lelii Date: Fri, 25 Nov 2016 14:34:11 +0000 Subject: [PATCH] git-svn-id: https://svn.d4science-ii.research-infrastructures.eu/gcube/branches/common/authorization-service/2.0@134808 82a268e6-3cf1-43bd-a215-b396298e98cf --- pom.xml | 2 +- .../authorizationservice/PolicyManager.java | 4 +- .../authorizationservice/TokenManager.java | 79 ++++++++++- .../configuration/AuthorizationRule.java | 14 +- .../configuration/RuleBuilder.java | 12 +- .../filters/AuthorizedCallFilter.java | 70 ++++++---- .../persistence/RelationDBPersistence.java | 132 +++++++++++------- .../persistence/entities/AuthorizationId.java | 42 +++++- .../ExternalServiceAuthorizationEntity.java | 6 +- .../persistence/entities/PolicyEntity.java | 17 ++- .../entities/ServicePolicyEntity.java | 4 +- .../entities/UserPolicyEntity.java | 5 +- .../util/TokenPersistence.java | 3 + src/main/resources/META-INF/persistence.xml | 2 +- .../WEB-INF/AuthorizationConfiguration.xml | 23 +-- .../org/gcube/common/authz/GenerateTest.java | 4 + .../common/authz/configuration/Binder.java | 3 +- 17 files changed, 297 insertions(+), 125 deletions(-) diff --git a/pom.xml b/pom.xml index d085a95..9f33662 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.gcube.common authorization-service - 2.0.0-SNAPSHOT + 2.0.1-SNAPSHOT authorization service war diff --git a/src/main/java/org/gcube/common/authorizationservice/PolicyManager.java b/src/main/java/org/gcube/common/authorizationservice/PolicyManager.java index 77b68f2..f28e679 100644 --- a/src/main/java/org/gcube/common/authorizationservice/PolicyManager.java +++ b/src/main/java/org/gcube/common/authorizationservice/PolicyManager.java @@ -62,7 +62,9 @@ public class PolicyManager { public Policies getPoliciesPerContext(@NotNull @QueryParam("context") String context) { try{ log.info("retrieving polices in context {}", context); - return new Policies(tokenPersistence.getPolices(context)); + Policies policies = new Policies(tokenPersistence.getPolices(context)); + log.info("returning {} policies from getPoliciesPerContext",policies.getPolicies().size()); + return policies; }catch(Exception e){ log.error("error retrieving policies per context {}", context, e); throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST) diff --git a/src/main/java/org/gcube/common/authorizationservice/TokenManager.java b/src/main/java/org/gcube/common/authorizationservice/TokenManager.java index 8b6d09b..d010773 100644 --- a/src/main/java/org/gcube/common/authorizationservice/TokenManager.java +++ b/src/main/java/org/gcube/common/authorizationservice/TokenManager.java @@ -20,6 +20,7 @@ import javax.ws.rs.core.Response; import lombok.extern.slf4j.Slf4j; import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.ExternalServiceList; import org.gcube.common.authorization.library.provider.ContainerInfo; import org.gcube.common.authorization.library.provider.ExternalServiceInfo; import org.gcube.common.authorization.library.provider.ServiceInfo; @@ -76,6 +77,49 @@ public class TokenManager { } + /** + * + * retrieves the AuthorzationEntry connected to the specified token + * + * @param token + * @return the authorization entry + */ + @GET + @Path("resolve/{user}") + public String getTokenByUserAndContext(@NotNull @PathParam("user") String user, @QueryParam("context") String context ) { + + log.info("resolving token for user {} in context {}",user, context); + + if (context==null){ + log.error("null context found"); + throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND) + .entity("null context found").type(MediaType.TEXT_PLAIN).build()); + } + + String token = persistence.getExistingToken(user, context, Constants.DEFAULT_TOKEN_QUALIFIER); + + + if (token == null){ + log.error("token {} not found ", token); + throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND) + .entity("token for user "+user+" in context "+context+" not found").type(MediaType.TEXT_PLAIN).build()); + } + + //TODO: re-add it with common-scope 2.0 + /* + try{ + ServiceMap map = .instance.getMap(info.getContext()); + info.setMap(map); + }catch(Exception e){ + log.error("error retrieving map for {}", info.getContext(), e); + throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity("Error retrieving map").type(MediaType.TEXT_PLAIN).build()); + }*/ + + return token; + + } + /** * * Generates a token for a user (saving the passed roles) if it doesn't exist yet. @@ -145,21 +189,21 @@ public class TokenManager { * @param externalServiceInfo * @return the generated token or the token related to the external service (if it was already created) */ - @Path("external") + @Path("external/{serviceId}") @PUT @Consumes(MediaType.APPLICATION_XML) - public String generateExternalServiceToken(ExternalServiceInfo externalService, @Context HttpServletRequest req) { + public String generateExternalServiceToken(@PathParam("serviceId") String serviceId, @Context HttpServletRequest req) { try{ AuthorizationEntry info = (AuthorizationEntry)req.getAttribute(AuthorizedCallFilter.AUTH_ATTRIBUTE); - log.info("generator called for external service {} in context {} ",externalService.getId(), info.getContext()); + log.info("generator called for external service {} in context {} ",serviceId, info.getContext()); - if (externalService.getId().split(":").length>1) throw new Exception("invalid external service id: "+externalService.getId()); + if (serviceId.split(":").length>1) throw new Exception("invalid external service id: "+serviceId); - String token = persistence.getExistingToken(externalService.getId(), info.getContext(), Constants.DEFAULT_TOKEN_QUALIFIER); + String token = persistence.getExistingToken(serviceId, info.getContext(), Constants.DEFAULT_TOKEN_QUALIFIER); if (token==null){ token= UUID.randomUUID().toString(); - persistence.saveAuthorizationEntry(token, info.getContext(), externalService, Constants.DEFAULT_TOKEN_QUALIFIER, null); + persistence.saveAuthorizationEntry(token, info.getContext(), new ExternalServiceInfo(serviceId, info.getClientInfo().getId()), Constants.DEFAULT_TOKEN_QUALIFIER, info.getClientInfo().getId()); } return token; @@ -170,6 +214,29 @@ public class TokenManager { } } + /** + * + * Generates a token for an external service if it doesn't exist yet. + * + * @param externalServiceInfo + * @return the generated token or the token related to the external service (if it was already created) + */ + @Path("external") + @GET + @Consumes(MediaType.APPLICATION_XML) + public ExternalServiceList getExternalServiceCreated(@Context HttpServletRequest req) { + try{ + AuthorizationEntry info = (AuthorizationEntry)req.getAttribute(AuthorizedCallFilter.AUTH_ATTRIBUTE); + log.info("get External Service called in context {} by {} ",info.getContext(), info.getClientInfo().getId()); + ExternalServiceList toReturn = new ExternalServiceList(persistence.getExistingExternalServices(info.getClientInfo().getId(), info.getContext())); + return toReturn; + }catch(Exception e){ + log.error("error generating token ",e); + throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST) + .entity("Error Generating Token: "+e.getMessage()).type(MediaType.TEXT_PLAIN).build()); + } + } + @Path("node") @PUT @Consumes(MediaType.APPLICATION_XML) diff --git a/src/main/java/org/gcube/common/authorizationservice/configuration/AuthorizationRule.java b/src/main/java/org/gcube/common/authorizationservice/configuration/AuthorizationRule.java index c8c29ef..9a0c09a 100644 --- a/src/main/java/org/gcube/common/authorizationservice/configuration/AuthorizationRule.java +++ b/src/main/java/org/gcube/common/authorizationservice/configuration/AuthorizationRule.java @@ -9,6 +9,8 @@ import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import org.gcube.common.authorization.library.ClientType; + @XmlRootElement(name="Rule") @XmlAccessorType(XmlAccessType.FIELD) public class AuthorizationRule { @@ -20,16 +22,20 @@ public class AuthorizationRule { @XmlAttribute(name="requiresToken") private boolean requiresToken = true; + @XmlAttribute(name="acceptedTokenTypes") + private List acceptedTokenType = new ArrayList(); + @XmlElement(name="Entity") private List entities= new ArrayList(); protected AuthorizationRule(){} - public AuthorizationRule(String servletPath, List entities, boolean requiresToken) { + public AuthorizationRule(String servletPath, List entities, boolean requiresToken, List acceptedTokenType) { super(); this.servletPath = servletPath; this.entities = entities; this.requiresToken = requiresToken; + this.acceptedTokenType = acceptedTokenType; } public String getServletPath() { @@ -44,6 +50,10 @@ public class AuthorizationRule { public boolean isTokenRequired() { return requiresToken; } + + public List getAcceptedTokenType() { + return acceptedTokenType; + } @Override public int hashCode() { @@ -81,7 +91,7 @@ public class AuthorizationRule { @Override public String toString() { return "AuthorizationRule [servletPath=" + servletPath + ", entities=" - + entities + " requiresToken= "+requiresToken+"]"; + + entities + " requiresToken= "+requiresToken+", acceptedTokenType= "+ acceptedTokenType+" ]"; } diff --git a/src/main/java/org/gcube/common/authorizationservice/configuration/RuleBuilder.java b/src/main/java/org/gcube/common/authorizationservice/configuration/RuleBuilder.java index 111b9d3..950070c 100644 --- a/src/main/java/org/gcube/common/authorizationservice/configuration/RuleBuilder.java +++ b/src/main/java/org/gcube/common/authorizationservice/configuration/RuleBuilder.java @@ -1,14 +1,19 @@ package org.gcube.common.authorizationservice.configuration; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.gcube.common.authorization.library.ClientType; + public class RuleBuilder { private String servletPath; private List entities = new ArrayList(); + + private List acceptedClients = new ArrayList(); private boolean requiresToken= true; @@ -24,8 +29,9 @@ public class RuleBuilder { return this; } - public RuleBuilder needsToken(boolean needsToken){ - this.requiresToken= needsToken; + public RuleBuilder needsToken(ClientType ... typesAccepted){ + this.requiresToken= true; + this.acceptedClients = Arrays.asList(typesAccepted); return this; } @@ -42,6 +48,6 @@ public class RuleBuilder { } public AuthorizationRule build(){ - return new AuthorizationRule(servletPath, entities, requiresToken); + return new AuthorizationRule(servletPath, entities, requiresToken, acceptedClients); } } \ No newline at end of file diff --git a/src/main/java/org/gcube/common/authorizationservice/filters/AuthorizedCallFilter.java b/src/main/java/org/gcube/common/authorizationservice/filters/AuthorizedCallFilter.java index 2c2575c..2e9d4d7 100644 --- a/src/main/java/org/gcube/common/authorizationservice/filters/AuthorizedCallFilter.java +++ b/src/main/java/org/gcube/common/authorizationservice/filters/AuthorizedCallFilter.java @@ -58,16 +58,21 @@ public class AuthorizedCallFilter implements Filter { String pathInfo = ((HttpServletRequest) request).getPathInfo(); log.info("called path {}", pathInfo); + if (pathInfo==null || pathInfo.isEmpty()){ + log.info("call rejected from filters: invalid path info"); + return; + } + + if (requiresToken(pathInfo) && token==null ){ ((HttpServletResponse)response).sendError(HttpServletResponse.SC_UNAUTHORIZED); log.info("call rejected from filters, call requires caller token"); return; } - String callerIp = ((HttpServletRequest)request).getHeader("x-forwarded-for"); - if(callerIp==null) - callerIp=request.getRemoteHost(); + if(callerIp==null) + callerIp=request.getRemoteHost(); log.info("caller ip {}", callerIp); /*X509Certificate certs[] = @@ -97,46 +102,55 @@ public class AuthorizedCallFilter implements Filter { return false; } + + //TODO: review it, something is not working check if is correct that they are in OR private boolean checkAllowed(String pathInfo, String callerIp, AuthorizationEntry info){ AuthorizationConfiguration conf = ConfigurationHolder.getConfiguration(); List rules = conf.getAuthorizationRules(); for (AuthorizationRule rule: rules){ - if (!rule.getEntities().isEmpty() && (pathInfo.startsWith(rule.getServletPath()) || pathInfo.equals(rule.getServletPath()))){ - for (AllowedEntity entity : rule.getEntities()){ - switch(entity.getType()){ - case IP: - log.trace("checking ip rule : {} -> {}", entity.getValue(), callerIp); - if(checkIpInRange(callerIp, entity.getValue())) - return true; - break; - case USER: - log.trace("checking user rule : {} -> {}", entity.getValue(), info.getClientInfo().getId()); - if (entity.getValue().equals(info.getClientInfo().getId())) - return entity.getValue().equals(info.getClientInfo().getId()); - break; - case ROLE: - log.trace("checking role rule : {} -> {}", entity.getValue(), info.getClientInfo().getRoles()); - if (info.getClientInfo().getRoles().contains(entity.getValue())) - return true; - break; - } + if (pathInfo.startsWith(rule.getServletPath()) || pathInfo.equals(rule.getServletPath())){ + if (!rule.getAcceptedTokenType().isEmpty() && !rule.getAcceptedTokenType().contains(info.getClientInfo().getType())){ + log.info("rejecting the call: callerType {} is not in the allowed types defined {} ", info.getClientInfo().getType(), rule.getAcceptedTokenType()); + return false; + } + + if (!rule.getEntities().isEmpty()){ + for (AllowedEntity entity : rule.getEntities()){ + switch(entity.getType()){ + case IP: + log.trace("checking ip rule : {} -> {}", entity.getValue(), callerIp); + if(checkIpInRange(callerIp, entity.getValue())) + return true; + break; + case USER: + log.trace("checking user rule : {} -> {}", entity.getValue(), info.getClientInfo().getId()); + if (entity.getValue().equals(info.getClientInfo().getId())) + return true; + break; + case ROLE: + log.trace("checking role rule : {} -> {}", entity.getValue(), info.getClientInfo().getRoles()); + if (info.getClientInfo().getRoles().contains(entity.getValue())) + return true; + break; + } + } + //IF a servlet path matches the caller is not allowed to that servlet (the call should be rejected) + return false; } - //IF a servlet path matches the caller is not allowed to that servlet (the call should be rejected) - return false; } } return true; } - + private static boolean checkIpInRange(String ip, String mask) { - + String[] maskArray = mask.split("\\."); String[] ipArray = ip.split("\\."); - + int[] maskByte= new int[4]; int[] ipByte = new int[4]; - + for (int i=0; i<4; i++){ maskByte[i] = ((Integer)Integer.parseInt(maskArray[i])).byteValue(); ipByte[i] = ((Integer)Integer.parseInt(ipArray[i])).byteValue(); diff --git a/src/main/java/org/gcube/common/authorizationservice/persistence/RelationDBPersistence.java b/src/main/java/org/gcube/common/authorizationservice/persistence/RelationDBPersistence.java index 9e83a5c..b8571eb 100644 --- a/src/main/java/org/gcube/common/authorizationservice/persistence/RelationDBPersistence.java +++ b/src/main/java/org/gcube/common/authorizationservice/persistence/RelationDBPersistence.java @@ -1,16 +1,17 @@ package org.gcube.common.authorizationservice.persistence; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; import javax.inject.Inject; import javax.inject.Singleton; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; import javax.persistence.NoResultException; import javax.persistence.TypedQuery; @@ -46,6 +47,10 @@ public class RelationDBPersistence implements TokenPersistence{ @Inject EntityManagerFactory emFactory; + ReentrantLock lock = new ReentrantLock(true); + + HashMap synchMap = new HashMap(); + //ONLY FOR TEST PURPOSE public void setEntitymanagerFactory(EntityManagerFactory emf){ this.emFactory = emf; @@ -60,16 +65,12 @@ public class RelationDBPersistence implements TokenPersistence{ query.setParameter("token", token); AuthorizationEntity authEntity; try{ - em.getTransaction().begin(); - authEntity = query.getSingleResult(); - authEntity.setLastTimeUsed(Calendar.getInstance()); - em.merge(authEntity); - em.getTransaction().commit(); + authEntity = query.getSingleResult(); }catch (NoResultException e){ log.warn("no result found for token {}",token); return null; } - + if (authEntity.getEntryType().equals(EntityConstants.SERVICE_AUTHORIZATION)){ ServiceAuthorizationEntity sAuth = (ServiceAuthorizationEntity) authEntity; return new AuthorizationEntry(sAuth.getInfo(), sAuth.getContext(), retrievePolicies(sAuth, em), sAuth.getQualifier()); @@ -114,20 +115,37 @@ public class RelationDBPersistence implements TokenPersistence{ else if (info instanceof ServiceInfo) authEntity = new ServiceAuthorizationEntity(token, context, tokenQualifier, (ServiceInfo) info, generatedBy); else if (info instanceof ExternalServiceInfo) authEntity = new ExternalServiceAuthorizationEntity(token, context, tokenQualifier, (ExternalServiceInfo) info, generatedBy); else authEntity = new NodeAuthorizationEntity(token, context, tokenQualifier, (ContainerInfo) info, generatedBy); - - EntityManager em = emFactory.createEntityManager(); + + AuthorizationId authId = new AuthorizationId(context, info.getId(), tokenQualifier); + lock.lock(); try{ - em.getTransaction().begin(); - em.persist(authEntity); - em.getTransaction().commit(); - }catch(RuntimeException e){ - log.error("error saving authorization Entry", e); - em.getTransaction().rollback(); - throw e; - } finally{ - em.close(); + if (synchMap.containsKey(authId.toString())) + authId = synchMap.get(authId.toString()); + else synchMap.put(authId.toString(), authId); + }finally{ + lock.unlock(); } + synchronized (authId) { + EntityManager em = emFactory.createEntityManager(); + EntityTransaction tx = em.getTransaction(); + try{ + tx.begin(); + AuthorizationEntity ae = em.find(AuthorizationEntity.class, authId); + log.trace("AuthorizationEntity {} found, saving it", (ae==null)?"not":""); + if (ae==null) + em.persist(authEntity); + tx.commit(); + }catch(RuntimeException e){ + log.error("error saving authorization Entry", e); + if (tx.isActive()) + tx.rollback(); + throw e; + } finally{ + em.close(); + synchMap.remove(authId.toString()); + } + } } @@ -147,6 +165,9 @@ public class RelationDBPersistence implements TokenPersistence{ em.getTransaction().commit(); }catch (Exception e) { + log.error("error storing policy",e); + throw new RuntimeException(e); + }finally{ em.close(); } } @@ -164,7 +185,9 @@ public class RelationDBPersistence implements TokenPersistence{ else log.warn("policy with id {} not found", policyId); em.getTransaction().commit(); }catch (Exception e) { - log.error("error removing policy with id {}", policyId); + log.error("error removing policy with id {}", policyId,e); + throw new RuntimeException(e); + }finally{ em.close(); } } @@ -174,14 +197,16 @@ public class RelationDBPersistence implements TokenPersistence{ List policiesToReturn = new ArrayList(); EntityManager em = emFactory.createEntityManager(); try{ - TypedQuery query = em.createNamedQuery("Policy.all", PolicyEntity.class); + TypedQuery query = em.createNamedQuery("Policy.allPolicies", PolicyEntity.class); query.setParameter("context", context); - for (PolicyEntity pEntity: query.getResultList()){ + log.info("query to get all policies in context {} , {} ", query.getParameterValue("context"), query.toString()); + List entities = query.getResultList(); + for (PolicyEntity pEntity: entities ){ Policy policy; if (pEntity.getPolicyType().equals(EntityConstants.SERVICE_POLICY)){ - policy = new Service2ServicePolicy(context, pEntity.getServiceAccess(), ((ServicePolicyEntity) pEntity).getClientAccess(), pEntity.getAction()); + policy = new Service2ServicePolicy(pEntity.getContext(), pEntity.getServiceAccess(), ((ServicePolicyEntity) pEntity).getClientAccess(), pEntity.getAction()); }else - policy = new User2ServicePolicy(context, pEntity.getServiceAccess(), ((UserPolicyEntity) pEntity).getUser(), pEntity.getAction()); + policy = new User2ServicePolicy(pEntity.getContext(), pEntity.getServiceAccess(), ((UserPolicyEntity) pEntity).getUser(), pEntity.getAction()); policy.setId(pEntity.getId()); policy.setCreationTime(pEntity.getCreationTime()); policy.setLastUpdateTime(pEntity.getLastUpdateTime()); @@ -190,6 +215,7 @@ public class RelationDBPersistence implements TokenPersistence{ }finally{ em.close(); } + log.info("policies to return are {} ",policiesToReturn.size()); return policiesToReturn; } @@ -254,6 +280,12 @@ public class RelationDBPersistence implements TokenPersistence{ return policies; } + + /** + * + * + * return a map with key qualifier and value the corresponding token + */ @Override public Map getExistingApiKeys(String clientId, String context) { EntityManager em = emFactory.createEntityManager(); @@ -274,6 +306,32 @@ public class RelationDBPersistence implements TokenPersistence{ } + + /** + * + * + * return a map with key the external service id and value the corresponding token + */ + @Override + public Map getExistingExternalServices(String generatorId, String context) { + EntityManager em = emFactory.createEntityManager(); + + try{ + TypedQuery queryS = em.createNamedQuery("ExternalService.getByGenerator", ExternalServiceAuthorizationEntity.class); + queryS.setParameter("context", context); + queryS.setParameter("generatorId", generatorId); + List externals = queryS.getResultList(); + Map externalServiceMapping = new HashMap(); + for (ExternalServiceAuthorizationEntity external: externals) + externalServiceMapping.put(external.getClientId(), external.getToken()); + return externalServiceMapping; + }finally{ + em.close(); + } + + + } + @Override public void removeApiKey(String token) { EntityManager em = emFactory.createEntityManager(); @@ -291,32 +349,4 @@ public class RelationDBPersistence implements TokenPersistence{ } } - - - /* @Override - public Key getSymmetricKey(String token) { - EntityManager em = emFactory.createEntityManager(); - try{ - //retrieve entity for token - TypedQuery query = em.createNamedQuery("Authz.get", AuthorizationEntity.class); - query.setParameter("token", token); - AuthorizationEntity authEntity; - try{ - authEntity = query.getSingleResult(); - }catch (NoResultException e){ - log.warn("no result found for token {}",token); - return null; - } - - return authEntity.getApiSymmetricKey(); - - }catch(Throwable t){ - log.error("error retrieving key fro token {}",token, t); - return null; - }finally{ - em.close(); - } - }*/ - - } diff --git a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/AuthorizationId.java b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/AuthorizationId.java index 3527cd0..8e6fcd8 100644 --- a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/AuthorizationId.java +++ b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/AuthorizationId.java @@ -22,8 +22,46 @@ public class AuthorizationId { @Override public String toString() { - return "AuthorizationId [context=" + context - + ", clientId=" + clientId + " qualifier ="+qualifier+"]"; + return context+clientId+qualifier; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((clientId == null) ? 0 : clientId.hashCode()); + result = prime * result + ((context == null) ? 0 : context.hashCode()); + result = prime * result + + ((qualifier == null) ? 0 : qualifier.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AuthorizationId other = (AuthorizationId) obj; + if (clientId == null) { + if (other.clientId != null) + return false; + } else if (!clientId.equals(other.clientId)) + return false; + if (context == null) { + if (other.context != null) + return false; + } else if (!context.equals(other.context)) + return false; + if (qualifier == null) { + if (other.qualifier != null) + return false; + } else if (!qualifier.equals(other.qualifier)) + return false; + return true; } diff --git a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/ExternalServiceAuthorizationEntity.java b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/ExternalServiceAuthorizationEntity.java index 03d276f..6885dd1 100644 --- a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/ExternalServiceAuthorizationEntity.java +++ b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/ExternalServiceAuthorizationEntity.java @@ -11,7 +11,9 @@ import org.gcube.common.authorization.library.provider.ExternalServiceInfo; @DiscriminatorValue(EntityConstants.EXTERNAL_SERVICE_AUTHORIZATION) @NamedQueries({ @NamedQuery(name="ExternalService.get", query="SELECT info FROM ExternalServiceAuthorizationEntity info WHERE " - + " info.token=:token AND info.id.context=:context AND info.id.clientId=:clientId") + + " info.token=:token AND info.id.context=:context AND info.id.clientId=:clientId"), + @NamedQuery(name="ExternalService.getByGenerator", query="SELECT info FROM ExternalServiceAuthorizationEntity info WHERE " + + " info.id.context=:context AND info.internalInfo.generatedBy=:generatorId") }) public class ExternalServiceAuthorizationEntity extends AuthorizationEntity{ @@ -22,7 +24,7 @@ public class ExternalServiceAuthorizationEntity extends AuthorizationEntity{ public ExternalServiceAuthorizationEntity(String token, String context, String qualifier, ExternalServiceInfo externalServiceInfo, String generatedBy) { - super(token, context, externalServiceInfo, qualifier, EntityConstants.SERVICE_AUTHORIZATION, generatedBy); + super(token, context, externalServiceInfo, qualifier, EntityConstants.EXTERNAL_SERVICE_AUTHORIZATION, generatedBy); } diff --git a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/PolicyEntity.java b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/PolicyEntity.java index 4555c33..aef2f8a 100644 --- a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/PolicyEntity.java +++ b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/PolicyEntity.java @@ -11,7 +11,6 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; -import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Temporal; @@ -25,10 +24,7 @@ import org.gcube.common.authorization.library.policies.ServiceAccess; @Inheritance @DiscriminatorColumn(name="PolicyType") @Table(name="Policies") -@NamedQueries({ - @NamedQuery(name="Policy.all", query="SELECT policy FROM PolicyEntity policy WHERE " - + " policy.context=:context") -}) +@NamedQuery(name="Policy.allPolicies", query="SELECT policy FROM PolicyEntity policy WHERE policy.context = :context") public abstract class PolicyEntity { @Column @@ -126,5 +122,16 @@ public abstract class PolicyEntity { } public abstract boolean isRewritable(); + + @Override + public String toString() { + return "PolicyEntity [id=" + id + ", context=" + context + + ", policyType=" + policyType + ", serviceAccess=" + + serviceAccess + ", accessServiceClass=" + accessServiceClass + + ", accessServiceName=" + accessServiceName + + ", accessServiceIdentifier=" + accessServiceIdentifier + + ", action=" + action + "]"; + } + } diff --git a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/ServicePolicyEntity.java b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/ServicePolicyEntity.java index f485ce4..93fba6a 100644 --- a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/ServicePolicyEntity.java +++ b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/ServicePolicyEntity.java @@ -73,11 +73,11 @@ public class ServicePolicyEntity extends PolicyEntity { return true; } - + @Override public String toString() { return "ServicePolicyEntity [clientAccessEntity=" + clientAccessEntity - + ", excludes=" + excludes + "]"; + + ", toString()=" + super.toString() + "]"; } diff --git a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/UserPolicyEntity.java b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/UserPolicyEntity.java index dd45b18..4f821bc 100644 --- a/src/main/java/org/gcube/common/authorizationservice/persistence/entities/UserPolicyEntity.java +++ b/src/main/java/org/gcube/common/authorizationservice/persistence/entities/UserPolicyEntity.java @@ -72,9 +72,8 @@ public class UserPolicyEntity extends PolicyEntity{ @Override public String toString() { - return "UserPolicyEntity [userClient=" + userClient + ", type=" + type - + ", excludes=" + excludes + ", identifier=" + identifier + "]"; + return "UserPolicyEntity [identifier=" + identifier + ", toString()=" + + super.toString() + "]"; } - } diff --git a/src/main/java/org/gcube/common/authorizationservice/util/TokenPersistence.java b/src/main/java/org/gcube/common/authorizationservice/util/TokenPersistence.java index 93d2f3c..6a4b884 100644 --- a/src/main/java/org/gcube/common/authorizationservice/util/TokenPersistence.java +++ b/src/main/java/org/gcube/common/authorizationservice/util/TokenPersistence.java @@ -30,4 +30,7 @@ public interface TokenPersistence { List getPolicesByTypeAndClientId(String context, PolicyType type, String clientId); + + Map getExistingExternalServices(String generatorId, + String context); } diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index aa54ee4..c8809e3 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -21,7 +21,7 @@ org.gcube.common.authorizationservice.persistence.entities.UserPolicyEntity + value="jdbc:postgresql://auth-db-dev-d4s.d4science.org/authorization" /> diff --git a/src/main/webapp/WEB-INF/AuthorizationConfiguration.xml b/src/main/webapp/WEB-INF/AuthorizationConfiguration.xml index d572f2e..0e31a43 100644 --- a/src/main/webapp/WEB-INF/AuthorizationConfiguration.xml +++ b/src/main/webapp/WEB-INF/AuthorizationConfiguration.xml @@ -1,20 +1,9 @@ - - - - - - - - - - - - - - - - + + + + + + - diff --git a/src/test/java/org/gcube/common/authz/GenerateTest.java b/src/test/java/org/gcube/common/authz/GenerateTest.java index c3b3378..7a86fad 100644 --- a/src/test/java/org/gcube/common/authz/GenerateTest.java +++ b/src/test/java/org/gcube/common/authz/GenerateTest.java @@ -6,6 +6,7 @@ import javax.ws.rs.client.Entity; import javax.ws.rs.core.Application; import org.gcube.common.authorization.library.provider.ContainerInfo; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.provider.ServiceIdentifier; import org.gcube.common.authorization.library.provider.ServiceInfo; import org.gcube.common.authorization.library.provider.UserInfo; @@ -34,6 +35,8 @@ public class GenerateTest extends JerseyTest{ return config; } + + @Test public void generateTokenForUser() { @@ -67,6 +70,7 @@ public class GenerateTest extends JerseyTest{ Assert.assertNotNull(token); } + @Test(expected=Exception.class) public void generateTokenForNodeERROR() { target("token").path("node") diff --git a/src/test/java/org/gcube/common/authz/configuration/Binder.java b/src/test/java/org/gcube/common/authz/configuration/Binder.java index 252552c..deb6d58 100644 --- a/src/test/java/org/gcube/common/authz/configuration/Binder.java +++ b/src/test/java/org/gcube/common/authz/configuration/Binder.java @@ -7,6 +7,7 @@ import java.io.StringWriter; import javax.xml.bind.JAXBContext; +import org.gcube.common.authorization.library.ClientType; import org.gcube.common.authorizationservice.configuration.AllowedEntity; import org.gcube.common.authorizationservice.configuration.AllowedEntity.EntityType; import org.gcube.common.authorizationservice.configuration.AuthorizationConfiguration; @@ -28,7 +29,7 @@ public class Binder { @Test public void binder() throws Exception{ - AuthorizationRule firtRule = new RuleBuilder().path("/*").entity(new AllowedEntity(EntityType.IP, "192.168.0.1")).entity(new AllowedEntity(EntityType.IP, "192.168.0.2")).build(); + AuthorizationRule firtRule = new RuleBuilder().path("/*").entity(new AllowedEntity(EntityType.IP, "192.168.0.1")).entity(new AllowedEntity(EntityType.IP, "192.168.0.2")).needsToken(ClientType.USER, ClientType.CONTAINER).build(); AuthorizationRule secondRule = new RuleBuilder().path("/newPath").entity(new AllowedEntity(EntityType.ROLE, "ContextManager")).entity(new AllowedEntity(EntityType.IP, "192.168.0.3")).build(); AuthorizationRule thirdRule = new RuleBuilder().path("/anotherPath").entity(new AllowedEntity(EntityType.USER, "user")).build();