From d7a35d13cd691e6821f774b624e4203a404e67d9 Mon Sep 17 00:00:00 2001
From: Roberto Sánchez <roberto.sanchez@curisit.net>
Date: Tue, 21 Jan 2014 10:16:13 +0000
Subject: [PATCH] #396 feature - Added authorization management
---
/dev/null | 108 -------------
securis/src/main/java/net/curisit/securis/db/User.java | 4
securis/src/main/java/net/curisit/securis/db/Application.java | 3
securis/src/main/java/net/curisit/securis/db/Organization.java | 6
securis/src/main/java/net/curisit/securis/services/UserResource.java | 4
securis/src/main/java/net/curisit/securis/security/Securable.java | 2
securis/src/main/java/net/curisit/securis/utils/CacheTTL.java | 13 +
securis/src/main/java/net/curisit/securis/security/BasicSecurityContext.java | 92 +++++++++++
securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java | 6
securis/src/main/java/net/curisit/securis/services/BasicServices.java | 1
securis/src/main/java/net/curisit/securis/services/OrganizationResource.java | 43 ++++
securis/src/main/java/net/curisit/securis/security/SecurityInterceptor.java | 144 ++++++++++++++++++
12 files changed, 299 insertions(+), 127 deletions(-)
diff --git a/securis/src/main/java/net/curisit/securis/db/Application.java b/securis/src/main/java/net/curisit/securis/db/Application.java
index eb26cde..2273e91 100644
--- a/securis/src/main/java/net/curisit/securis/db/Application.java
+++ b/securis/src/main/java/net/curisit/securis/db/Application.java
@@ -6,6 +6,7 @@
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
@@ -43,7 +44,7 @@
@JsonIgnore
// We don't include the referenced entities to limit the size of each row at the listing
- @OneToMany(mappedBy = "application")
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "application")
private Set<LicenseType> licenseTypes;
public int getId() {
diff --git a/securis/src/main/java/net/curisit/securis/db/Organization.java b/securis/src/main/java/net/curisit/securis/db/Organization.java
index 57e536a..a2fe5fa 100644
--- a/securis/src/main/java/net/curisit/securis/db/Organization.java
+++ b/securis/src/main/java/net/curisit/securis/db/Organization.java
@@ -9,6 +9,7 @@
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
@@ -36,7 +37,8 @@
@Entity
@Table(name = "organization")
@NamedQueries(
- { @NamedQuery(name = "list-organizations", query = "SELECT o FROM Organization o"), @NamedQuery(name = "find-children-org", query = "SELECT o FROM Organization o where o.parentOrganization = :parentOrganization") })
+ { @NamedQuery(name = "list-organizations", query = "SELECT o FROM Organization o"), @NamedQuery(name = "list-organizations-by-ids", query = "SELECT o FROM Organization o where id in :list_ids"),
+ @NamedQuery(name = "find-children-org", query = "SELECT o FROM Organization o where o.parentOrganization = :parentOrganization") })
public class Organization implements Serializable {
@SuppressWarnings("unused")
@@ -73,7 +75,7 @@
@JsonIgnore
// We don't include the users to limit the size of each row a the listing
- @OneToMany(mappedBy = "parentOrganization")
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "parentOrganization")
private Set<Organization> childOrganizations;
public int getId() {
diff --git a/securis/src/main/java/net/curisit/securis/db/User.java b/securis/src/main/java/net/curisit/securis/db/User.java
index 7f57cf8..79d2aa2 100644
--- a/securis/src/main/java/net/curisit/securis/db/User.java
+++ b/securis/src/main/java/net/curisit/securis/db/User.java
@@ -181,10 +181,10 @@
}
@JsonProperty("organizations_ids")
- public List<Integer> getOrgsIds() {
+ public Set<Integer> getOrgsIds() {
if (organizations == null)
return null;
- List<Integer> ids = new ArrayList<>();
+ Set<Integer> ids = new HashSet<>();
for (Organization org : organizations) {
ids.add(org.getId());
}
diff --git a/securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java b/securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java
index 4059219..7de70d9 100644
--- a/securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java
+++ b/securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java
@@ -1,5 +1,6 @@
package net.curisit.securis.ioc;
+import net.curisit.securis.security.SecurityInterceptor;
import net.curisit.securis.services.ApiResource;
import net.curisit.securis.services.ApplicationResource;
import net.curisit.securis.services.BasicServices;
@@ -8,7 +9,6 @@
import net.curisit.securis.services.LicenseTypeResource;
import net.curisit.securis.services.OrganizationResource;
import net.curisit.securis.services.PackResource;
-import net.curisit.securis.services.SecurityInterceptor;
import net.curisit.securis.services.UserResource;
import org.eclipse.jetty.server.Authentication.User;
@@ -24,10 +24,12 @@
protected void configure() {
super.configure();
// TODO: Make the bind using reflection dynamically
+ bind(SecurityInterceptor.class);
+ // bind(SecurityContextWrapper.class).in(RequestScoped.class);
+
bind(BasicServices.class);
bind(LicenseServices.class);
bind(UserResource.class);
- bind(SecurityInterceptor.class);
bind(ApplicationResource.class);
bind(LicenseTypeResource.class);
diff --git a/securis/src/main/java/net/curisit/securis/security/BasicSecurityContext.java b/securis/src/main/java/net/curisit/securis/security/BasicSecurityContext.java
new file mode 100644
index 0000000..73ef3b2
--- /dev/null
+++ b/securis/src/main/java/net/curisit/securis/security/BasicSecurityContext.java
@@ -0,0 +1,92 @@
+package net.curisit.securis.security;
+
+import java.security.Principal;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.SecurityContext;
+
+import net.curisit.integrity.commons.Utils;
+import net.curisit.securis.db.User;
+
+public class BasicSecurityContext implements SecurityContext {
+
+ final public static String ROL_ADVANCE = "advance";
+ final public static String ROL_ADMIN = "admin";
+
+ final static Map<String, Integer> ROLES = Utils.<String, Integer> createMap(ROL_ADVANCE, User.Rol.ADVANCE, ROL_ADMIN, User.Rol.ADMIN);
+
+ Principal user = null;
+ int roles = 0;
+ boolean secure = false;
+ Set<Integer> organizationsIds = null;
+ double ran = 0;
+
+ public BasicSecurityContext(String username, int roles, boolean secure) {
+ user = new UserPrincipal(username);
+ this.roles = roles;
+ this.secure = secure;
+ ran = Math.random();
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return user;
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ Integer introle = ROLES.get(role);
+ return introle != null && (introle & roles) != 0;
+ }
+
+ @Override
+ public boolean isSecure() {
+ return secure;
+ }
+
+ @Override
+ public String getAuthenticationScheme() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+
+ return String.format("SecurityContextWrapper(%f) %s", ran, user);
+ }
+
+ public void setOrganizationsIds(Set<Integer> orgs) {
+ this.organizationsIds = orgs;
+ }
+
+ public Set<Integer> getOrganizationsIds() {
+ return this.organizationsIds;
+ }
+
+ private class UserPrincipal implements Principal {
+
+ final String name;
+
+ public UserPrincipal(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("[%s]", name);
+ }
+
+ }
+
+ public boolean isOrgAccesible(Integer orgid) {
+ if (organizationsIds == null || orgid == null)
+ return false;
+ return organizationsIds.contains(orgid);
+ }
+}
diff --git a/securis/src/main/java/net/curisit/securis/services/Securable.java b/securis/src/main/java/net/curisit/securis/security/Securable.java
similarity index 93%
rename from securis/src/main/java/net/curisit/securis/services/Securable.java
rename to securis/src/main/java/net/curisit/securis/security/Securable.java
index 6fcb8e3..79389e0 100644
--- a/securis/src/main/java/net/curisit/securis/services/Securable.java
+++ b/securis/src/main/java/net/curisit/securis/security/Securable.java
@@ -1,4 +1,4 @@
-package net.curisit.securis.services;
+package net.curisit.securis.security;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/securis/src/main/java/net/curisit/securis/security/SecurityInterceptor.java b/securis/src/main/java/net/curisit/securis/security/SecurityInterceptor.java
new file mode 100644
index 0000000..768dde2
--- /dev/null
+++ b/securis/src/main/java/net/curisit/securis/security/SecurityInterceptor.java
@@ -0,0 +1,144 @@
+package net.curisit.securis.security;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Priority;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.Provider;
+
+import net.curisit.securis.db.User;
+import net.curisit.securis.utils.CacheTTL;
+import net.curisit.securis.utils.TokenHelper;
+
+import org.jboss.resteasy.core.Dispatcher;
+import org.jboss.resteasy.core.ResourceMethodInvoker;
+import org.jboss.resteasy.core.ServerResponse;
+import org.jboss.resteasy.spi.Failure;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+//@Provider
+//@Priority(Priorities.AUTHENTICATION)
+//public class SecurityInterceptor implements javax.ws.rs.container.ContainerRequestFilter {
+
+@Provider
+// @ServerInterceptor
+// @Precedence("SECURITY")
+// public class SecurityInterceptor implements PreProcessInterceptor {
+// @PreMatching
+@Priority(Priorities.AUTHENTICATION)
+public class SecurityInterceptor implements javax.ws.rs.container.ContainerRequestFilter {
+ private static final Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);
+
+ @Inject
+ private TokenHelper tokenHelper;
+
+ @Context
+ private HttpServletRequest servletRequest;
+
+ @Inject
+ CacheTTL cache;
+
+ @Context
+ Dispatcher dispatcher;
+
+ @Inject
+ com.google.inject.Provider<EntityManager> emProvider;
+
+ public void filter(ContainerRequestContext containerRequestContext) throws IOException {
+ // log.info("scw {}, {}", scw, scw.getClass());
+ log.info("MACHED res: {}", containerRequestContext.getUriInfo().getMatchedResources());
+ // dispatcher.getDefaultContextObjects().remove(SecurityContextWrapper.class);
+ ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
+ Method method = methodInvoker.getMethod();
+
+ if (!method.isAnnotationPresent(Securable.class))
+ return;
+ String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM);
+ if (token == null || !tokenHelper.isTokenValid(token)) {
+ log.info("Access denied to '{}', Token not valid.", servletRequest.getPathInfo());
+ containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
+ } else {
+ Securable sec = method.getAnnotation(Securable.class);
+
+ // If roles == 0 we only need to validate the token
+ String username = tokenHelper.extractUserFromToken(token);
+ int userRoles = getUserRoles(username);
+ // if (sec.roles() != 0) {
+ // if ((sec.roles() & userRoles) == 0) {
+ // log.info("User {} has no necessary role to access url: {}", username, servletRequest.getPathInfo());
+ // containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
+ // }
+ // }
+ Set<Integer> orgs = getUserOrganizations(username);
+
+ BasicSecurityContext scw = new BasicSecurityContext(username, userRoles, servletRequest.isSecure());
+ scw.setOrganizationsIds(orgs);
+ containerRequestContext.setSecurityContext(scw);
+ // Next line provide injection in resource methods
+ log.info("TEST context {}", ResteasyProviderFactory.getContextData(BasicSecurityContext.class));
+ ResteasyProviderFactory.pushContext(BasicSecurityContext.class, scw);
+ // log.info("{}", dispatcher.getDefaultContextObjects());
+ // dispatcher.getDefaultContextObjects().put(SecurityContextWrapper.class, secContext);
+ log.info("Added custom SecurityContext for user {}", username);
+ }
+ }
+
+ private Set<Integer> getUserOrganizations(String username) {
+ @SuppressWarnings("unchecked")
+ Set<Integer> userOrgs = cache.get("orgs_" + username, Set.class);
+ if (userOrgs == null) {
+ // Theorically this shouldn't be never null, but just in case...
+ EntityManager em = emProvider.get();
+ User user = em.find(User.class, username);
+ if (user != null) {
+ userOrgs = user.getAllOrgsIds();
+ // We store user orgs in cache only for one hour
+ cache.set("orgs_" + username, userOrgs, 3600);
+ }
+ }
+
+ return userOrgs;
+ }
+
+ private int getUserRoles(String username) {
+ if (username == null)
+ return 0;
+ Integer userRoles = cache.get("roles_" + username, Integer.class);
+ if (userRoles == null) {
+ EntityManager em = emProvider.get();
+ User user = em.find(User.class, username);
+ if (user != null) {
+ userRoles = 0;
+ List<Integer> roles = user.getRoles();
+ for (Integer rol : roles) {
+ userRoles += rol;
+ }
+ // We store user roles in cache only for one hour
+ cache.set("roles_" + username, userRoles, 3600);
+ cache.set("orgs_" + username, user.getOrgsIds(), 3600);
+ }
+ }
+ return userRoles == null ? 0 : userRoles.intValue();
+ }
+
+ // @Override
+ public ServerResponse preProcess(HttpRequest request, ResourceMethodInvoker method) throws Failure, WebApplicationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/securis/src/main/java/net/curisit/securis/services/BasicServices.java b/securis/src/main/java/net/curisit/securis/services/BasicServices.java
index e1a7a77..efa8907 100644
--- a/securis/src/main/java/net/curisit/securis/services/BasicServices.java
+++ b/securis/src/main/java/net/curisit/securis/services/BasicServices.java
@@ -21,6 +21,7 @@
import javax.ws.rs.core.UriBuilder;
import net.curisit.integrity.commons.Utils;
+import net.curisit.securis.security.Securable;
import net.curisit.securis.utils.TokenHelper;
import org.slf4j.Logger;
diff --git a/securis/src/main/java/net/curisit/securis/services/OrganizationResource.java b/securis/src/main/java/net/curisit/securis/services/OrganizationResource.java
index 71b5441..e13bd7b 100644
--- a/securis/src/main/java/net/curisit/securis/services/OrganizationResource.java
+++ b/securis/src/main/java/net/curisit/securis/services/OrganizationResource.java
@@ -4,6 +4,7 @@
import java.util.Date;
import java.util.List;
+import javax.annotation.security.RolesAllowed;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.persistence.EntityManager;
@@ -27,8 +28,11 @@
import net.curisit.securis.SecurisErrorHandler;
import net.curisit.securis.db.Organization;
import net.curisit.securis.db.User;
+import net.curisit.securis.security.BasicSecurityContext;
+import net.curisit.securis.security.Securable;
import net.curisit.securis.utils.TokenHelper;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,10 +49,7 @@
private static final Logger log = LoggerFactory.getLogger(OrganizationResource.class);
@Inject
- TokenHelper tokenHelper;
-
- @Inject
- Provider<EntityManager> emProvider;
+ private Provider<EntityManager> emProvider;
public OrganizationResource() {
}
@@ -61,11 +62,30 @@
@Path("/")
@Produces(
{ MediaType.APPLICATION_JSON })
- public Response index() {
+ @Securable
+ // @RolesAllowed(SecurityContextWrapper.ROL_ADVANCE)
+ public Response index(@Context BasicSecurityContext bsc) {
log.info("Getting organizations list ");
+ // log.info("User orgs: {}", request.getAttribute("oser_orgs"));
+ BasicSecurityContext bsc2 = ResteasyProviderFactory.getContextData(BasicSecurityContext.class);
+ log.info("bsc: {}", bsc);
+ log.info("bsc2: {}", bsc2);
+ // log.info("securityContext: {}", scw);
+ log.info("securityContext ROL_ADMIN?: {}", bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN));
EntityManager em = emProvider.get();
- TypedQuery<Organization> q = em.createNamedQuery("list-organizations", Organization.class);
+ TypedQuery<Organization> q;
+ if (bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
+ log.info("GEtting all orgs for user: " + bsc.getUserPrincipal());
+ q = em.createNamedQuery("list-organizations", Organization.class);
+ } else {
+ q = em.createNamedQuery("list-organizations", Organization.class);
+ // if (securityContext.getOrganizationsIds() == null)
+ // Response.ok().build();
+ // log.info("Getting only {} orgs for user: {}", securityContext.getOrganizationsIds(), securityContext.getUserPrincipal());
+ // q = em.createNamedQuery("list-organizations-by-ids", Organization.class);
+ // q.setParameter("list_ids", securityContext.getOrganizationsIds());
+ }
List<Organization> list = q.getResultList();
@@ -80,12 +100,17 @@
@Path("/{orgid}")
@Produces(
{ MediaType.APPLICATION_JSON })
+ @Securable
public Response get(@PathParam("orgid") String orgid, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
log.info("Getting organization data for id: {}: ", orgid);
if (orgid == null || orgid.equals("")) {
log.error("Organization ID is mandatory");
return Response.status(Status.NOT_FOUND).build();
}
+ // if (!securityContext.isOrgAccesible(Integer.parseInt(orgid))) {
+ // log.error("Organization with id {} not accessible for user: {}", orgid, securityContext.getUserPrincipal());
+ // return Response.status(Status.UNAUTHORIZED).build();
+ // }
EntityManager em = emProvider.get();
Organization lt = em.find(Organization.class, Integer.parseInt(orgid));
@@ -111,6 +136,8 @@
@Produces(
{ MediaType.APPLICATION_JSON })
@Transactional
+ @Securable
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
public Response create(Organization org, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
log.info("Creating new organization");
EntityManager em = emProvider.get();
@@ -151,6 +178,8 @@
@Consumes(MediaType.APPLICATION_JSON)
@Produces(
{ MediaType.APPLICATION_JSON })
+ @Securable
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
public Response modify(Organization org, @PathParam("orgid") String orgid, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
log.info("Modifying organization with id: {}", orgid);
EntityManager em = emProvider.get();
@@ -201,6 +230,8 @@
@Transactional
@Produces(
{ MediaType.APPLICATION_JSON })
+ @Securable
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
public Response delete(@PathParam("orgid") String orgid, @Context HttpServletRequest request) {
log.info("Deleting organization with id: {}", orgid);
EntityManager em = emProvider.get();
diff --git a/securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java b/securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java
deleted file mode 100644
index 08c4e2e..0000000
--- a/securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package net.curisit.securis.services;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.persistence.EntityManager;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.ext.Provider;
-
-import net.curisit.securis.db.User;
-import net.curisit.securis.utils.CacheTTL;
-import net.curisit.securis.utils.TokenHelper;
-
-import org.jboss.resteasy.core.ResourceMethodInvoker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Provider
-public class SecurityInterceptor implements javax.ws.rs.container.ContainerRequestFilter {
-
- private static final Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);
-
- @Inject
- private TokenHelper tokenHelper;
-
- @Context
- private HttpServletRequest servletRequest;
-
- @Inject
- CacheTTL cache;
-
- @Inject
- com.google.inject.Provider<EntityManager> emProvider;
-
- @Override
- public void filter(ContainerRequestContext containerRequestContext) throws IOException {
- ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
- Method method = methodInvoker.getMethod();
-
- if (!method.isAnnotationPresent(Securable.class))
- return;
- String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM);
- if (token == null || !tokenHelper.isTokenValid(token)) {
- log.info("Access denied to '{}', Token not valid.", servletRequest.getPathInfo());
- containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
- } else {
- Securable sec = method.getAnnotation(Securable.class);
-
- // If roles == 0 we only need to validate the token
- if (sec.roles() != 0) {
- String username = tokenHelper.extractUserFromToken(token);
- int userRoles = getUserRoles(username);
- if ((sec.roles() & userRoles) == 0) {
- log.info("User {} has no necessary role to access url: {}", username, servletRequest.getPathInfo());
- containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
- }
- Set<Integer> orgs = getUserOrganizations(username);
- servletRequest.setAttribute("user_orgs", orgs);
- }
- }
- }
-
- private Set<Integer> getUserOrganizations(String username) {
- @SuppressWarnings("unchecked")
- Set<Integer> userOrgs = cache.get("orgs_" + username, Set.class);
- if (userOrgs == null) {
- // Theorically this shouldn't be never null, but just in case...
- EntityManager em = emProvider.get();
- User user = em.find(User.class, username);
- if (user != null) {
- userOrgs = user.getAllOrgsIds();
- // We store user orgs in cache only for one hour
- cache.set("orgs_" + username, userOrgs, 3600);
- }
- }
-
- return userOrgs;
- }
-
- private int getUserRoles(String username) {
- if (username == null)
- return 0;
- Integer userRoles = cache.get("roles_" + username, Integer.class);
- if (userRoles == null) {
- EntityManager em = emProvider.get();
- User user = em.find(User.class, username);
- if (user != null) {
- userRoles = 0;
- List<Integer> roles = user.getRoles();
- for (Integer rol : roles) {
- userRoles += rol;
- }
- // We store user roles in cache only for one hour
- cache.set("roles_" + username, userRoles, 3600);
- cache.set("orgs_" + username, user.getOrgsIds(), 3600);
- }
- }
- return userRoles == null ? 0 : userRoles.intValue();
- }
-
-}
diff --git a/securis/src/main/java/net/curisit/securis/services/UserResource.java b/securis/src/main/java/net/curisit/securis/services/UserResource.java
index 014ce20..f6b4560 100644
--- a/securis/src/main/java/net/curisit/securis/services/UserResource.java
+++ b/securis/src/main/java/net/curisit/securis/services/UserResource.java
@@ -115,7 +115,7 @@
}
Set<Organization> orgs = null;
- List<Integer> orgsIds = user.getOrgsIds();
+ Set<Integer> orgsIds = user.getOrgsIds();
if (orgsIds != null && orgsIds.size() > 0) {
orgs = new HashSet<>();
for (Integer orgId : orgsIds) {
@@ -154,7 +154,7 @@
}
Set<Organization> orgs = null;
- List<Integer> orgsIds = user.getOrgsIds();
+ Set<Integer> orgsIds = user.getOrgsIds();
if (orgsIds != null && orgsIds.size() > 0) {
orgs = new HashSet<>();
for (Integer orgId : orgsIds) {
diff --git a/securis/src/main/java/net/curisit/securis/utils/CacheTTL.java b/securis/src/main/java/net/curisit/securis/utils/CacheTTL.java
index 51a59e4..6561517 100644
--- a/securis/src/main/java/net/curisit/securis/utils/CacheTTL.java
+++ b/securis/src/main/java/net/curisit/securis/utils/CacheTTL.java
@@ -1,7 +1,9 @@
package net.curisit.securis.utils;
+import java.util.ArrayList;
import java.util.Date;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.inject.Inject;
@@ -25,7 +27,7 @@
*/
private static int DEFAULT_CACHE_DURATION = 24 * 60 * 60;
- private Map<String, CachedObject> data = new Hashtable<>();
+ private Map<String, CachedObject> data = new HashMap<>();
private Thread cleaningThread = null;
@@ -46,12 +48,17 @@
}
// log.info("Cheking expired objects " + new Date());
Date now = new Date();
+ List<String> keysToRemove = new ArrayList<>();
for (String key : CacheTTL.this.data.keySet()) {
CachedObject co = CacheTTL.this.data.get(key);
if (now.after(co.getExpireAt())) {
- CacheTTL.this.data.remove(key);
+ keysToRemove.add(key);
}
}
+ for (String key : keysToRemove) {
+ // If we try to remove directly in the previous loop an exception is thrown java.util.ConcurrentModificationException
+ CacheTTL.this.data.remove(key);
+ }
}
}
});
--
Gitblit v1.3.2