Joaquín Reñé
2025-10-07 146a0fb8b0e90f9196e569152f649baf60d6cc8f
securis/src/main/java/net/curisit/securis/db/User.java
....@@ -1,3 +1,6 @@
1
+/*
2
+* Copyright @ 2013 CurisTEC, S.A.S. All Rights Reserved.
3
+*/
14 package net.curisit.securis.db;
25
36 import java.io.Serializable;
....@@ -27,275 +30,426 @@
2730 import com.fasterxml.jackson.annotation.JsonProperty;
2831
2932 /**
30
- * Entity implementation class for Entity: Users
31
- *
32
- */
33
+* User
34
+* <p>
35
+* Application user with bitmask-based roles and membership in organizations
36
+* and applications. Exposes convenience JSON properties to fetch/set related
37
+* entity IDs without fetching full entities.
38
+*
39
+* Mapping details:
40
+* - Table: user
41
+* - ManyToMany organizations via user_organization
42
+* - ManyToMany applications via user_application
43
+* - Named queries: list-users, get-user, auth-user, delete-all-users
44
+*
45
+* Roles:
46
+* - Stored as integer bitmask; see {@link Rol}.
47
+*
48
+* @author JRA
49
+* Last reviewed by JRA on Oct 5, 2025.
50
+*/
3351 @JsonAutoDetect
3452 @JsonInclude(Include.NON_NULL)
3553 @JsonIgnoreProperties(ignoreUnknown = true)
3654 @Entity
3755 @Table(name = "user")
38
-@NamedQueries({ @NamedQuery(name = "list-users", query = "SELECT u FROM User u"), @NamedQuery(name = "get-user", query = "SELECT u FROM User u where u.username = :username"),
39
- @NamedQuery(name = "auth-user", query = "SELECT u FROM User u where u.username = :username and u.password = :password"),
40
- @NamedQuery(name = "delete-all-users", query = "delete FROM User u") })
56
+@NamedQueries({
57
+ @NamedQuery(name = "list-users", query = "SELECT u FROM User u"),
58
+ @NamedQuery(name = "get-user", query = "SELECT u FROM User u where u.username = :username"),
59
+ @NamedQuery(name = "auth-user", query = "SELECT u FROM User u where u.username = :username and u.password = :password"),
60
+ @NamedQuery(name = "delete-all-users", query = "delete FROM User u")
61
+})
4162 public class User implements Serializable {
4263
43
- private static final long serialVersionUID = 1L;
64
+ private static final long serialVersionUID = 1L;
4465
45
- @Id
46
- private String username;
66
+ /** Username (PK). */
67
+ @Id
68
+ private String username;
4769
48
- private String password;
70
+ /** Password hash/string (not exposed in JSON). */
71
+ private String password;
4972
50
- @JsonProperty(value = "first_name")
51
- @Column(name = "first_name")
52
- private String firstName;
73
+ @JsonProperty("first_name")
74
+ @Column(name = "first_name")
75
+ private String firstName;
5376
54
- @JsonProperty(value = "last_name")
55
- @Column(name = "last_name")
56
- private String lastName;
77
+ @JsonProperty("last_name")
78
+ @Column(name = "last_name")
79
+ private String lastName;
5780
58
- private int roles;
81
+ /** Roles bitmask (see Rol constants). */
82
+ private int roles;
5983
60
- @Column(name = "last_login")
61
- private Date lastLogin;
84
+ @Column(name = "last_login")
85
+ private Date lastLogin;
6286
63
- @Column(name = "modification_timestamp")
64
- private Date modificationTimestamp;
87
+ @Column(name = "modification_timestamp")
88
+ private Date modificationTimestamp;
6589
66
- @Column(name = "creation_timestamp")
67
- @JsonProperty("creation_timestamp")
68
- private Date creationTimestamp;
90
+ @Column(name = "creation_timestamp")
91
+ @JsonProperty("creation_timestamp")
92
+ private Date creationTimestamp;
6993
70
- private String lang;
94
+ private String lang;
95
+ private String email;
7196
72
- private String email;
97
+ @JsonIgnore
98
+ @ManyToMany
99
+ @JoinTable(name = "user_organization",
100
+ joinColumns = { @JoinColumn(name = "username", referencedColumnName = "username") },
101
+ inverseJoinColumns = { @JoinColumn(name = "organization_id", referencedColumnName = "id") })
102
+ private Set<Organization> organizations;
73103
74
- @JsonIgnore
75
- @ManyToMany
76
- @JoinTable(name = "user_organization", //
77
- joinColumns = { @JoinColumn(name = "username", referencedColumnName = "username") }, //
78
- inverseJoinColumns = { @JoinColumn(name = "organization_id", referencedColumnName = "id") } //
79
- )
80
- private Set<Organization> organizations;
104
+ @JsonIgnore
105
+ @ManyToMany
106
+ @JoinTable(name = "user_application",
107
+ joinColumns = { @JoinColumn(name = "username", referencedColumnName = "username") },
108
+ inverseJoinColumns = { @JoinColumn(name = "application_id", referencedColumnName = "id") })
109
+ private Set<Application> applications;
81110
82
- @JsonIgnore
83
- @ManyToMany
84
- @JoinTable(name = "user_application", //
85
- joinColumns = { @JoinColumn(name = "username", referencedColumnName = "username") }, //
86
- inverseJoinColumns = { @JoinColumn(name = "application_id", referencedColumnName = "id") } //
87
- )
88
- private Set<Application> applications;
111
+ // -------- Getters & setters --------
89112
90
- public String getUsername() {
91
- return username;
92
- }
113
+ /**
114
+ * getUsername<p>
115
+ * Return username (PK).
116
+ *
117
+ * @return username
118
+ */
119
+ public String getUsername() { return username; }
93120
94
- public void setUsername(String username) {
95
- this.username = username;
96
- }
121
+ /**
122
+ * setUsername<p>
123
+ * Set username (PK).
124
+ *
125
+ * @param username
126
+ */
127
+ public void setUsername(String username) { this.username = username; }
97128
98
- @JsonProperty("password")
99
- public String getDummyPassword() {
100
- return null;
101
- }
129
+ /**
130
+ * getDummyPassword<p>
131
+ * Forces password to be omitted in JSON responses.
132
+ *
133
+ * @return always null
134
+ */
135
+ @JsonProperty("password")
136
+ public String getDummyPassword() { return null; }
102137
103
- public String getPassword() {
104
- return password;
105
- }
138
+ /**
139
+ * getPassword<p>
140
+ * Return raw/hashed password (internal use).
141
+ *
142
+ * @return password
143
+ */
144
+ public String getPassword() { return password; }
106145
107
- public void setPassword(String password) {
108
- this.password = password;
109
- }
146
+ /**
147
+ * setPassword<p>
148
+ * Set raw/hashed password (internal use).
149
+ *
150
+ * @param password
151
+ */
152
+ public void setPassword(String password) { this.password = password; }
110153
111
- public List<Integer> getRoles() {
112
- if (roles == 0) {
113
- return null;
114
- }
115
- List<Integer> aux = new ArrayList<>();
116
- for (int rol : Rol.ALL) {
117
- if ((roles & rol) != 0) { // Each rol is a number with only 1 bit ==
118
- // 1 in binary representation
119
- aux.add(rol);
120
- }
121
- }
122
- return aux;
123
- }
154
+ /**
155
+ * getRoles<p>
156
+ * Return list of individual role flags contained in the bitmask.
157
+ *
158
+ * @return list of role integers or null if no roles
159
+ */
160
+ public List<Integer> getRoles() {
161
+ if (roles == 0) return null;
162
+ List<Integer> aux = new ArrayList<>();
163
+ for (int rol : Rol.ALL) {
164
+ if ((roles & rol) != 0) aux.add(rol);
165
+ }
166
+ return aux;
167
+ }
124168
125
- public void setRoles(List<Integer> roles) {
126
- this.roles = 0;
127
- if (roles != null) {
128
- for (Integer rol : roles) {
129
- this.roles |= rol;
130
- }
131
- }
132
- }
169
+ /**
170
+ * setRoles<p>
171
+ * Set the roles bitmask from a list of role flags.
172
+ *
173
+ * @param roles list of flags
174
+ */
175
+ public void setRoles(List<Integer> roles) {
176
+ this.roles = 0;
177
+ if (roles != null) {
178
+ for (Integer rol : roles) this.roles |= rol;
179
+ }
180
+ }
133181
134
- public String getFirstName() {
135
- return firstName;
136
- }
182
+ /**
183
+ * getFirstName<p>
184
+ * Return first name.
185
+ *
186
+ * @return firstName
187
+ */
188
+ public String getFirstName() { return firstName; }
137189
138
- public void setFirstName(String firstName) {
139
- this.firstName = firstName;
140
- }
190
+ /**
191
+ * setFirstName<p>
192
+ * Set first name.
193
+ *
194
+ * @param firstName
195
+ */
196
+ public void setFirstName(String firstName) { this.firstName = firstName; }
141197
142
- public String getLastName() {
143
- return lastName;
144
- }
198
+ /**
199
+ * getLastName<p>
200
+ * Return last name.
201
+ *
202
+ * @return lastName
203
+ */
204
+ public String getLastName() { return lastName; }
145205
146
- public void setLastName(String lastName) {
147
- this.lastName = lastName;
148
- }
206
+ /**
207
+ * setLastName<p>
208
+ * Set last name.
209
+ *
210
+ * @param lastName
211
+ */
212
+ public void setLastName(String lastName) { this.lastName = lastName; }
149213
150
- public Date getLastLogin() {
151
- return lastLogin;
152
- }
214
+ /**
215
+ * getLastLogin<p>
216
+ * Return last login timestamp.
217
+ *
218
+ * @return lastLogin
219
+ */
220
+ public Date getLastLogin() { return lastLogin; }
153221
154
- public void setLastLogin(Date lastLogin) {
155
- this.lastLogin = lastLogin;
156
- }
222
+ /**
223
+ * setLastLogin<p>
224
+ * Set last login timestamp.
225
+ *
226
+ * @param lastLogin
227
+ */
228
+ public void setLastLogin(Date lastLogin) { this.lastLogin = lastLogin; }
157229
158
- public Date getModificationTimestamp() {
159
- return modificationTimestamp;
160
- }
230
+ /**
231
+ * getModificationTimestamp<p>
232
+ * Return modification timestamp.
233
+ *
234
+ * @return modificationTimestamp
235
+ */
236
+ public Date getModificationTimestamp() { return modificationTimestamp; }
161237
162
- public void setModificationTimestamp(Date modificationTimestamp) {
163
- this.modificationTimestamp = modificationTimestamp;
164
- }
238
+ /**
239
+ * setModificationTimestamp<p>
240
+ * Set modification timestamp.
241
+ *
242
+ * @param modificationTimestamp
243
+ */
244
+ public void setModificationTimestamp(Date modificationTimestamp) { this.modificationTimestamp = modificationTimestamp; }
165245
166
- public Date getCreationTimestamp() {
167
- return creationTimestamp;
168
- }
246
+ /**
247
+ * getCreationTimestamp<p>
248
+ * Return creation timestamp.
249
+ *
250
+ * @return creationTimestamp
251
+ */
252
+ public Date getCreationTimestamp() { return creationTimestamp; }
169253
170
- public void setCreationTimestamp(Date creationTimestamp) {
171
- this.creationTimestamp = creationTimestamp;
172
- }
254
+ /**
255
+ * setCreationTimestamp<p>
256
+ * Set creation timestamp.
257
+ *
258
+ * @param creationTimestamp
259
+ */
260
+ public void setCreationTimestamp(Date creationTimestamp) { this.creationTimestamp = creationTimestamp; }
173261
174
- @Override
175
- public String toString() {
176
- return "{User: " + username + " Name: " + firstName + " " + lastName + ", last login: " + lastLogin + "}";
177
- }
262
+ /**
263
+ * getLang<p>
264
+ * Return preferred language.
265
+ *
266
+ * @return lang
267
+ */
268
+ public String getLang() { return lang; }
178269
179
- public String getLang() {
180
- return lang;
181
- }
270
+ /**
271
+ * setLang<p>
272
+ * Set preferred language.
273
+ *
274
+ * @param lang
275
+ */
276
+ public void setLang(String lang) { this.lang = lang; }
182277
183
- public void setLang(String lang) {
184
- this.lang = lang;
185
- }
278
+ /**
279
+ * getEmail<p>
280
+ * Return email address.
281
+ *
282
+ * @return email
283
+ */
284
+ public String getEmail() { return email; }
186285
187
- public Set<Organization> getOrganizations() {
188
- return organizations;
189
- }
286
+ /**
287
+ * setEmail<p>
288
+ * Set email address.
289
+ *
290
+ * @param email
291
+ */
292
+ public void setEmail(String email) { this.email = email; }
190293
191
- public void setOrganizations(Set<Organization> organizations) {
192
- this.organizations = organizations;
193
- }
294
+ /**
295
+ * getOrganizations<p>
296
+ * Return organizations (entity set).
297
+ *
298
+ * @return organizations
299
+ */
300
+ public Set<Organization> getOrganizations() { return organizations; }
194301
195
- public Set<Application> getApplications() {
196
- return applications;
197
- }
302
+ /**
303
+ * setOrganizations<p>
304
+ * Set organizations (entity set).
305
+ *
306
+ * @param organizations
307
+ */
308
+ public void setOrganizations(Set<Organization> organizations) { this.organizations = organizations; }
198309
199
- public void setApplications(Set<Application> applications) {
200
- this.applications = applications;
201
- }
310
+ /**
311
+ * getApplications<p>
312
+ * Return applications (entity set).
313
+ *
314
+ * @return applications
315
+ */
316
+ public Set<Application> getApplications() { return applications; }
202317
203
- @JsonProperty("organizations_ids")
204
- public void setOrgsIds(List<Integer> orgsIds) {
205
- organizations = new HashSet<>();
206
- for (Integer orgid : orgsIds) {
207
- Organization o = new Organization();
208
- o.setId(orgid);
209
- organizations.add(o);
210
- }
211
- }
318
+ /**
319
+ * setApplications<p>
320
+ * Set applications (entity set).
321
+ *
322
+ * @param applications
323
+ */
324
+ public void setApplications(Set<Application> applications) { this.applications = applications; }
212325
213
- @JsonProperty("organizations_ids")
214
- public Set<Integer> getOrgsIds() {
215
- if (organizations == null) {
216
- return null;
217
- }
218
- Set<Integer> ids = new HashSet<>();
219
- for (Organization org : organizations) {
220
- ids.add(org.getId());
221
- }
222
- return ids;
223
- }
326
+ // -------- JSON helpers for related IDs --------
224327
225
- @JsonProperty("applications_ids")
226
- public void setAppsIds(Collection<Integer> appIds) {
227
- applications = new HashSet<>();
228
- for (Integer appid : appIds) {
229
- Application a = new Application();
230
- a.setId(appid);
231
- applications.add(a);
232
- }
233
- }
328
+ /**
329
+ * setOrgsIds<p>
330
+ * Replace organizations from a list of org IDs.
331
+ *
332
+ * @param orgsIds
333
+ */
334
+ @JsonProperty("organizations_ids")
335
+ public void setOrgsIds(List<Integer> orgsIds) {
336
+ organizations = new HashSet<>();
337
+ for (Integer orgid : orgsIds) {
338
+ Organization o = new Organization();
339
+ o.setId(orgid);
340
+ organizations.add(o);
341
+ }
342
+ }
234343
235
- @JsonProperty("applications_ids")
236
- public Set<Integer> getAppsIds() {
237
- if (applications == null) {
238
- return null;
239
- }
240
- Set<Integer> ids = new HashSet<>();
241
- for (Application app : applications) {
242
- ids.add(app.getId());
243
- }
244
- return ids;
245
- }
344
+ /**
345
+ * getOrgsIds<p>
346
+ * Expose organization IDs.
347
+ *
348
+ * @return orgsIds
349
+ */
350
+ @JsonProperty("organizations_ids")
351
+ public Set<Integer> getOrgsIds() {
352
+ if (organizations == null) return null;
353
+ Set<Integer> ids = new HashSet<>();
354
+ for (Organization org : organizations) ids.add(org.getId());
355
+ return ids;
356
+ }
246357
247
- @JsonIgnore
248
- public Set<Integer> getAllOrgsIds() {
249
- if (organizations == null) {
250
- return null;
251
- }
252
- Set<Integer> ids = new HashSet<>();
253
- includeAllOrgs(this.organizations, ids);
254
- return ids;
255
- }
358
+ /**
359
+ * setAppsIds<p>
360
+ * Replace applications from a collection of app IDs.
361
+ *
362
+ * @param appIds
363
+ */
364
+ @JsonProperty("applications_ids")
365
+ public void setAppsIds(Collection<Integer> appIds) {
366
+ applications = new HashSet<>();
367
+ for (Integer appid : appIds) {
368
+ Application a = new Application();
369
+ a.setId(appid);
370
+ applications.add(a);
371
+ }
372
+ }
256373
257
- @JsonIgnore
258
- public Set<Integer> getAllAppsIds() {
259
- if (applications == null) {
260
- return null;
261
- }
262
- Set<Integer> ids = this.applications.parallelStream().map(app -> app.getId()).collect(Collectors.toSet());
374
+ /**
375
+ * getAppsIds<p>
376
+ * Expose application IDs.
377
+ *
378
+ * @return appsIds
379
+ */
380
+ @JsonProperty("applications_ids")
381
+ public Set<Integer> getAppsIds() {
382
+ if (applications == null) return null;
383
+ Set<Integer> ids = new HashSet<>();
384
+ for (Application app : applications) ids.add(app.getId());
385
+ return ids;
386
+ }
263387
264
- return ids;
265
- }
388
+ // -------- Derived scopes --------
266389
267
- /**
268
- * Walk into the organization hierarchy to include all descendants
269
- *
270
- * @param list
271
- * @param orgIds
272
- */
273
- private void includeAllOrgs(Set<Organization> list, Set<Integer> orgIds) {
274
- for (Organization org : list) {
275
- orgIds.add(org.getId());
276
- includeAllOrgs(org.getChildOrganizations(), orgIds);
277
- }
278
- }
390
+ /**
391
+ * getAllOrgsIds<p>
392
+ * Compute full organization scope including descendants.
393
+ *
394
+ * @return set of org IDs (may be null when no organizations)
395
+ */
396
+ @JsonIgnore
397
+ public Set<Integer> getAllOrgsIds() {
398
+ if (organizations == null) return null;
399
+ Set<Integer> ids = new HashSet<>();
400
+ includeAllOrgs(this.organizations, ids);
401
+ return ids;
402
+ }
279403
280
- public String getEmail() {
281
- return email;
282
- }
404
+ /**
405
+ * getAllAppsIds<p>
406
+ * Compute application scope (direct associations only).
407
+ *
408
+ * @return set of application IDs (may be null when no applications)
409
+ */
410
+ @JsonIgnore
411
+ public Set<Integer> getAllAppsIds() {
412
+ if (applications == null) return null;
413
+ return this.applications.parallelStream().map(Application::getId).collect(Collectors.toSet());
414
+ }
283415
284
- public void setEmail(String email) {
285
- this.email = email;
286
- }
416
+ /**
417
+ * includeAllOrgs<p>
418
+ * Walk organization hierarchy to include all descendants.
419
+ *
420
+ * @param list current level orgs
421
+ * @param orgIds accumulator of ids
422
+ */
423
+ private void includeAllOrgs(Set<Organization> list, Set<Integer> orgIds) {
424
+ for (Organization org : list) {
425
+ orgIds.add(org.getId());
426
+ includeAllOrgs(org.getChildOrganizations(), orgIds);
427
+ }
428
+ }
287429
288
- /**
289
- * Numeric rol mask. Be aware to use different bit position for each role
290
- *
291
- * @author rob
292
- */
293
- public static class Rol {
294
- public static final int ADVANCE = 0x01;
295
- public static final int ADMIN = 0x02;
296
- public static final int BASIC = 0x04;
297
- public static final int API_CLIENT = 0x80;
298
- public static final int[] ALL = new int[] { ADVANCE, ADMIN, BASIC, API_CLIENT };
299
- }
430
+ /**
431
+ * toString<p>
432
+ * Get the string describing the current object
433
+ *
434
+ * @return object string
435
+ */
436
+ @Override
437
+ public String toString() {
438
+ return "{User: " + username + " Name: " + firstName + " " + lastName + ", last login: " + lastLogin + "}";
439
+ }
300440
441
+
442
+ /**
443
+ * Rol
444
+ * <p>
445
+ * Bitmask constants for user roles. Each constant must occupy a distinct bit.
446
+ */
447
+ public static class Rol {
448
+ public static final int ADVANCE = 0x01;
449
+ public static final int ADMIN = 0x02;
450
+ public static final int BASIC = 0x04;
451
+ public static final int API_CLIENT= 0x80;
452
+ public static final int[] ALL = new int[] { ADVANCE, ADMIN, BASIC, API_CLIENT };
453
+ }
301454 }
455
+