rsanchez
2017-04-10 8d99c88af55041ff06e6b9372b6b1f66220bed38
securis/src/main/java/net/curisit/securis/ioc/RequestsInterceptor.java
....@@ -21,12 +21,6 @@
2121 import javax.ws.rs.ext.WriterInterceptor;
2222 import javax.ws.rs.ext.WriterInterceptorContext;
2323
24
-import net.curisit.securis.db.User;
25
-import net.curisit.securis.security.BasicSecurityContext;
26
-import net.curisit.securis.security.Securable;
27
-import net.curisit.securis.utils.CacheTTL;
28
-import net.curisit.securis.utils.TokenHelper;
29
-
3024 import org.apache.logging.log4j.LogManager;
3125 import org.apache.logging.log4j.Logger;
3226 import org.jboss.resteasy.core.Dispatcher;
....@@ -36,158 +30,188 @@
3630 import org.jboss.resteasy.spi.HttpRequest;
3731 import org.jboss.resteasy.spi.ResteasyProviderFactory;
3832
33
+import net.curisit.securis.db.User;
34
+import net.curisit.securis.security.BasicSecurityContext;
35
+import net.curisit.securis.security.Securable;
36
+import net.curisit.securis.utils.CacheTTL;
37
+import net.curisit.securis.utils.TokenHelper;
38
+
3939 @Provider
4040 @Priority(Priorities.AUTHENTICATION)
4141 public class RequestsInterceptor implements ContainerRequestFilter, WriterInterceptor {
42
- private static final Logger LOG = LogManager.getLogger(RequestsInterceptor.class);
42
+ private static final Logger LOG = LogManager.getLogger(RequestsInterceptor.class);
4343
44
- @Context
45
- private HttpServletResponse servletResponse;
44
+ @Context
45
+ private HttpServletResponse servletResponse;
4646
47
- @Context
48
- private HttpServletRequest servletRequest;
47
+ @Context
48
+ private HttpServletRequest servletRequest;
4949
50
- @Inject
51
- private CacheTTL cache;
50
+ @Inject
51
+ private CacheTTL cache;
5252
53
- @Inject
54
- private TokenHelper tokenHelper;
53
+ @Inject
54
+ private TokenHelper tokenHelper;
5555
56
- @Context
57
- private Dispatcher dispatcher;
56
+ @Context
57
+ private Dispatcher dispatcher;
5858
59
- @Inject
60
- private EntityManagerProvider emProvider;
59
+ @Inject
60
+ private EntityManagerProvider emProvider;
6161
62
- @Override
63
- public void filter(ContainerRequestContext containerRequestContext) throws IOException {
64
- EntityManager em = emProvider.getEntityManager();
65
- LOG.debug("GETTING EM: {}", em);
62
+ @Override
63
+ public void filter(ContainerRequestContext containerRequestContext) throws IOException {
64
+ EntityManager em = emProvider.getEntityManager();
65
+ LOG.debug("GETTING EM: {}", em);
6666
67
- ResteasyProviderFactory.pushContext(EntityManager.class, em);
67
+ ResteasyProviderFactory.pushContext(EntityManager.class, em);
6868
69
- ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext
70
- .getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
71
- Method method = methodInvoker.getMethod();
69
+ ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
70
+ Method method = methodInvoker.getMethod();
7271
73
- LOG.debug("Stored in context, em: {}, {}", em, method.toGenericString());
72
+ LOG.debug("Stored in context, em: {}, {}", em, method.toGenericString());
7473
75
- boolean next = checkSecurableMethods(containerRequestContext, method);
76
- if (next) {
77
- prepareTransaction(containerRequestContext, method, em);
78
- }
79
- }
74
+ boolean next = checkSecurableMethods(containerRequestContext, method);
75
+ if (next) {
76
+ prepareTransaction(containerRequestContext, method, em);
77
+ }
78
+ }
8079
81
- private void prepareTransaction(ContainerRequestContext containerRequestContext, Method method, EntityManager em) {
80
+ private void prepareTransaction(ContainerRequestContext containerRequestContext, Method method, EntityManager em) {
8281
83
- if (method.isAnnotationPresent(EnsureTransaction.class)) {
84
- LOG.debug("Beginning a new transaction");
85
- em.getTransaction().begin();
86
- }
87
- }
82
+ if (method.isAnnotationPresent(EnsureTransaction.class)) {
83
+ LOG.debug("Beginning a new transaction");
84
+ em.getTransaction().begin();
85
+ }
86
+ }
8887
89
- private boolean checkSecurableMethods(ContainerRequestContext containerRequestContext, Method method) {
90
- if (!method.isAnnotationPresent(Securable.class)) {
91
- return true;
92
- }
93
- String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM);
94
- if (token == null || !tokenHelper.isTokenValid(token)) {
95
- LOG.warn("Access denied, Token not valid: {} for method: {}::{}", token, method.getDeclaringClass(), method.getName());
96
- containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
97
- return false;
98
- } else {
88
+ private boolean checkSecurableMethods(ContainerRequestContext containerRequestContext, Method method) {
89
+ if (!method.isAnnotationPresent(Securable.class)) {
90
+ return true;
91
+ }
92
+ String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM);
93
+ if (token == null || !tokenHelper.isTokenValid(token)) {
94
+ LOG.warn("Access denied, Token not valid: {} for method: {}::{}", token, method.getDeclaringClass(), method.getName());
95
+ containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
96
+ return false;
97
+ } else {
98
+ Securable securable = method.getAnnotation(Securable.class);
99
+ // If roles == 0 we only need to validate the token
100
+ String username = tokenHelper.extractUserFromToken(token);
101
+ int userRoles = getUserRoles(username);
102
+ if (securable.roles() != 0 && (securable.roles() & userRoles) == 0) {
103
+ LOG.warn("Method {} requires roles: {}, but user {} hasn't got them", method.getName(), securable.roles(), username);
104
+ containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
105
+ return false;
106
+ }
107
+ Set<Integer> orgs = getUserOrganizations(username);
108
+ Set<Integer> apps = getUserApplications(username);
99109
100
- // If roles == 0 we only need to validate the token
101
- String username = tokenHelper.extractUserFromToken(token);
102
- int userRoles = getUserRoles(username);
103
- Set<Integer> orgs = getUserOrganizations(username);
110
+ BasicSecurityContext scw = new BasicSecurityContext(username, userRoles, servletRequest.isSecure());
111
+ scw.setOrganizationsIds(orgs);
112
+ scw.setApplicationsIds(apps);
113
+ containerRequestContext.setSecurityContext(scw);
114
+ // Next line provide injection in resource methods
115
+ ResteasyProviderFactory.pushContext(BasicSecurityContext.class, scw);
116
+ LOG.debug("Added custom SecurityContext for user {}, orgs: {}", username, orgs);
117
+ }
118
+ return true;
104119
105
- BasicSecurityContext scw = new BasicSecurityContext(username, userRoles, servletRequest.isSecure());
106
- scw.setOrganizationsIds(orgs);
107
- containerRequestContext.setSecurityContext(scw);
108
- // Next line provide injection in resource methods
109
- ResteasyProviderFactory.pushContext(BasicSecurityContext.class, scw);
110
- LOG.debug("Added custom SecurityContext for user {}, orgs: {}", username, orgs);
111
- }
112
- return true;
120
+ }
113121
114
- }
122
+ private Set<Integer> getUserOrganizations(String username) {
123
+ @SuppressWarnings("unchecked")
124
+ Set<Integer> userOrgs = cache.get("orgs_" + username, Set.class);
125
+ if (userOrgs == null) {
126
+ EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class);
115127
116
- private Set<Integer> getUserOrganizations(String username) {
117
- @SuppressWarnings("unchecked")
118
- Set<Integer> userOrgs = cache.get("orgs_" + username, Set.class);
119
- if (userOrgs == null) {
120
- EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class);
128
+ // Theorically this shouldn't be never null, but just in case...
129
+ User user = em.find(User.class, username);
130
+ if (user != null) {
131
+ userOrgs = user.getAllOrgsIds();
132
+ // We store user orgs in cache only for one hour
133
+ cache.set("orgs_" + username, userOrgs, 3600);
134
+ }
135
+ }
121136
122
- // Theorically this shouldn't be never null, but just in case...
123
- User user = em.find(User.class, username);
124
- if (user != null) {
125
- userOrgs = user.getAllOrgsIds();
126
- // We store user orgs in cache only for one hour
127
- cache.set("orgs_" + username, userOrgs, 3600);
128
- }
129
- }
137
+ return userOrgs;
138
+ }
130139
131
- return userOrgs;
132
- }
140
+ private Set<Integer> getUserApplications(String username) {
141
+ @SuppressWarnings("unchecked")
142
+ Set<Integer> userApps = cache.get("apps_" + username, Set.class);
143
+ if (userApps == null) {
144
+ EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class);
133145
134
- private int getUserRoles(String username) {
135
- if (username == null) {
136
- return 0;
137
- }
138
- Integer userRoles = cache.get("roles_" + username, Integer.class);
139
- if (userRoles == null) {
140
- EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class);
146
+ // Theorically this shouldn't be never null, but just in case...
147
+ User user = em.find(User.class, username);
148
+ if (user != null) {
149
+ userApps = user.getAllAppsIds();
150
+ // We store user orgs in cache only for one hour
151
+ cache.set("apps_" + username, userApps, 3600);
152
+ }
153
+ }
141154
142
- User user = em.find(User.class, username);
143
- if (user != null) {
144
- userRoles = 0;
145
- List<Integer> roles = user.getRoles();
146
- if (roles != null) {
147
- for (Integer rol : roles) {
148
- userRoles += rol;
149
- }
150
- }
151
- // We store user roles in cache only for one hour
152
- cache.set("roles_" + username, userRoles, 3600);
153
- cache.set("orgs_" + username, user.getOrgsIds(), 3600);
154
- }
155
- }
156
- return userRoles == null ? 0 : userRoles.intValue();
157
- }
155
+ return userApps;
156
+ }
158157
159
- // @Override
160
- public ServerResponse preProcess(HttpRequest request, ResourceMethodInvoker method) throws Failure, WebApplicationException {
161
- return null;
162
- }
158
+ private int getUserRoles(String username) {
159
+ if (username == null) {
160
+ return 0;
161
+ }
162
+ Integer userRoles = cache.get("roles_" + username, Integer.class);
163
+ if (userRoles == null) {
164
+ EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class);
163165
164
- @Override
165
- public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
166
- context.proceed();
167
- EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class);
168
- try {
169
- if (em != null && em.getTransaction().isActive()) {
170
- if (servletResponse.getStatus() == Status.OK.getStatusCode()) {
171
- em.getTransaction().commit();
172
- LOG.debug("COMMIT");
173
- } else {
174
- // This code is never executed if there is an error the
175
- // filter chain is broken
176
- em.getTransaction().rollback();
177
- LOG.debug("ROLLBACK");
178
- }
179
- }
180
- } finally {
181
- if (em.isOpen()) {
182
- LOG.debug("CLOSING EM: {}, trans: {}", em, em.isJoinedToTransaction());
183
- try {
184
- em.close();
185
- } catch (Exception ex) {
186
- ex.printStackTrace();
187
- LOG.error("Error closing EM: {}, {}", em, ex);
188
- }
189
- }
190
- }
191
- }
166
+ User user = em.find(User.class, username);
167
+ if (user != null) {
168
+ userRoles = 0;
169
+ List<Integer> roles = user.getRoles();
170
+ if (roles != null) {
171
+ for (Integer rol : roles) {
172
+ userRoles += rol;
173
+ }
174
+ }
175
+ // We store user roles in cache only for one hour
176
+ cache.set("roles_" + username, userRoles, 3600);
177
+ cache.set("orgs_" + username, user.getOrgsIds(), 3600);
178
+ }
179
+ }
180
+ return userRoles == null ? 0 : userRoles.intValue();
181
+ }
182
+
183
+ // @Override
184
+ public ServerResponse preProcess(HttpRequest request, ResourceMethodInvoker method) throws Failure, WebApplicationException {
185
+ return null;
186
+ }
187
+
188
+ @Override
189
+ public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
190
+ context.proceed();
191
+ EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class);
192
+ try {
193
+ if (em != null && em.getTransaction().isActive()) {
194
+ if (servletResponse.getStatus() == Status.OK.getStatusCode()) {
195
+ em.getTransaction().commit();
196
+ LOG.debug("COMMIT");
197
+ } else {
198
+ // This code is never executed if there is an error the
199
+ // filter chain is broken
200
+ em.getTransaction().rollback();
201
+ LOG.debug("ROLLBACK");
202
+ }
203
+ }
204
+ } finally {
205
+ if (em.isOpen()) {
206
+ LOG.debug("CLOSING EM: {}, trans: {}", em, em.isJoinedToTransaction());
207
+ try {
208
+ em.close();
209
+ } catch (Exception ex) {
210
+ ex.printStackTrace();
211
+ LOG.error("Error closing EM: {}, {}", em, ex);
212
+ }
213
+ }
214
+ }
215
+ }
192216
193217 }