Roberto Sánchez
2014-01-17 c2cf57687d1d61fd476659bc5bead0592143a5c6
#395 feature - Added remaining resources to REST API in Licenses
management
3 files added
6 files modified
changed files
securis/src/main/java/net/curisit/securis/db/License.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/services/ApiResource.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/LicenseResource.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/PackResource.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/utils/TokenHelper.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/License.java
....@@ -145,17 +145,17 @@
145145 }
146146
147147 @JsonProperty("pack_code")
148
- public String getLicenseTypcode() {
148
+ public String getPackCode() {
149149 return pack == null ? null : pack.getCode();
150150 }
151151
152152 @JsonProperty("pack_id")
153
- public Integer getOrgId() {
153
+ public Integer getPackId() {
154154 return pack == null ? null : pack.getId();
155155 }
156156
157157 @JsonProperty("pack_id")
158
- public void setOrgId(Integer idPack) {
158
+ public void setPackId(Integer idPack) {
159159 if (idPack == null) {
160160 pack = null;
161161 } else {
securis/src/main/java/net/curisit/securis/ioc/RequestsModule.java
....@@ -1,10 +1,13 @@
11 package net.curisit.securis.ioc;
22
3
+import net.curisit.securis.services.ApiResource;
34 import net.curisit.securis.services.ApplicationResource;
45 import net.curisit.securis.services.BasicServices;
6
+import net.curisit.securis.services.LicenseResource;
57 import net.curisit.securis.services.LicenseServices;
68 import net.curisit.securis.services.LicenseTypeResource;
79 import net.curisit.securis.services.OrganizationResource;
10
+import net.curisit.securis.services.PackResource;
811 import net.curisit.securis.services.SecurityInterceptor;
912 import net.curisit.securis.services.UserResource;
1013
....@@ -29,6 +32,9 @@
2932 bind(ApplicationResource.class);
3033 bind(LicenseTypeResource.class);
3134 bind(OrganizationResource.class);
35
+ bind(ApiResource.class);
36
+ bind(LicenseResource.class);
37
+ bind(PackResource.class);
3238 }
3339
3440 @Provides
securis/src/main/java/net/curisit/securis/services/ApiResource.java
....@@ -0,0 +1,49 @@
1
+package net.curisit.securis.services;
2
+
3
+import javax.inject.Inject;
4
+import javax.inject.Provider;
5
+import javax.persistence.EntityManager;
6
+import javax.ws.rs.GET;
7
+import javax.ws.rs.Path;
8
+import javax.ws.rs.Produces;
9
+import javax.ws.rs.core.MediaType;
10
+import javax.ws.rs.core.Response;
11
+
12
+import net.curisit.securis.utils.TokenHelper;
13
+
14
+import org.slf4j.Logger;
15
+import org.slf4j.LoggerFactory;
16
+
17
+/**
18
+ * External API to be accessed by third parties
19
+ *
20
+ * @author roberto <roberto.sanchez@curisit.net>
21
+ */
22
+@Path("/api")
23
+public class ApiResource {
24
+
25
+ @SuppressWarnings("unused")
26
+ private static final Logger log = LoggerFactory.getLogger(ApiResource.class);
27
+
28
+ @Inject
29
+ TokenHelper tokenHelper;
30
+
31
+ @Inject
32
+ Provider<EntityManager> emProvider;
33
+
34
+ public ApiResource() {
35
+ }
36
+
37
+ /**
38
+ *
39
+ * @return Simple text message to check API status
40
+ */
41
+ @GET
42
+ @Path("/")
43
+ @Produces(
44
+ { MediaType.TEXT_PLAIN })
45
+ public Response index() {
46
+ return Response.ok("SeCuris API").build();
47
+ }
48
+
49
+}
securis/src/main/java/net/curisit/securis/services/BasicServices.java
....@@ -21,7 +21,6 @@
2121 import javax.ws.rs.core.UriBuilder;
2222
2323 import net.curisit.integrity.commons.Utils;
24
-import net.curisit.securis.db.User;
2524 import net.curisit.securis.utils.TokenHelper;
2625
2726 import org.slf4j.Logger;
....@@ -88,7 +87,7 @@
8887 * @return
8988 */
9089 @GET
91
- @Securable(roles = User.Rol.ADMIN)
90
+ @Securable()
9291 @Path("/check")
9392 @Produces(
9493 { MediaType.APPLICATION_JSON })
securis/src/main/java/net/curisit/securis/services/LicenseResource.java
....@@ -0,0 +1,216 @@
1
+package net.curisit.securis.services;
2
+
3
+import java.util.Date;
4
+import java.util.List;
5
+
6
+import javax.inject.Inject;
7
+import javax.inject.Provider;
8
+import javax.persistence.EntityManager;
9
+import javax.persistence.TypedQuery;
10
+import javax.servlet.http.HttpServletRequest;
11
+import javax.ws.rs.Consumes;
12
+import javax.ws.rs.DELETE;
13
+import javax.ws.rs.GET;
14
+import javax.ws.rs.HeaderParam;
15
+import javax.ws.rs.POST;
16
+import javax.ws.rs.PUT;
17
+import javax.ws.rs.Path;
18
+import javax.ws.rs.PathParam;
19
+import javax.ws.rs.Produces;
20
+import javax.ws.rs.core.Context;
21
+import javax.ws.rs.core.MediaType;
22
+import javax.ws.rs.core.Response;
23
+import javax.ws.rs.core.Response.Status;
24
+
25
+import net.curisit.integrity.commons.Utils;
26
+import net.curisit.integrity.exception.CurisException;
27
+import net.curisit.securis.SecurisErrorHandler;
28
+import net.curisit.securis.db.License;
29
+import net.curisit.securis.db.Pack;
30
+import net.curisit.securis.db.User;
31
+import net.curisit.securis.utils.TokenHelper;
32
+
33
+import org.slf4j.Logger;
34
+import org.slf4j.LoggerFactory;
35
+
36
+import com.google.inject.persist.Transactional;
37
+
38
+/**
39
+ * License resource, this service will provide methods to create, modify and delete licenses
40
+ *
41
+ * @author roberto <roberto.sanchez@curisit.net>
42
+ */
43
+@Path("/organization")
44
+public class LicenseResource {
45
+
46
+ private static final Logger log = LoggerFactory.getLogger(LicenseResource.class);
47
+
48
+ @Inject
49
+ TokenHelper tokenHelper;
50
+
51
+ @Inject
52
+ Provider<EntityManager> emProvider;
53
+
54
+ public LicenseResource() {
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @return the server version in format majorVersion.minorVersion
60
+ */
61
+ @GET
62
+ @Path("/")
63
+ @Produces(
64
+ { MediaType.APPLICATION_JSON })
65
+ public Response index() {
66
+ log.info("Getting licenses list ");
67
+
68
+ EntityManager em = emProvider.get();
69
+ TypedQuery<License> q = em.createNamedQuery("list-licenses-by-pack", License.class);
70
+
71
+ List<License> list = q.getResultList();
72
+
73
+ return Response.ok(list).build();
74
+ }
75
+
76
+ /**
77
+ *
78
+ * @return the server version in format majorVersion.minorVersion
79
+ */
80
+ @GET
81
+ @Path("/{licId}")
82
+ @Produces(
83
+ { MediaType.APPLICATION_JSON })
84
+ public Response get(@PathParam("licId") String licId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
85
+ log.info("Getting organization data for id: {}: ", licId);
86
+ if (licId == null || licId.equals("")) {
87
+ log.error("License ID is mandatory");
88
+ return Response.status(Status.NOT_FOUND).build();
89
+ }
90
+
91
+ EntityManager em = emProvider.get();
92
+ License lt = em.find(License.class, Integer.parseInt(licId));
93
+ if (lt == null) {
94
+ log.error("License with id {} not found in DB", licId);
95
+ return Response.status(Status.NOT_FOUND).build();
96
+ }
97
+ return Response.ok(lt).build();
98
+ }
99
+
100
+ @POST
101
+ @Path("/")
102
+ @Consumes(MediaType.APPLICATION_JSON)
103
+ @Produces(
104
+ { MediaType.APPLICATION_JSON })
105
+ @Transactional
106
+ public Response create(License lic, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
107
+ log.info("Creating new organization");
108
+ EntityManager em = emProvider.get();
109
+ Pack pack = null;
110
+ if (lic.getPackId() != null) {
111
+ pack = em.find(Pack.class, lic.getPackId());
112
+ if (pack == null) {
113
+ log.error("License pack with id {} not found in DB", lic.getPackId());
114
+ return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's pack not found with ID: " + lic.getPackId()).build();
115
+ }
116
+ }
117
+
118
+ try {
119
+ User createdBy = getUser(lic.getCreatedById(), em);
120
+ lic.setCreatedBy(createdBy);
121
+ } catch (CurisException ex) {
122
+ String createdByUsername = lic.getCreatedById();
123
+ log.error("License created by user with id {} not found in DB", createdByUsername);
124
+ return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's created by user not found with ID: " + createdByUsername).build();
125
+ }
126
+
127
+ try {
128
+ User canceledBy = getUser(lic.getCanceledById(), em);
129
+ lic.setCanceledBy(canceledBy);
130
+ } catch (CurisException ex) {
131
+ String canceledByUsername = lic.getCreatedById();
132
+ log.error("License canceled by user with id {} not found in DB", canceledByUsername);
133
+ return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's canceled by user not found with ID: " + canceledByUsername).build();
134
+ }
135
+
136
+ lic.setCreationTimestamp(new Date());
137
+ em.persist(lic);
138
+
139
+ return Response.ok(lic).build();
140
+ }
141
+
142
+ private User getUser(String username, EntityManager em) throws CurisException {
143
+ User user = null;
144
+ if (username != null) {
145
+ user = em.find(User.class, username);
146
+ if (user == null) {
147
+ throw new CurisException("User not found");
148
+ }
149
+ }
150
+ return user;
151
+ }
152
+
153
+ @PUT
154
+ @POST
155
+ @Path("/{licId}")
156
+ @Transactional
157
+ @Consumes(MediaType.APPLICATION_JSON)
158
+ @Produces(
159
+ { MediaType.APPLICATION_JSON })
160
+ public Response modify(License lic, @PathParam("licId") String licId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
161
+ log.info("Modifying organization with id: {}", licId);
162
+ EntityManager em = emProvider.get();
163
+
164
+ Pack pack = null;
165
+ if (lic.getPackId() != null) {
166
+ pack = em.find(Pack.class, lic.getPackId());
167
+ if (pack == null) {
168
+ log.error("License pack with id {} not found in DB", lic.getPackId());
169
+ return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's pack not found with ID: " + lic.getPackId()).build();
170
+ }
171
+ }
172
+ User createdBy = null;
173
+ try {
174
+ createdBy = getUser(lic.getCreatedById(), em);
175
+ } catch (CurisException ex) {
176
+ String createdByUsername = lic.getCreatedById();
177
+ log.error("License created by user with id {} not found in DB", createdByUsername);
178
+ return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's created by user not found with ID: " + createdByUsername).build();
179
+ }
180
+
181
+ User canceledBy = null;
182
+ try {
183
+ canceledBy = getUser(lic.getCanceledById(), em);
184
+ } catch (CurisException ex) {
185
+ String canceledByUsername = lic.getCreatedById();
186
+ log.error("License canceled by user with id {} not found in DB", canceledByUsername);
187
+ return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License's canceled by user not found with ID: " + canceledByUsername).build();
188
+ }
189
+
190
+ lic.setCreatedBy(createdBy);
191
+ lic.setCanceledBy(canceledBy);
192
+ lic.setPack(pack);
193
+ em.persist(lic);
194
+
195
+ return Response.ok(lic).build();
196
+ }
197
+
198
+ @DELETE
199
+ @Path("/{licId}")
200
+ @Transactional
201
+ @Produces(
202
+ { MediaType.APPLICATION_JSON })
203
+ public Response delete(@PathParam("licId") String licId, @Context HttpServletRequest request) {
204
+ log.info("Deleting license with id: {}", licId);
205
+ EntityManager em = emProvider.get();
206
+ License org = em.find(License.class, Integer.parseInt(licId));
207
+ if (org == null) {
208
+ log.error("License with id {} can not be deleted, It was not found in DB", licId);
209
+ return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "License was not found, ID: " + licId).build();
210
+ }
211
+
212
+ em.remove(org);
213
+ return Response.ok(Utils.createMap("success", true, "id", licId)).build();
214
+ }
215
+
216
+}
securis/src/main/java/net/curisit/securis/services/OrganizationResource.java
....@@ -202,7 +202,7 @@
202202 @Produces(
203203 { MediaType.APPLICATION_JSON })
204204 public Response delete(@PathParam("orgid") String orgid, @Context HttpServletRequest request) {
205
- log.info("Deleting app with id: {}", orgid);
205
+ log.info("Deleting organization with id: {}", orgid);
206206 EntityManager em = emProvider.get();
207207 Organization org = em.find(Organization.class, Integer.parseInt(orgid));
208208 if (org == null) {
securis/src/main/java/net/curisit/securis/services/PackResource.java
....@@ -0,0 +1,160 @@
1
+package net.curisit.securis.services;
2
+
3
+import java.util.Date;
4
+import java.util.List;
5
+
6
+import javax.inject.Inject;
7
+import javax.inject.Provider;
8
+import javax.persistence.EntityManager;
9
+import javax.persistence.TypedQuery;
10
+import javax.servlet.http.HttpServletRequest;
11
+import javax.ws.rs.Consumes;
12
+import javax.ws.rs.DELETE;
13
+import javax.ws.rs.GET;
14
+import javax.ws.rs.HeaderParam;
15
+import javax.ws.rs.POST;
16
+import javax.ws.rs.PUT;
17
+import javax.ws.rs.Path;
18
+import javax.ws.rs.PathParam;
19
+import javax.ws.rs.Produces;
20
+import javax.ws.rs.core.Context;
21
+import javax.ws.rs.core.MediaType;
22
+import javax.ws.rs.core.Response;
23
+import javax.ws.rs.core.Response.Status;
24
+
25
+import net.curisit.integrity.commons.Utils;
26
+import net.curisit.integrity.exception.CurisException;
27
+import net.curisit.securis.SecurisErrorHandler;
28
+import net.curisit.securis.db.Pack;
29
+import net.curisit.securis.db.User;
30
+import net.curisit.securis.utils.TokenHelper;
31
+
32
+import org.slf4j.Logger;
33
+import org.slf4j.LoggerFactory;
34
+
35
+import com.google.inject.persist.Transactional;
36
+
37
+/**
38
+ * Pack resource, this service will provide methods to create, modify and delete packs
39
+ *
40
+ * @author roberto <roberto.sanchez@curisit.net>
41
+ */
42
+@Path("/pack")
43
+public class PackResource {
44
+
45
+ private static final Logger log = LoggerFactory.getLogger(PackResource.class);
46
+
47
+ @Inject
48
+ TokenHelper tokenHelper;
49
+
50
+ @Inject
51
+ Provider<EntityManager> emProvider;
52
+
53
+ public PackResource() {
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @return the server version in format majorVersion.minorVersion
59
+ */
60
+ @GET
61
+ @Path("/")
62
+ @Produces(
63
+ { MediaType.APPLICATION_JSON })
64
+ public Response index() {
65
+ log.info("Getting packs list ");
66
+
67
+ EntityManager em = emProvider.get();
68
+ TypedQuery<Pack> q = em.createNamedQuery("list-packs-by-orgs", Pack.class);
69
+
70
+ List<Pack> list = q.getResultList();
71
+
72
+ return Response.ok(list).build();
73
+ }
74
+
75
+ /**
76
+ *
77
+ * @return the server version in format majorVersion.minorVersion
78
+ */
79
+ @GET
80
+ @Path("/{packId}")
81
+ @Produces(
82
+ { MediaType.APPLICATION_JSON })
83
+ public Response get(@PathParam("packId") String packId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
84
+ log.info("Getting pack data for id: {}: ", packId);
85
+ if (packId == null || packId.equals("")) {
86
+ log.error("Pack ID is mandatory");
87
+ return Response.status(Status.NOT_FOUND).build();
88
+ }
89
+
90
+ EntityManager em = emProvider.get();
91
+ Pack lt = em.find(Pack.class, Integer.parseInt(packId));
92
+ if (lt == null) {
93
+ log.error("Pack with id {} not found in DB", packId);
94
+ return Response.status(Status.NOT_FOUND).build();
95
+ }
96
+ return Response.ok(lt).build();
97
+ }
98
+
99
+ @POST
100
+ @Path("/")
101
+ @Consumes(MediaType.APPLICATION_JSON)
102
+ @Produces(
103
+ { MediaType.APPLICATION_JSON })
104
+ @Transactional
105
+ public Response create(Pack pack, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
106
+ log.info("Creating new pack");
107
+ EntityManager em = emProvider.get();
108
+
109
+ pack.setCreationTimestamp(new Date());
110
+ em.persist(pack);
111
+
112
+ return Response.ok(pack).build();
113
+ }
114
+
115
+ private User getUser(String username, EntityManager em) throws CurisException {
116
+ User user = null;
117
+ if (username != null) {
118
+ user = em.find(User.class, username);
119
+ if (user == null) {
120
+ throw new CurisException("User not found");
121
+ }
122
+ }
123
+ return user;
124
+ }
125
+
126
+ @PUT
127
+ @POST
128
+ @Path("/{packId}")
129
+ @Transactional
130
+ @Consumes(MediaType.APPLICATION_JSON)
131
+ @Produces(
132
+ { MediaType.APPLICATION_JSON })
133
+ public Response modify(Pack pack, @PathParam("packId") String packId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
134
+ log.info("Modifying pack with id: {}", packId);
135
+ EntityManager em = emProvider.get();
136
+
137
+ em.persist(pack);
138
+
139
+ return Response.ok(pack).build();
140
+ }
141
+
142
+ @DELETE
143
+ @Path("/{packId}")
144
+ @Transactional
145
+ @Produces(
146
+ { MediaType.APPLICATION_JSON })
147
+ public Response delete(@PathParam("packId") String packId, @Context HttpServletRequest request) {
148
+ log.info("Deleting pack with id: {}", packId);
149
+ EntityManager em = emProvider.get();
150
+ Pack org = em.find(Pack.class, Integer.parseInt(packId));
151
+ if (org == null) {
152
+ log.error("Pack with id {} can not be deleted, It was not found in DB", packId);
153
+ return Response.status(Status.NOT_FOUND).header(SecurisErrorHandler.HEADER_ERROR_MESSAGE, "Pack was not found, ID: " + packId).build();
154
+ }
155
+
156
+ em.remove(org);
157
+ return Response.ok(Utils.createMap("success", true, "id", packId)).build();
158
+ }
159
+
160
+}
securis/src/main/java/net/curisit/securis/services/SecurityInterceptor.java
....@@ -40,31 +40,33 @@
4040
4141 @Override
4242 public void filter(ContainerRequestContext containerRequestContext) throws IOException {
43
- log.info("filter using REST interceptor, method: {}", containerRequestContext.getMethod());
44
-
45
- log.info("filter using REST interceptor, ResourceMethodInvoker: {}", containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker"));
4643 ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
4744 Method method = methodInvoker.getMethod();
4845
4946 if (!method.isAnnotationPresent(Securable.class))
5047 return;
5148 String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM);
52
- if (token == null || !tokenHelper.isTokenValid(token))
49
+ if (token == null || !tokenHelper.isTokenValid(token)) {
50
+ log.info("Access denied to '{}', Token not valid.", servletRequest.getPathInfo());
5351 containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
54
- Securable sec = method.getAnnotation(Securable.class);
52
+ } else {
53
+ Securable sec = method.getAnnotation(Securable.class);
5554
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());
55
+ // If roles == 0 we only need to validate the token
56
+ if (sec.roles() != 0) {
57
+ String username = tokenHelper.extractUserFromToken(token);
58
+ int userRoles = getUserRoles(username);
59
+ if ((sec.roles() & userRoles) == 0) {
60
+ log.info("User {} has no necessary role to access url: {}", username, servletRequest.getPathInfo());
61
+ containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
62
+ }
6363 }
6464 }
6565 }
6666
6767 private int getUserRoles(String username) {
68
+ if (username == null)
69
+ return 0;
6870 Integer userRoles = cache.get("roles_" + username, Integer.class);
6971 if (userRoles == null) {
7072 EntityManager em = emProvider.get();
securis/src/main/java/net/curisit/securis/utils/TokenHelper.java
....@@ -101,6 +101,8 @@
101101
102102 public String extractUserFromToken(String token) {
103103 try {
104
+ if (token == null)
105
+ return null;
104106 String tokenDecoded = new String(Base64.decode(token));
105107 String[] parts = StringUtils.split(tokenDecoded, ' ');
106108 if (parts == null || parts.length < 3)