Roberto Sánchez
2014-01-23 cbfe9207ad7c9bba96b39c550d250d12097fd06f
#395 feature - Implemented license section at 75%
7 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/services/LicenseResource.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/PackResource.java patch | view | blame | history
securis/src/main/resources/static/css/securis.css patch | view | blame | history
securis/src/main/resources/static/js/licenses.js patch | view | blame | history
securis/src/main/resources/static/js/main.js patch | view | blame | history
securis/src/main/resources/static/licenses.html patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/License.java
....@@ -15,6 +15,7 @@
1515
1616 import org.codehaus.jackson.annotate.JsonAutoDetect;
1717 import org.codehaus.jackson.annotate.JsonIgnore;
18
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
1819 import org.codehaus.jackson.annotate.JsonProperty;
1920 import org.codehaus.jackson.map.annotate.JsonSerialize;
2021
....@@ -26,8 +27,9 @@
2627 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
2728 @Entity
2829 @Table(name = "license")
30
+@JsonIgnoreProperties(ignoreUnknown = true)
2931 @NamedQueries(
30
- { @NamedQuery(name = "list-licenses", query = "SELECT l FROM License l") })
32
+ { @NamedQuery(name = "list-licenses-by-pack", query = "SELECT l FROM License l where l.pack.id = :packId") })
3133 public class License implements Serializable {
3234
3335 private static final long serialVersionUID = 1L;
....@@ -56,9 +58,18 @@
5658 private int status;
5759
5860 @Column(name = "full_name")
61
+ @JsonProperty("full_name")
5962 private String fullName;
6063
6164 private String email;
65
+
66
+ @Column(name = "request_data")
67
+ @JsonProperty("request_data")
68
+ private String requestData;
69
+
70
+ @Column(name = "license_data")
71
+ @JsonProperty("license_data")
72
+ private String licenseData;
6273
6374 @Column(name = "creation_timestamp")
6475 private Date creationTimestamp;
....@@ -77,6 +88,8 @@
7788
7889 @Column(name = "last_access_timestamp")
7990 private Date lastAccessTimestamp;
91
+
92
+ private String comments;
8093
8194 public int getId() {
8295 return id;
....@@ -240,6 +253,30 @@
240253 this.lastAccessTimestamp = lastAccessTimestamp;
241254 }
242255
256
+ public String getRequestData() {
257
+ return requestData;
258
+ }
259
+
260
+ public void setRequestData(String requestData) {
261
+ this.requestData = requestData;
262
+ }
263
+
264
+ public String getLicenseData() {
265
+ return licenseData;
266
+ }
267
+
268
+ public void setLicenseData(String licenseData) {
269
+ this.licenseData = licenseData;
270
+ }
271
+
272
+ public String getComments() {
273
+ return comments;
274
+ }
275
+
276
+ public void setComments(String comments) {
277
+ this.comments = comments;
278
+ }
279
+
243280 public static class Status {
244281 public static final int CREATED = 0;
245282 public static final int SENT = 1;
securis/src/main/java/net/curisit/securis/services/LicenseResource.java
....@@ -7,16 +7,15 @@
77 import javax.inject.Provider;
88 import javax.persistence.EntityManager;
99 import javax.persistence.TypedQuery;
10
-import javax.servlet.http.HttpServletRequest;
1110 import javax.ws.rs.Consumes;
1211 import javax.ws.rs.DELETE;
1312 import javax.ws.rs.GET;
14
-import javax.ws.rs.HeaderParam;
1513 import javax.ws.rs.POST;
1614 import javax.ws.rs.PUT;
1715 import javax.ws.rs.Path;
1816 import javax.ws.rs.PathParam;
1917 import javax.ws.rs.Produces;
18
+import javax.ws.rs.QueryParam;
2019 import javax.ws.rs.core.Context;
2120 import javax.ws.rs.core.MediaType;
2221 import javax.ws.rs.core.Response;
....@@ -28,6 +27,8 @@
2827 import net.curisit.securis.db.License;
2928 import net.curisit.securis.db.Pack;
3029 import net.curisit.securis.db.User;
30
+import net.curisit.securis.security.BasicSecurityContext;
31
+import net.curisit.securis.security.Securable;
3132 import net.curisit.securis.utils.TokenHelper;
3233
3334 import org.slf4j.Logger;
....@@ -40,7 +41,7 @@
4041 *
4142 * @author roberto <roberto.sanchez@curisit.net>
4243 */
43
-@Path("/organization")
44
+@Path("/license")
4445 public class LicenseResource {
4546
4647 private static final Logger log = LoggerFactory.getLogger(LicenseResource.class);
....@@ -60,14 +61,25 @@
6061 */
6162 @GET
6263 @Path("/")
64
+ @Securable
6365 @Produces(
6466 { MediaType.APPLICATION_JSON })
65
- public Response index() {
67
+ public Response index(@QueryParam("packId") Integer packId, @Context BasicSecurityContext bsc) {
6668 log.info("Getting licenses list ");
6769
6870 EntityManager em = emProvider.get();
69
- TypedQuery<License> q = em.createNamedQuery("list-licenses-by-pack", License.class);
7071
72
+ if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
73
+ Pack pack = em.find(Pack.class, packId);
74
+ if (pack == null)
75
+ return Response.ok().build();
76
+ if (!bsc.getOrganizationsIds().contains(pack.getOrganization().getId())) {
77
+ log.error("Pack with id {} not accesible by user {}", pack, bsc.getUserPrincipal());
78
+ return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to pack licenses").build();
79
+ }
80
+ }
81
+ TypedQuery<License> q = em.createNamedQuery("list-licenses-by-pack", License.class);
82
+ q.setParameter("packId", packId);
7183 List<License> list = q.getResultList();
7284
7385 return Response.ok(list).build();
....@@ -79,9 +91,10 @@
7991 */
8092 @GET
8193 @Path("/{licId}")
94
+ @Securable
8295 @Produces(
8396 { MediaType.APPLICATION_JSON })
84
- public Response get(@PathParam("licId") String licId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
97
+ public Response get(@PathParam("licId") Integer licId, @Context BasicSecurityContext bsc) {
8598 log.info("Getting organization data for id: {}: ", licId);
8699 if (licId == null || licId.equals("")) {
87100 log.error("License ID is mandatory");
....@@ -89,21 +102,28 @@
89102 }
90103
91104 EntityManager em = emProvider.get();
92
- License lt = em.find(License.class, Integer.parseInt(licId));
93
- if (lt == null) {
105
+ License lic = em.find(License.class, licId);
106
+ if (lic == null) {
94107 log.error("License with id {} not found in DB", licId);
95
- return Response.status(Status.NOT_FOUND).build();
108
+ return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License not found for ID: " + licId).build();
96109 }
97
- return Response.ok(lt).build();
110
+ if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
111
+ if (!bsc.getOrganizationsIds().contains(lic.getPack().getOrganization().getId())) {
112
+ log.error("License with id {} is not accesible by user {}", licId, bsc.getUserPrincipal());
113
+ return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to license data").build();
114
+ }
115
+ }
116
+ return Response.ok(lic).build();
98117 }
99118
100119 @POST
101120 @Path("/")
102121 @Consumes(MediaType.APPLICATION_JSON)
122
+ @Securable
103123 @Produces(
104124 { MediaType.APPLICATION_JSON })
105125 @Transactional
106
- public Response create(License lic, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
126
+ public Response create(License lic, @Context BasicSecurityContext bsc) {
107127 log.info("Creating new organization");
108128 EntityManager em = emProvider.get();
109129 Pack pack = null;
....@@ -112,6 +132,13 @@
112132 if (pack == null) {
113133 log.error("License pack with id {} not found in DB", lic.getPackId());
114134 return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's pack not found with ID: " + lic.getPackId()).build();
135
+ } else {
136
+ if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
137
+ if (!bsc.getOrganizationsIds().contains(pack.getOrganization().getId())) {
138
+ log.error("License for pack with id {} can not be created by user {}", pack.getId(), bsc.getUserPrincipal());
139
+ return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized action on pack license").build();
140
+ }
141
+ }
115142 }
116143 }
117144
....@@ -124,16 +151,11 @@
124151 return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's created by user not found with ID: " + createdByUsername).build();
125152 }
126153
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(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's canceled by user not found with ID: " + canceledByUsername).build();
134
- }
135
-
154
+ // ODO: Manage status if request data is set
155
+ lic.setCanceledBy(null);
156
+ lic.setStatus(License.Status.CREATED);
136157 lic.setCreationTimestamp(new Date());
158
+ lic.setModificationTimestamp(lic.getCreationTimestamp());
137159 em.persist(lic);
138160
139161 return Response.ok(lic).build();
....@@ -153,22 +175,30 @@
153175 @PUT
154176 @POST
155177 @Path("/{licId}")
178
+ @Securable
156179 @Transactional
157180 @Consumes(MediaType.APPLICATION_JSON)
158181 @Produces(
159182 { MediaType.APPLICATION_JSON })
160
- public Response modify(License lic, @PathParam("licId") String licId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
183
+ public Response modify(License lic, @PathParam("licId") Integer licId, @Context BasicSecurityContext bsc) {
161184 log.info("Modifying organization with id: {}", licId);
162185 EntityManager em = emProvider.get();
163186
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(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's pack not found with ID: " + lic.getPackId()).build();
170
- }
171
- }
187
+ // Pack pack = null;
188
+ // if (lic.getPackId() != null) {
189
+ // pack = em.find(Pack.class, lic.getPackId());
190
+ // if (pack == null) {
191
+ // log.error("License pack with id {} not found in DB", lic.getPackId());
192
+ // return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's pack not found with ID: " + lic.getPackId()).build();
193
+ // } else {
194
+ // if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
195
+ // if (!bsc.getOrganizationsIds().contains(pack.getOrganization().getId())) {
196
+ // log.error("License for pack with id {} can not be modified by user {}", pack.getId(), bsc.getUserPrincipal());
197
+ // return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized action on pack license").build();
198
+ // }
199
+ // }
200
+ // }
201
+ // }
172202 User createdBy = null;
173203 try {
174204 createdBy = getUser(lic.getCreatedById(), em);
....@@ -186,30 +216,59 @@
186216 log.error("License canceled by user with id {} not found in DB", canceledByUsername);
187217 return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License's canceled by user not found with ID: " + canceledByUsername).build();
188218 }
219
+ License currentLicense = em.find(License.class, lic.getId());
220
+ if (currentLicense == null) {
221
+ log.error("License with id {} not found in DB", licId);
222
+ return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License not found for ID: " + licId).build();
223
+ }
224
+ if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
225
+ if (!bsc.getOrganizationsIds().contains(lic.getPack().getOrganization().getId())) {
226
+ log.error("License with id {} is not accesible by user {}", licId, bsc.getUserPrincipal());
227
+ return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to license data").build();
228
+ }
229
+ }
230
+ // TODO: set status based in current one and dates ? use custom actions ?
231
+ currentLicense.setCreatedBy(createdBy);
232
+ currentLicense.setCanceledBy(canceledBy);
233
+ // currentLicense.setPack(pack);
234
+ currentLicense.setCode(lic.getCode());
235
+ currentLicense.setFullName(lic.getFullName());
236
+ currentLicense.setEmail(lic.getEmail());
237
+ currentLicense.setRequestData(lic.getRequestData());
238
+ currentLicense.setModificationTimestamp(new Date());
239
+ em.persist(currentLicense);
189240
190
- lic.setCreatedBy(createdBy);
191
- lic.setCanceledBy(canceledBy);
192
- lic.setPack(pack);
193
- em.persist(lic);
194
-
195
- return Response.ok(lic).build();
241
+ return Response.ok(currentLicense).build();
196242 }
197243
198244 @DELETE
199245 @Path("/{licId}")
200246 @Transactional
247
+ @Securable
201248 @Produces(
202249 { MediaType.APPLICATION_JSON })
203
- public Response delete(@PathParam("licId") String licId, @Context HttpServletRequest request) {
250
+ public Response delete(@PathParam("licId") String licId, @Context BasicSecurityContext bsc) {
204251 log.info("Deleting license with id: {}", licId);
205252 EntityManager em = emProvider.get();
206
- License org = em.find(License.class, Integer.parseInt(licId));
207
- if (org == null) {
253
+ License lic = em.find(License.class, Integer.parseInt(licId));
254
+ if (lic == null) {
208255 log.error("License with id {} can not be deleted, It was not found in DB", licId);
209256 return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License was not found, ID: " + licId).build();
210257 }
211258
212
- em.remove(org);
259
+ if (!bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
260
+ if (!bsc.getOrganizationsIds().contains(lic.getPack().getOrganization().getId())) {
261
+ log.error("License with id {} is not accesible by user {}", licId, bsc.getUserPrincipal());
262
+ return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to license data").build();
263
+ }
264
+ }
265
+
266
+ if (lic.getStatus() != License.Status.CANCELED || lic.getStatus() != License.Status.CREATED) {
267
+ log.error("License {} can not be deleted with status {}", lic.getCode(), lic.getStatus());
268
+ return Response.status(Status.FORBIDDEN).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "License can not be deleted in current status").build();
269
+ }
270
+
271
+ em.remove(lic);
213272 return Response.ok(Utils.createMap("success", true, "id", licId)).build();
214273 }
215274
securis/src/main/java/net/curisit/securis/services/PackResource.java
....@@ -101,7 +101,7 @@
101101 @Securable
102102 @Produces(
103103 { MediaType.APPLICATION_JSON })
104
- public Response get(@PathParam("packId") String packId, @Context BasicSecurityContext bsc) {
104
+ public Response get(@PathParam("packId") Integer packId, @Context BasicSecurityContext bsc) {
105105 log.info("Getting pack data for id: {}: ", packId);
106106 if (packId == null || packId.equals("")) {
107107 log.error("Pack ID is mandatory");
....@@ -109,7 +109,7 @@
109109 }
110110
111111 EntityManager em = emProvider.get();
112
- Pack pack = em.find(Pack.class, Integer.parseInt(packId));
112
+ Pack pack = em.find(Pack.class, packId);
113113 if (pack == null) {
114114 log.error("Pack with id {} not found in DB", packId);
115115 return Response.status(Status.NOT_FOUND).build();
....@@ -171,10 +171,10 @@
171171 @Consumes(MediaType.APPLICATION_JSON)
172172 @Produces(
173173 { MediaType.APPLICATION_JSON })
174
- public Response modify(Pack pack, @PathParam("packId") String packId) {
174
+ public Response modify(Pack pack, @PathParam("packId") Integer packId) {
175175 log.info("Modifying pack with id: {}", packId);
176176 EntityManager em = emProvider.get();
177
- Pack currentPack = em.find(Pack.class, Integer.parseInt(packId));
177
+ Pack currentPack = em.find(Pack.class, packId);
178178
179179 Organization org = null;
180180 if (pack.getOrgId() != null) {
securis/src/main/resources/static/css/securis.css
....@@ -15,6 +15,7 @@
1515 }
1616 }
1717
18
+
1819 a {
1920 cursor: default !important;
2021 }
securis/src/main/resources/static/js/licenses.js
....@@ -60,7 +60,7 @@
6060 if (!txt || txt.length <= len) return txt;
6161 return txt.substring(0, len) + '...';
6262 }
63
- $scope.currentPackId = $store.get('currentPackId');
63
+ $scope.currentPack = $store.get('currentPack');
6464
6565 }]);
6666
....@@ -153,11 +153,131 @@
153153 $scope.showForm = false;
154154 }
155155
156
- $scope.selectPack = function(packId) {
157
- $scope.$parent.currentPackId = packId;
158
- $store.put('currentPackId', packId);
156
+ $scope.selectPack = function(pack) {
157
+ $scope.$parent.currentPack = pack;
158
+ $store.put('currentPack', pack);
159
+ $scope.$parent.$broadcast('pack_changed', pack);
159160 }
160161
161162 } ]);
162163
164
+ app.controller('LicensesCtrl', [
165
+ '$scope',
166
+ '$http',
167
+ '$resource',
168
+ 'toaster',
169
+ '$store',
170
+ '$L',
171
+ function($scope, $http, $resource, toaster, $store, $L) {
172
+ $scope.$on('pack_changed', function(evt, message) {
173
+ $scope.licenses = licenseResource.query({packId: $scope.currentPack.id});
174
+ console.log('on pack_changed');
175
+ if ($scope.showForm) {
176
+ if ($scope.isNew) {
177
+ $scope.license.pack_id = $scope.currentPack.id
178
+ } else {
179
+ $scope.showForm = false;
180
+ }
181
+ }
182
+ })
183
+
184
+ var licenseResource = $resource('/license/:licenseId', {
185
+ licenseId : '@id'
186
+ });
187
+ $scope.mandatory = {
188
+ code: true
189
+ }
190
+ $scope.maxlength = {
191
+ code: 50,
192
+ comments: 1024
193
+ }
194
+ $scope.refs = {};
195
+
196
+ // Used to create the form with the appropriate data
197
+ $scope.isNew = undefined;
198
+
199
+ // Selected license from listing
200
+ // license is the edited license, in creation contains the data for the new license
201
+ $scope.license = null;
202
+ if ($scope.currentPack)
203
+ $scope.licenses = licenseResource.query({packId: $scope.currentPack.id});
204
+
205
+ $scope.save = function() {
206
+ var _success = function() {
207
+ if (!$scope.isNew) $scope.showForm = false;
208
+ $scope.licenses = licenseResource.query({packId: $scope.currentPack.id});
209
+ }
210
+ licenseResource.save($scope.license, _success)
211
+ }
212
+
213
+ $scope.newLicense = function() {
214
+ if (!$scope.currentPack) {
215
+ BootstrapDialog.show({
216
+ title: $L.get('New license'),
217
+ type: BootstrapDialog.TYPE_WARNING,
218
+ message: $L.get('Please, select a pack before to create a new license'),
219
+ buttons: [{
220
+ label: 'OK',
221
+ action: function(dialog) {
222
+ dialog.close();
223
+ }
224
+ }]
225
+ });
226
+ return;
227
+ }
228
+
229
+ $scope.isNew = true;
230
+ $scope.showForm = true;
231
+ $scope.license = {
232
+ pack_id: $scope.currentPack.id
233
+ }
234
+ setTimeout(function() {
235
+ $('#licenseForm * #code').focus();
236
+ }, 0);
237
+ }
238
+
239
+ $scope.editLicense = function(selectedlicense) {
240
+ $scope.isNew = false;
241
+ $scope.showForm = true;
242
+ $scope.license = selectedlicense;
243
+ setTimeout(function() {
244
+ $('#licenseForm * #code').focus();
245
+ }, 0);
246
+ }
247
+
248
+ $scope.deletelicense = function(selectedlicense) {
249
+ $scope.showForm = false;
250
+ BootstrapDialog.confirm($L.get("The license '{0}' will be deleted, are you sure?", selectedlicense.code), function(result){
251
+ if(result) {
252
+ var promise = licenseResource.remove({}, {id: selectedlicense.id}).$promise;
253
+ promise.then(function(data) {
254
+ $scope.selectlicense(null);
255
+ $scope.licenses = licenseResource.query({packId: $scope.currentPack.id});
256
+ toaster.pop('success', Catalogs.getName(), $L.get("License '{0}' deleted successfully", selectedlicense.code));
257
+ },function(error) {
258
+ console.log(error);
259
+ toaster.pop('error', Catalogs.getName(), $L.get("Error deleting license, reason: {0}. Details: {1}", $L.get(HTTP_ERRORS[error.status]), error.headers('X-SECURIS-ERROR')), 10000);
260
+ });
261
+ }
262
+ });
263
+ $scope.isNew = false;
264
+ }
265
+
266
+
267
+ $scope.cancel = function() {
268
+ $scope.showForm = false;
269
+ }
270
+
271
+ $scope.showStatus = function(lic) {
272
+
273
+ }
274
+ $scope.showStatusComplete = function(license) {
275
+
276
+ }
277
+ $scope.isActionVisible = function(actionMask, lic) {
278
+
279
+ }
280
+
281
+ } ]);
282
+
163283 })();
securis/src/main/resources/static/js/main.js
....@@ -21,26 +21,27 @@
2121 }
2222 });
2323
24
- m.factory('securisHttpInterceptor', function($q, $location, $store) {
24
+ m.factory('securisHttpInterceptor', function($q, $location, $store, toaster) {
2525 var isUnauthorizedAccess = function(rejection) {
26
- console.log('rejection -----------------------');
27
- console.log(rejection);
2826 return rejection.status === 401 /* Unauthorized */;
2927 }
3028 return {
3129 'request': function(config) {
32
- var la = $store.get('last_access');
33
- var now = new Date().getTime();
34
- if (la !== null) {
35
- if (now > (la + 1800000)) { // Session timeout is 1/2 hour
36
- $store.clear();
37
- $location.path('/login');
38
- BootstrapDialog.alert('Session has expired');
39
- } else {
40
- console.log('Last access recent');
41
- }
42
- }
43
- $store.set('last_access', now);
30
+ var token = $store.get('token');
31
+ if (token) {
32
+ var la = $store.get('last_access');
33
+ var now = new Date().getTime();
34
+ if (la !== null) {
35
+ if (now > (la + 1800000)) { // Session timeout is 1/2 hour
36
+ $store.clear();
37
+ $location.path('/login');
38
+ toaster.pop('warning', 'Session has expired', null, 4000);
39
+ } else {
40
+ console.log('Last access recent');
41
+ }
42
+ }
43
+ $store.set('last_access', now);
44
+ }
4445 return config || $q.when(config);
4546 },
4647 'responseError': function(rejection) {
securis/src/main/resources/static/licenses.html
....@@ -145,7 +145,7 @@
145145 </tr>
146146 </thead>
147147 <tbody>
148
- <tr ng-repeat="p in packs | filter:searchText" ng-dblclick="editPack(p)" ng-class="{success: currentPackId === p.id}" ng-click="selectPack(p.id)">
148
+ <tr ng-repeat="p in packs | filter:searchText" ng-dblclick="editPack(p)" ng-class="{success: currentPack.id === p.id}" ng-click="selectPack(p)">
149149 <td style="white-space: nowrap;" ng-bind="p.code"></td>
150150 <td ng-bind="ellipsis(p.organization_name, 20)" title="{{pack.organization_name}}" ></td>
151151 <td ng-bind="p.application_name"></td>
....@@ -164,8 +164,8 @@
164164
165165 </div>
166166
167
- <div id="licenses_section" class="col-md-6" >
168
- <nav class="navbar navbar-default navbar-static-top" ng-disabled="currentPackId === null">
167
+ <div id="licenses_section" class="col-md-6" ng-controller="LicensesCtrl">
168
+ <nav class="navbar navbar-default navbar-static-top" ng-disabled="!currentPack">
169169 <!-- Brand and toggle get grouped for better mobile display -->
170170 <div class="navbar-header success">
171171 <a class="navbar-brand" i18n>Licenses</a>
....@@ -175,9 +175,9 @@
175175 <div class="collapse navbar-collapse"
176176 id="bs-example-navbar-collapse-1">
177177 <ul class="nav navbar-nav">
178
- <li><a i18n ng-click="editNewLicense()"><span class="glyphicon glyphicon-plus"></span>
178
+ <li><a i18n ng-click="newLicense()"><span class="glyphicon glyphicon-plus"></span>
179179 New</a></li>
180
- <li><a i18n ng-click="cancelEditionLicense()"> <span
180
+ <li><a i18n ng-click="cancel()"> <span
181181 class="glyphicon glyphicon-ban-circle"></span> Cancel
182182 </a></li>
183183 </ul>
....@@ -191,12 +191,179 @@
191191 </div>
192192 </nav>
193193
194
- <div ng-if="currentPackId === null" class="well well-lg">
194
+ <div ng-if="!currentPack" class="well well-lg">
195195 <h4 i18n>No pack selected</h4>
196196 <p i18n>Please, select a pack to manage its licenses</p>
197197 </div>
198198
199
- <div class="panel panel-default" ng-if="currentPackId !== null">
199
+ <div ng-if="currentPack" class="panel panel-default animate-show ng-hide" ng-show="showForm">
200
+ <form role="form" class="form-horizontal " name="licenseForm" id="licenseForm" ng-submit="save()" >
201
+ <div class="form-group" ng-if="!isNew">
202
+ <label class="col-md-3 control-label" >ID</label>
203
+ <div class="col-md-8">
204
+ <p class="form-control-static" ng-bind="license.id"></p>
205
+ </div>
206
+ </div>
207
+ <div class="form-group" >
208
+ <label class="col-md-3 control-label" for="pack_id" i18n>Pack</label>
209
+ <div class="col-md-8">
210
+ <p class="form-control-static" ng-bind="currentPack.code"></p>
211
+ <input type="hidden" id="pack_id" name="pack_id" ng-model="license.pack_id" />
212
+ </div>
213
+ </div>
214
+ <div class="form-group" >
215
+ <label class="col-md-3 control-label" for="code" i18n>Code</label>
216
+ <div class="col-md-8">
217
+ <input type="string" id="code" name="code" placeholder="" class="form-control" ng-model="license.code" ng-required="mandatory.code" ng-maxlength="{{maxlength.code}}" />
218
+ <div class="alert inline-alert alert-warning" ng-show="licenseForm.code.$invalid">
219
+ <span class="glyphicon glyphicon-warning-sign"></span>
220
+ <span ng-show="licenseForm.code.$error.maxlength" ng-bind="maxlengthErrorMsg('Code', maxlength.code)"></span>
221
+ <span ng-show="licenseForm.code.$error.required" ng-bind="mandatoryFieldErrorMsg('Code')"></span>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ <div class="form-group" ng-if="!isNew">
226
+ <label class="col-md-3 control-label" i18n>Status</label>
227
+ <div class="col-md-8">
228
+ <p class="form-control-static" ng-bind="showStatusComplete(license)"></p>
229
+ </div>
230
+ </div>
231
+
232
+ <div class="form-group" >
233
+ <label class="col-md-3 control-label" for="full_name" i18n>User full name</label>
234
+ <div class="col-md-8">
235
+ <input type="string" id="full_name" name="full_name" placeholder="" class="form-control" ng-model="license.full_name" ng-required="mandatory.full_name" />
236
+ <div class="alert inline-alert alert-warning" ng-show="licenseForm.full_name.$invalid">
237
+ <span class="glyphicon glyphicon-warning-sign"></span>
238
+ <span ng-show="licenseForm.full_name.$error.maxlength" ng-bind="maxlengthErrorMsg('User full name', maxlength.full_name)"></span>
239
+ <span ng-show="licenseForm.full_name.$error.required" ng-bind="mandatoryFieldErrorMsg('User full name')"></span>
240
+ </div>
241
+ </div>
242
+ </div>
243
+
244
+ <div class="form-group" >
245
+ <label class="col-md-3 control-label" for="email" i18n>User email</label>
246
+ <div class="col-md-8">
247
+ <input type="email" id="email" name="email" placeholder="" class="form-control" ng-model="license.email" ng-required="mandatory.email" />
248
+ <div class="alert inline-alert alert-warning" ng-show="licenseForm.email.$invalid">
249
+ <span class="glyphicon glyphicon-warning-sign"></span>
250
+ <span ng-show="licenseForm.email.$error.email" ng-bind="'Please, write a valid email address'"></span>
251
+ <span ng-show="licenseForm.email.$error.maxlength" ng-bind="maxlengthErrorMsg('User email', maxlength.email)"></span>
252
+ <span ng-show="licenseForm.email.$error.required" ng-bind="mandatoryFieldErrorMsg('User email')"></span>
253
+ </div>
254
+ </div>
255
+ </div>
256
+
257
+ <div class="form-group" ng-if="isNew || !license.request_data" >
258
+ <label class="col-md-3 control-label" for="request_data" i18n>Request data</label>
259
+ <div class="col-md-8">
260
+ <textarea type="string" id="request_data" name="request_data" placeholder=""
261
+ class="form-control" ng-model="license.request_data" rows="2" ng-required="mandatory.request_data" ng-maxlength="{{maxlength.request_data}}"></textarea>
262
+ <div class="alert inline-alert alert-warning" ng-show="licenseForm.request_data.$invalid">
263
+ <span class="glyphicon glyphicon-warning-sign"></span>
264
+ <span ng-show="licenseForm.request_data.$error.maxlength" ng-bind="maxlengthErrorMsg('Request data', maxlength.request_data)"></span>
265
+ <span ng-show="licenseForm.request_data.$error.required" ng-bind="mandatoryFieldErrorMsg('Request data')"></span>
266
+ </div>
267
+ </div>
268
+ </div>
269
+
270
+ <div class="form-group" >
271
+ <label class="col-md-3 control-label" for="comments" i18n>Comments</label>
272
+ <div class="col-md-8">
273
+ <textarea type="string" id="comments" name="comments" placeholder=""
274
+ class="form-control" ng-model="license.comments" rows="2" ng-required="mandatory.comments" ng-maxlength="{{maxlength.comments}}"></textarea>
275
+ <div class="alert inline-alert alert-warning" ng-show="licenseForm.comments.$invalid">
276
+ <span class="glyphicon glyphicon-warning-sign"></span>
277
+ <span ng-show="licenseForm.comments.$error.maxlength" ng-bind="maxlengthErrorMsg('Comments', maxlength.comments)"></span>
278
+ <span ng-show="licenseForm.comments.$error.required" ng-bind="mandatoryFieldErrorMsg('comments')"></span>
279
+ </div>
280
+ </div>
281
+ </div>
282
+
283
+ <div class="form-group" ng-if="!isNew && license.request_data">
284
+ <label class="col-md-3 control-label" i18n>Request data</label>
285
+ <div class="col-md-8">
286
+ <pre class="form-control-static" ng-bind="license.request_data | json"></pre>
287
+ </div>
288
+ </div>
289
+
290
+ <div class="form-group" ng-if="!isNew && license.license_data">
291
+ <label class="col-md-3 control-label" i18n >License file</label>
292
+ <div class="col-md-8">
293
+ <p class="form-control-static" ng-bind="license.license_data"></p>
294
+ <button id="downloadLicense" class="btn btn-xs btn-link" ng-click="downloadLicense(license)">
295
+ <span i18n class="glyphicon glyphicon-download"></span>
296
+ </button>
297
+ </div>
298
+ </div>
299
+
300
+ <div class="form-group" ng-if="!isNew">
301
+ <label class="col-md-3 control-label" i18n>Created by</label>
302
+ <div class="col-md-8">
303
+ <p class="form-control-static" ng-bind="license.created_by_name"></p>
304
+ </div>
305
+ </div>
306
+
307
+ <div class="form-group" ng-if="!isNew && license.canceled_by_name">
308
+ <label class="col-md-3 control-label" >Canceled by</label>
309
+ <div class="col-md-8">
310
+ <p class="form-control-static" ng-bind="license.canceled_by_name"></p>
311
+ </div>
312
+ </div>
313
+
314
+ <div class="form-group" ng-if="!isNew">
315
+ <label class="col-md-3 control-label" i18n>Creation date</label>
316
+ <div class="col-md-8">
317
+ <p class="form-control-static" ng-bind="license.creationTimestamp | date:'medium'"></p>
318
+ </div>
319
+ </div>
320
+
321
+ <div class="form-group" ng-if="!isNew">
322
+ <label class="col-md-3 control-label" i18n >Modification date</label>
323
+ <div class="col-md-8">
324
+ <p class="form-control-static" ng-bind="license.modificationTimestamp | date:'medium'"></p>
325
+ </div>
326
+ </div>
327
+
328
+ <div class="form-group" ng-if="!isNew && license.activationTimestamp">
329
+ <label class="col-md-3 control-label" i18n >Activation date</label>
330
+ <div class="col-md-8">
331
+ <p class="form-control-static" ng-bind="license.activationTimestamp | date:'medium'"></p>
332
+ </div>
333
+ </div>
334
+
335
+ <div class="form-group" ng-if="!isNew && license.sendTimestamp">
336
+ <label class="col-md-3 control-label" i18n >Send date</label>
337
+ <div class="col-md-8">
338
+ <p class="form-control-static" ng-bind="license.sendTimestamp | date:'medium'"></p>
339
+ </div>
340
+ </div>
341
+
342
+ <div class="form-group" ng-if="!isNew && license.cancelationTimestamp">
343
+ <label class="col-md-3 control-label" i18n >Cancelation date</label>
344
+ <div class="col-md-8">
345
+ <p class="form-control-static" ng-bind="license.cancelationTimestamp | date:'medium'"></p>
346
+ </div>
347
+ </div>
348
+
349
+ <div class="form-group" ng-if="!isNew && license.lastAccessTimestamp">
350
+ <label class="col-md-3 control-label" i18n>Last access date</label>
351
+ <div class="col-md-8">
352
+ <p class="form-control-static" ng-bind="license.lastAccessTimestamp | date:'medium'"></p>
353
+ </div>
354
+ </div>
355
+
356
+ <div class="form-group">
357
+ <div class="col-md-offset-3 col-md-10" id="saveContainer">
358
+ <button id="save" type="submit" class="btn btn-primary" >
359
+ <span i18n class="glyphicon glyphicon-floppy-disk"></span> Save
360
+ </button>
361
+ </div>
362
+ </div>
363
+ </form>
364
+ </div>
365
+
366
+ <div class="panel panel-default" ng-if="currentPack">
200367 <div class="panel-heading">
201368 <span i18n>Licenses for pack: </span>{{currentPack.code}}
202369 <span style="color: lightgreen;" class="badge pull-right" ng-bind="currentPack.lic_available || 0"></span>
....@@ -217,19 +384,20 @@
217384 <tbody>
218385 <tr ng-repeat="lic in licenses | filter:searchLicenseText" ng-dblclick="editLicense(lic)" >
219386 <td style="white-space: nowrap;" ng-bind="lic.code"></td>
220
- <td ng-bind="ellipsis(lic.user_fullname, 20)" title="{{lic.user_fullname}}" ></td>
221
- <td ng-bind="ellipsis(lic.user_email, 30)" title="{{lic.user_email}}" ></td>
222
- <td ng-bind="lic.status"></td>
387
+ <td ng-bind="ellipsis(lic.full_name, 20)" title="{{lic.full_name}}" ></td>
388
+ <td ng-bind="ellipsis(lic.email, 30)" title="{{lic.email}}" ></td>
389
+ <td ng-bind="showStatus(lic.status)"></td>
223390 <td>
224391 <div class="dropdown">
225392 <a class="dropdown-toggle" data-toggle="dropdown" >
226393 <span class="glyphicon glyphicon-align-justify"></span> <span class="caret"></span>
227394 </a>
228395 <ul class="dropdown-menu">
229
- <li><a ng-click="editLicense(lic)"><span class="glyphicon glyphicon-pencil"></span> <span i18n>Edit</span></a></li>
230
- <li><a ng-click="activateLicense(lic)"><span class="glyphicon glyphicon-check"></span> <span i18n>Activate</span></a></li>
231
- <li><a ng-click="sendEmail(lic)"><span class="glyphicon glyphicon-send"></span> <span i18n>Send email</span></a></li>
232
- <li><a ng-click="editLicense(lic)"><span class="glyphicon glyphicon-remove"></span> <span i18n>Remove</span></a></li>
396
+ <li ng-if="isActionVisible(1, lic)"><a ng-click="downloadLicense(lic)"><span class="glyphicon glyphicon-download"></span> <span i18n>Download</span></a></li>
397
+ <li ng-if="isActionVisible(2, lic)"><a ng-click="editLicense(lic)"><span class="glyphicon glyphicon-pencil"></span> <span i18n>Edit</span></a></li>
398
+ <li ng-if="isActionVisible(4, lic)"><a ng-click="activateLicense(lic)"><span class="glyphicon glyphicon-check"></span> <span i18n>Activate</span></a></li>
399
+ <li ng-if="isActionVisible(8, lic)"><a ng-click="sendEmail(lic)"><span class="glyphicon glyphicon-send"></span> <span i18n>Send email</span></a></li>
400
+ <li ng-if="isActionVisible(16, lic)"><a ng-click="deleteLicense(lic)"><span class="glyphicon glyphicon-remove"></span> <span i18n>Remove</span></a></li>
233401 </ul>
234402 </div>
235403 </td>