Roberto Sánchez
2014-01-21 d7a35d13cd691e6821f774b624e4203a404e67d9
#396 feature - Added authorization management
1 files deleted
2 files added
8 files modified
1 files renamed
changed files
securis/src/main/java/net/curisit/securis/db/Application.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/Organization.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/User.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/security/BasicSecurityContext.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/security/Securable.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/security/SecurityInterceptor.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/BasicServices.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/OrganizationResource.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/UserResource.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/utils/CacheTTL.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/Application.java
....@@ -6,6 +6,7 @@
66
77 import javax.persistence.Column;
88 import javax.persistence.Entity;
9
+import javax.persistence.FetchType;
910 import javax.persistence.GeneratedValue;
1011 import javax.persistence.Id;
1112 import javax.persistence.NamedQueries;
....@@ -43,7 +44,7 @@
4344
4445 @JsonIgnore
4546 // We don't include the referenced entities to limit the size of each row at the listing
46
- @OneToMany(mappedBy = "application")
47
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "application")
4748 private Set<LicenseType> licenseTypes;
4849
4950 public int getId() {
securis/src/main/java/net/curisit/securis/db/Organization.java
....@@ -9,6 +9,7 @@
99 import javax.persistence.CascadeType;
1010 import javax.persistence.Column;
1111 import javax.persistence.Entity;
12
+import javax.persistence.FetchType;
1213 import javax.persistence.GeneratedValue;
1314 import javax.persistence.Id;
1415 import javax.persistence.JoinColumn;
....@@ -36,7 +37,8 @@
3637 @Entity
3738 @Table(name = "organization")
3839 @NamedQueries(
39
- { @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") })
40
+ { @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"),
41
+ @NamedQuery(name = "find-children-org", query = "SELECT o FROM Organization o where o.parentOrganization = :parentOrganization") })
4042 public class Organization implements Serializable {
4143
4244 @SuppressWarnings("unused")
....@@ -73,7 +75,7 @@
7375
7476 @JsonIgnore
7577 // We don't include the users to limit the size of each row a the listing
76
- @OneToMany(mappedBy = "parentOrganization")
78
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "parentOrganization")
7779 private Set<Organization> childOrganizations;
7880
7981 public int getId() {
securis/src/main/java/net/curisit/securis/db/User.java
....@@ -181,10 +181,10 @@
181181 }
182182
183183 @JsonProperty("organizations_ids")
184
- public List<Integer> getOrgsIds() {
184
+ public Set<Integer> getOrgsIds() {
185185 if (organizations == null)
186186 return null;
187
- List<Integer> ids = new ArrayList<>();
187
+ Set<Integer> ids = new HashSet<>();
188188 for (Organization org : organizations) {
189189 ids.add(org.getId());
190190 }
securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java
....@@ -1,5 +1,6 @@
11 package net.curisit.securis.ioc;
22
3
+import net.curisit.securis.security.SecurityInterceptor;
34 import net.curisit.securis.services.ApiResource;
45 import net.curisit.securis.services.ApplicationResource;
56 import net.curisit.securis.services.BasicServices;
....@@ -8,7 +9,6 @@
89 import net.curisit.securis.services.LicenseTypeResource;
910 import net.curisit.securis.services.OrganizationResource;
1011 import net.curisit.securis.services.PackResource;
11
-import net.curisit.securis.services.SecurityInterceptor;
1212 import net.curisit.securis.services.UserResource;
1313
1414 import org.eclipse.jetty.server.Authentication.User;
....@@ -24,10 +24,12 @@
2424 protected void configure() {
2525 super.configure();
2626 // TODO: Make the bind using reflection dynamically
27
+ bind(SecurityInterceptor.class);
28
+ // bind(SecurityContextWrapper.class).in(RequestScoped.class);
29
+
2730 bind(BasicServices.class);
2831 bind(LicenseServices.class);
2932 bind(UserResource.class);
30
- bind(SecurityInterceptor.class);
3133
3234 bind(ApplicationResource.class);
3335 bind(LicenseTypeResource.class);
securis/src/main/java/net/curisit/securis/security/BasicSecurityContext.java
....@@ -0,0 +1,92 @@
1
+package net.curisit.securis.security;
2
+
3
+import java.security.Principal;
4
+import java.util.Map;
5
+import java.util.Set;
6
+
7
+import javax.ws.rs.core.SecurityContext;
8
+
9
+import net.curisit.integrity.commons.Utils;
10
+import net.curisit.securis.db.User;
11
+
12
+public class BasicSecurityContext implements SecurityContext {
13
+
14
+ final public static String ROL_ADVANCE = "advance";
15
+ final public static String ROL_ADMIN = "admin";
16
+
17
+ final static Map<String, Integer> ROLES = Utils.<String, Integer> createMap(ROL_ADVANCE, User.Rol.ADVANCE, ROL_ADMIN, User.Rol.ADMIN);
18
+
19
+ Principal user = null;
20
+ int roles = 0;
21
+ boolean secure = false;
22
+ Set<Integer> organizationsIds = null;
23
+ double ran = 0;
24
+
25
+ public BasicSecurityContext(String username, int roles, boolean secure) {
26
+ user = new UserPrincipal(username);
27
+ this.roles = roles;
28
+ this.secure = secure;
29
+ ran = Math.random();
30
+ }
31
+
32
+ @Override
33
+ public Principal getUserPrincipal() {
34
+ return user;
35
+ }
36
+
37
+ @Override
38
+ public boolean isUserInRole(String role) {
39
+ Integer introle = ROLES.get(role);
40
+ return introle != null && (introle & roles) != 0;
41
+ }
42
+
43
+ @Override
44
+ public boolean isSecure() {
45
+ return secure;
46
+ }
47
+
48
+ @Override
49
+ public String getAuthenticationScheme() {
50
+ return null;
51
+ }
52
+
53
+ @Override
54
+ public String toString() {
55
+
56
+ return String.format("SecurityContextWrapper(%f) %s", ran, user);
57
+ }
58
+
59
+ public void setOrganizationsIds(Set<Integer> orgs) {
60
+ this.organizationsIds = orgs;
61
+ }
62
+
63
+ public Set<Integer> getOrganizationsIds() {
64
+ return this.organizationsIds;
65
+ }
66
+
67
+ private class UserPrincipal implements Principal {
68
+
69
+ final String name;
70
+
71
+ public UserPrincipal(String name) {
72
+ this.name = name;
73
+ }
74
+
75
+ @Override
76
+ public String getName() {
77
+ return this.name;
78
+ }
79
+
80
+ @Override
81
+ public String toString() {
82
+ return String.format("[%s]", name);
83
+ }
84
+
85
+ }
86
+
87
+ public boolean isOrgAccesible(Integer orgid) {
88
+ if (organizationsIds == null || orgid == null)
89
+ return false;
90
+ return organizationsIds.contains(orgid);
91
+ }
92
+}
securis/src/main/java/net/curisit/securis/services/Securable.java
similarity index 93%rename from securis/src/main/java/net/curisit/securis/services/Securable.javarename to securis/src/main/java/net/curisit/securis/security/Securable.java
....@@ -1,4 +1,4 @@
1
-package net.curisit.securis.services;
1
+package net.curisit.securis.security;
22
33 import java.lang.annotation.ElementType;
44 import java.lang.annotation.Retention;
securis/src/main/java/net/curisit/securis/security/SecurityInterceptor.java
....@@ -0,0 +1,144 @@
1
+package net.curisit.securis.security;
2
+
3
+import java.io.IOException;
4
+import java.lang.reflect.Method;
5
+import java.util.List;
6
+import java.util.Set;
7
+
8
+import javax.annotation.Priority;
9
+import javax.inject.Inject;
10
+import javax.persistence.EntityManager;
11
+import javax.servlet.http.HttpServletRequest;
12
+import javax.ws.rs.Priorities;
13
+import javax.ws.rs.WebApplicationException;
14
+import javax.ws.rs.container.ContainerRequestContext;
15
+import javax.ws.rs.core.Context;
16
+import javax.ws.rs.core.Response;
17
+import javax.ws.rs.core.Response.Status;
18
+import javax.ws.rs.ext.Provider;
19
+
20
+import net.curisit.securis.db.User;
21
+import net.curisit.securis.utils.CacheTTL;
22
+import net.curisit.securis.utils.TokenHelper;
23
+
24
+import org.jboss.resteasy.core.Dispatcher;
25
+import org.jboss.resteasy.core.ResourceMethodInvoker;
26
+import org.jboss.resteasy.core.ServerResponse;
27
+import org.jboss.resteasy.spi.Failure;
28
+import org.jboss.resteasy.spi.HttpRequest;
29
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
30
+import org.slf4j.Logger;
31
+import org.slf4j.LoggerFactory;
32
+
33
+//@Provider
34
+//@Priority(Priorities.AUTHENTICATION)
35
+//public class SecurityInterceptor implements javax.ws.rs.container.ContainerRequestFilter {
36
+
37
+@Provider
38
+// @ServerInterceptor
39
+// @Precedence("SECURITY")
40
+// public class SecurityInterceptor implements PreProcessInterceptor {
41
+// @PreMatching
42
+@Priority(Priorities.AUTHENTICATION)
43
+public class SecurityInterceptor implements javax.ws.rs.container.ContainerRequestFilter {
44
+ private static final Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);
45
+
46
+ @Inject
47
+ private TokenHelper tokenHelper;
48
+
49
+ @Context
50
+ private HttpServletRequest servletRequest;
51
+
52
+ @Inject
53
+ CacheTTL cache;
54
+
55
+ @Context
56
+ Dispatcher dispatcher;
57
+
58
+ @Inject
59
+ com.google.inject.Provider<EntityManager> emProvider;
60
+
61
+ public void filter(ContainerRequestContext containerRequestContext) throws IOException {
62
+ // log.info("scw {}, {}", scw, scw.getClass());
63
+ log.info("MACHED res: {}", containerRequestContext.getUriInfo().getMatchedResources());
64
+ // dispatcher.getDefaultContextObjects().remove(SecurityContextWrapper.class);
65
+ ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
66
+ Method method = methodInvoker.getMethod();
67
+
68
+ if (!method.isAnnotationPresent(Securable.class))
69
+ return;
70
+ String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM);
71
+ if (token == null || !tokenHelper.isTokenValid(token)) {
72
+ log.info("Access denied to '{}', Token not valid.", servletRequest.getPathInfo());
73
+ containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
74
+ } else {
75
+ Securable sec = method.getAnnotation(Securable.class);
76
+
77
+ // If roles == 0 we only need to validate the token
78
+ String username = tokenHelper.extractUserFromToken(token);
79
+ int userRoles = getUserRoles(username);
80
+ // if (sec.roles() != 0) {
81
+ // if ((sec.roles() & userRoles) == 0) {
82
+ // log.info("User {} has no necessary role to access url: {}", username, servletRequest.getPathInfo());
83
+ // containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
84
+ // }
85
+ // }
86
+ Set<Integer> orgs = getUserOrganizations(username);
87
+
88
+ BasicSecurityContext scw = new BasicSecurityContext(username, userRoles, servletRequest.isSecure());
89
+ scw.setOrganizationsIds(orgs);
90
+ containerRequestContext.setSecurityContext(scw);
91
+ // Next line provide injection in resource methods
92
+ log.info("TEST context {}", ResteasyProviderFactory.getContextData(BasicSecurityContext.class));
93
+ ResteasyProviderFactory.pushContext(BasicSecurityContext.class, scw);
94
+ // log.info("{}", dispatcher.getDefaultContextObjects());
95
+ // dispatcher.getDefaultContextObjects().put(SecurityContextWrapper.class, secContext);
96
+ log.info("Added custom SecurityContext for user {}", username);
97
+ }
98
+ }
99
+
100
+ private Set<Integer> getUserOrganizations(String username) {
101
+ @SuppressWarnings("unchecked")
102
+ Set<Integer> userOrgs = cache.get("orgs_" + username, Set.class);
103
+ if (userOrgs == null) {
104
+ // Theorically this shouldn't be never null, but just in case...
105
+ EntityManager em = emProvider.get();
106
+ User user = em.find(User.class, username);
107
+ if (user != null) {
108
+ userOrgs = user.getAllOrgsIds();
109
+ // We store user orgs in cache only for one hour
110
+ cache.set("orgs_" + username, userOrgs, 3600);
111
+ }
112
+ }
113
+
114
+ return userOrgs;
115
+ }
116
+
117
+ private int getUserRoles(String username) {
118
+ if (username == null)
119
+ return 0;
120
+ Integer userRoles = cache.get("roles_" + username, Integer.class);
121
+ if (userRoles == null) {
122
+ EntityManager em = emProvider.get();
123
+ User user = em.find(User.class, username);
124
+ if (user != null) {
125
+ userRoles = 0;
126
+ List<Integer> roles = user.getRoles();
127
+ for (Integer rol : roles) {
128
+ userRoles += rol;
129
+ }
130
+ // We store user roles in cache only for one hour
131
+ cache.set("roles_" + username, userRoles, 3600);
132
+ cache.set("orgs_" + username, user.getOrgsIds(), 3600);
133
+ }
134
+ }
135
+ return userRoles == null ? 0 : userRoles.intValue();
136
+ }
137
+
138
+ // @Override
139
+ public ServerResponse preProcess(HttpRequest request, ResourceMethodInvoker method) throws Failure, WebApplicationException {
140
+ // TODO Auto-generated method stub
141
+ return null;
142
+ }
143
+
144
+}
securis/src/main/java/net/curisit/securis/services/BasicServices.java
....@@ -21,6 +21,7 @@
2121 import javax.ws.rs.core.UriBuilder;
2222
2323 import net.curisit.integrity.commons.Utils;
24
+import net.curisit.securis.security.Securable;
2425 import net.curisit.securis.utils.TokenHelper;
2526
2627 import org.slf4j.Logger;
securis/src/main/java/net/curisit/securis/services/OrganizationResource.java
....@@ -4,6 +4,7 @@
44 import java.util.Date;
55 import java.util.List;
66
7
+import javax.annotation.security.RolesAllowed;
78 import javax.inject.Inject;
89 import javax.inject.Provider;
910 import javax.persistence.EntityManager;
....@@ -27,8 +28,11 @@
2728 import net.curisit.securis.SecurisErrorHandler;
2829 import net.curisit.securis.db.Organization;
2930 import net.curisit.securis.db.User;
31
+import net.curisit.securis.security.BasicSecurityContext;
32
+import net.curisit.securis.security.Securable;
3033 import net.curisit.securis.utils.TokenHelper;
3134
35
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
3236 import org.slf4j.Logger;
3337 import org.slf4j.LoggerFactory;
3438
....@@ -45,10 +49,7 @@
4549 private static final Logger log = LoggerFactory.getLogger(OrganizationResource.class);
4650
4751 @Inject
48
- TokenHelper tokenHelper;
49
-
50
- @Inject
51
- Provider<EntityManager> emProvider;
52
+ private Provider<EntityManager> emProvider;
5253
5354 public OrganizationResource() {
5455 }
....@@ -61,11 +62,30 @@
6162 @Path("/")
6263 @Produces(
6364 { MediaType.APPLICATION_JSON })
64
- public Response index() {
65
+ @Securable
66
+ // @RolesAllowed(SecurityContextWrapper.ROL_ADVANCE)
67
+ public Response index(@Context BasicSecurityContext bsc) {
6568 log.info("Getting organizations list ");
6669
70
+ // log.info("User orgs: {}", request.getAttribute("oser_orgs"));
71
+ BasicSecurityContext bsc2 = ResteasyProviderFactory.getContextData(BasicSecurityContext.class);
72
+ log.info("bsc: {}", bsc);
73
+ log.info("bsc2: {}", bsc2);
74
+ // log.info("securityContext: {}", scw);
75
+ log.info("securityContext ROL_ADMIN?: {}", bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN));
6776 EntityManager em = emProvider.get();
68
- TypedQuery<Organization> q = em.createNamedQuery("list-organizations", Organization.class);
77
+ TypedQuery<Organization> q;
78
+ if (bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
79
+ log.info("GEtting all orgs for user: " + bsc.getUserPrincipal());
80
+ q = em.createNamedQuery("list-organizations", Organization.class);
81
+ } else {
82
+ q = em.createNamedQuery("list-organizations", Organization.class);
83
+ // if (securityContext.getOrganizationsIds() == null)
84
+ // Response.ok().build();
85
+ // log.info("Getting only {} orgs for user: {}", securityContext.getOrganizationsIds(), securityContext.getUserPrincipal());
86
+ // q = em.createNamedQuery("list-organizations-by-ids", Organization.class);
87
+ // q.setParameter("list_ids", securityContext.getOrganizationsIds());
88
+ }
6989
7090 List<Organization> list = q.getResultList();
7191
....@@ -80,12 +100,17 @@
80100 @Path("/{orgid}")
81101 @Produces(
82102 { MediaType.APPLICATION_JSON })
103
+ @Securable
83104 public Response get(@PathParam("orgid") String orgid, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
84105 log.info("Getting organization data for id: {}: ", orgid);
85106 if (orgid == null || orgid.equals("")) {
86107 log.error("Organization ID is mandatory");
87108 return Response.status(Status.NOT_FOUND).build();
88109 }
110
+ // if (!securityContext.isOrgAccesible(Integer.parseInt(orgid))) {
111
+ // log.error("Organization with id {} not accessible for user: {}", orgid, securityContext.getUserPrincipal());
112
+ // return Response.status(Status.UNAUTHORIZED).build();
113
+ // }
89114
90115 EntityManager em = emProvider.get();
91116 Organization lt = em.find(Organization.class, Integer.parseInt(orgid));
....@@ -111,6 +136,8 @@
111136 @Produces(
112137 { MediaType.APPLICATION_JSON })
113138 @Transactional
139
+ @Securable
140
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
114141 public Response create(Organization org, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
115142 log.info("Creating new organization");
116143 EntityManager em = emProvider.get();
....@@ -151,6 +178,8 @@
151178 @Consumes(MediaType.APPLICATION_JSON)
152179 @Produces(
153180 { MediaType.APPLICATION_JSON })
181
+ @Securable
182
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
154183 public Response modify(Organization org, @PathParam("orgid") String orgid, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
155184 log.info("Modifying organization with id: {}", orgid);
156185 EntityManager em = emProvider.get();
....@@ -201,6 +230,8 @@
201230 @Transactional
202231 @Produces(
203232 { MediaType.APPLICATION_JSON })
233
+ @Securable
234
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
204235 public Response delete(@PathParam("orgid") String orgid, @Context HttpServletRequest request) {
205236 log.info("Deleting organization with id: {}", orgid);
206237 EntityManager em = emProvider.get();
securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java
deleted file mode 100644
....@@ -1,108 +0,0 @@
1
-package net.curisit.securis.services;
2
-
3
-import java.io.IOException;
4
-import java.lang.reflect.Method;
5
-import java.util.List;
6
-import java.util.Set;
7
-
8
-import javax.inject.Inject;
9
-import javax.persistence.EntityManager;
10
-import javax.servlet.http.HttpServletRequest;
11
-import javax.ws.rs.container.ContainerRequestContext;
12
-import javax.ws.rs.core.Context;
13
-import javax.ws.rs.core.Response;
14
-import javax.ws.rs.core.Response.Status;
15
-import javax.ws.rs.ext.Provider;
16
-
17
-import net.curisit.securis.db.User;
18
-import net.curisit.securis.utils.CacheTTL;
19
-import net.curisit.securis.utils.TokenHelper;
20
-
21
-import org.jboss.resteasy.core.ResourceMethodInvoker;
22
-import org.slf4j.Logger;
23
-import org.slf4j.LoggerFactory;
24
-
25
-@Provider
26
-public class SecurityInterceptor implements javax.ws.rs.container.ContainerRequestFilter {
27
-
28
- private static final Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);
29
-
30
- @Inject
31
- private TokenHelper tokenHelper;
32
-
33
- @Context
34
- private HttpServletRequest servletRequest;
35
-
36
- @Inject
37
- CacheTTL cache;
38
-
39
- @Inject
40
- com.google.inject.Provider<EntityManager> emProvider;
41
-
42
- @Override
43
- public void filter(ContainerRequestContext containerRequestContext) throws IOException {
44
- ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
45
- Method method = methodInvoker.getMethod();
46
-
47
- if (!method.isAnnotationPresent(Securable.class))
48
- return;
49
- String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM);
50
- if (token == null || !tokenHelper.isTokenValid(token)) {
51
- log.info("Access denied to '{}', Token not valid.", servletRequest.getPathInfo());
52
- containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
53
- } else {
54
- Securable sec = method.getAnnotation(Securable.class);
55
-
56
- // If roles == 0 we only need to validate the token
57
- if (sec.roles() != 0) {
58
- String username = tokenHelper.extractUserFromToken(token);
59
- int userRoles = getUserRoles(username);
60
- if ((sec.roles() & userRoles) == 0) {
61
- log.info("User {} has no necessary role to access url: {}", username, servletRequest.getPathInfo());
62
- containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
63
- }
64
- Set<Integer> orgs = getUserOrganizations(username);
65
- servletRequest.setAttribute("user_orgs", orgs);
66
- }
67
- }
68
- }
69
-
70
- private Set<Integer> getUserOrganizations(String username) {
71
- @SuppressWarnings("unchecked")
72
- Set<Integer> userOrgs = cache.get("orgs_" + username, Set.class);
73
- if (userOrgs == null) {
74
- // Theorically this shouldn't be never null, but just in case...
75
- EntityManager em = emProvider.get();
76
- User user = em.find(User.class, username);
77
- if (user != null) {
78
- userOrgs = user.getAllOrgsIds();
79
- // We store user orgs in cache only for one hour
80
- cache.set("orgs_" + username, userOrgs, 3600);
81
- }
82
- }
83
-
84
- return userOrgs;
85
- }
86
-
87
- private int getUserRoles(String username) {
88
- if (username == null)
89
- return 0;
90
- Integer userRoles = cache.get("roles_" + username, Integer.class);
91
- if (userRoles == null) {
92
- EntityManager em = emProvider.get();
93
- User user = em.find(User.class, username);
94
- if (user != null) {
95
- userRoles = 0;
96
- List<Integer> roles = user.getRoles();
97
- for (Integer rol : roles) {
98
- userRoles += rol;
99
- }
100
- // We store user roles in cache only for one hour
101
- cache.set("roles_" + username, userRoles, 3600);
102
- cache.set("orgs_" + username, user.getOrgsIds(), 3600);
103
- }
104
- }
105
- return userRoles == null ? 0 : userRoles.intValue();
106
- }
107
-
108
-}
securis/src/main/java/net/curisit/securis/services/UserResource.java
....@@ -115,7 +115,7 @@
115115 }
116116
117117 Set<Organization> orgs = null;
118
- List<Integer> orgsIds = user.getOrgsIds();
118
+ Set<Integer> orgsIds = user.getOrgsIds();
119119 if (orgsIds != null && orgsIds.size() > 0) {
120120 orgs = new HashSet<>();
121121 for (Integer orgId : orgsIds) {
....@@ -154,7 +154,7 @@
154154 }
155155
156156 Set<Organization> orgs = null;
157
- List<Integer> orgsIds = user.getOrgsIds();
157
+ Set<Integer> orgsIds = user.getOrgsIds();
158158 if (orgsIds != null && orgsIds.size() > 0) {
159159 orgs = new HashSet<>();
160160 for (Integer orgId : orgsIds) {
securis/src/main/java/net/curisit/securis/utils/CacheTTL.java
....@@ -1,7 +1,9 @@
11 package net.curisit.securis.utils;
22
3
+import java.util.ArrayList;
34 import java.util.Date;
4
-import java.util.Hashtable;
5
+import java.util.HashMap;
6
+import java.util.List;
57 import java.util.Map;
68
79 import javax.inject.Inject;
....@@ -25,7 +27,7 @@
2527 */
2628 private static int DEFAULT_CACHE_DURATION = 24 * 60 * 60;
2729
28
- private Map<String, CachedObject> data = new Hashtable<>();
30
+ private Map<String, CachedObject> data = new HashMap<>();
2931
3032 private Thread cleaningThread = null;
3133
....@@ -46,12 +48,17 @@
4648 }
4749 // log.info("Cheking expired objects " + new Date());
4850 Date now = new Date();
51
+ List<String> keysToRemove = new ArrayList<>();
4952 for (String key : CacheTTL.this.data.keySet()) {
5053 CachedObject co = CacheTTL.this.data.get(key);
5154 if (now.after(co.getExpireAt())) {
52
- CacheTTL.this.data.remove(key);
55
+ keysToRemove.add(key);
5356 }
5457 }
58
+ for (String key : keysToRemove) {
59
+ // If we try to remove directly in the previous loop an exception is thrown java.util.ConcurrentModificationException
60
+ CacheTTL.this.data.remove(key);
61
+ }
5562 }
5663 }
5764 });