/* * Copyright @ 2013 CurisTEC, S.A.S. All Rights Reserved. */ package net.curisit.securis.db; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinTable; import jakarta.persistence.ManyToMany; import jakarta.persistence.NamedQueries; import jakarta.persistence.NamedQuery; import jakarta.persistence.Table; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; /** * User *
* Application user with bitmask-based roles and membership in organizations
* and applications. Exposes convenience JSON properties to fetch/set related
* entity IDs without fetching full entities.
*
* Mapping details:
* - Table: user
* - ManyToMany organizations via user_organization
* - ManyToMany applications via user_application
* - Named queries: list-users, get-user, auth-user, delete-all-users
*
* Roles:
* - Stored as integer bitmask; see {@link Rol}.
*
* @author JRA
* Last reviewed by JRA on Oct 5, 2025.
*/
@JsonAutoDetect
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Entity
@Table(name = "user")
@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"),
@NamedQuery(name = "auth-user", query = "SELECT u FROM User u where u.username = :username and u.password = :password"),
@NamedQuery(name = "delete-all-users", query = "delete FROM User u")
})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/** Username (PK). */
@Id
private String username;
/** Password hash/string (not exposed in JSON). */
private String password;
@JsonProperty("first_name")
@Column(name = "first_name")
private String firstName;
@JsonProperty("last_name")
@Column(name = "last_name")
private String lastName;
/** Roles bitmask (see Rol constants). */
private int roles;
@Column(name = "last_login")
private Date lastLogin;
@Column(name = "modification_timestamp")
private Date modificationTimestamp;
@Column(name = "creation_timestamp")
@JsonProperty("creation_timestamp")
private Date creationTimestamp;
private String lang;
private String email;
@JsonIgnore
@ManyToMany
@JoinTable(name = "user_organization",
joinColumns = { @JoinColumn(name = "username", referencedColumnName = "username") },
inverseJoinColumns = { @JoinColumn(name = "organization_id", referencedColumnName = "id") })
private Set
* Return username (PK).
*
* @return username
*/
public String getUsername() { return username; }
/**
* setUsername
* Set username (PK).
*
* @param username
*/
public void setUsername(String username) { this.username = username; }
/**
* getDummyPassword
* Forces password to be omitted in JSON responses.
*
* @return always null
*/
@JsonProperty("password")
public String getDummyPassword() { return null; }
/**
* getPassword
* Return raw/hashed password (internal use).
*
* @return password
*/
public String getPassword() { return password; }
/**
* setPassword
* Set raw/hashed password (internal use).
*
* @param password
*/
public void setPassword(String password) { this.password = password; }
/**
* getRoles
* Return list of individual role flags contained in the bitmask.
*
* @return list of role integers or null if no roles
*/
public List
* Set the roles bitmask from a list of role flags.
*
* @param roles list of flags
*/
public void setRoles(List
* Return first name.
*
* @return firstName
*/
public String getFirstName() { return firstName; }
/**
* setFirstName
* Set first name.
*
* @param firstName
*/
public void setFirstName(String firstName) { this.firstName = firstName; }
/**
* getLastName
* Return last name.
*
* @return lastName
*/
public String getLastName() { return lastName; }
/**
* setLastName
* Set last name.
*
* @param lastName
*/
public void setLastName(String lastName) { this.lastName = lastName; }
/**
* getLastLogin
* Return last login timestamp.
*
* @return lastLogin
*/
public Date getLastLogin() { return lastLogin; }
/**
* setLastLogin
* Set last login timestamp.
*
* @param lastLogin
*/
public void setLastLogin(Date lastLogin) { this.lastLogin = lastLogin; }
/**
* getModificationTimestamp
* Return modification timestamp.
*
* @return modificationTimestamp
*/
public Date getModificationTimestamp() { return modificationTimestamp; }
/**
* setModificationTimestamp
* Set modification timestamp.
*
* @param modificationTimestamp
*/
public void setModificationTimestamp(Date modificationTimestamp) { this.modificationTimestamp = modificationTimestamp; }
/**
* getCreationTimestamp
* Return creation timestamp.
*
* @return creationTimestamp
*/
public Date getCreationTimestamp() { return creationTimestamp; }
/**
* setCreationTimestamp
* Set creation timestamp.
*
* @param creationTimestamp
*/
public void setCreationTimestamp(Date creationTimestamp) { this.creationTimestamp = creationTimestamp; }
/**
* getLang
* Return preferred language.
*
* @return lang
*/
public String getLang() { return lang; }
/**
* setLang
* Set preferred language.
*
* @param lang
*/
public void setLang(String lang) { this.lang = lang; }
/**
* getEmail
* Return email address.
*
* @return email
*/
public String getEmail() { return email; }
/**
* setEmail
* Set email address.
*
* @param email
*/
public void setEmail(String email) { this.email = email; }
/**
* getOrganizations
* Return organizations (entity set).
*
* @return organizations
*/
public Set
* Set organizations (entity set).
*
* @param organizations
*/
public void setOrganizations(Set
* Return applications (entity set).
*
* @return applications
*/
public Set
* Set applications (entity set).
*
* @param applications
*/
public void setApplications(Set
* Replace organizations from a list of org IDs.
*
* @param orgsIds
*/
@JsonProperty("organizations_ids")
public void setOrgsIds(List
* Expose organization IDs.
*
* @return orgsIds
*/
@JsonProperty("organizations_ids")
public Set
* Replace applications from a collection of app IDs.
*
* @param appIds
*/
@JsonProperty("applications_ids")
public void setAppsIds(Collection
* Expose application IDs.
*
* @return appsIds
*/
@JsonProperty("applications_ids")
public Set
* Compute full organization scope including descendants.
*
* @return set of org IDs (may be null when no organizations)
*/
@JsonIgnore
public Set
* Compute application scope (direct associations only).
*
* @return set of application IDs (may be null when no applications)
*/
@JsonIgnore
public Set
* Walk organization hierarchy to include all descendants.
*
* @param list current level orgs
* @param orgIds accumulator of ids
*/
private void includeAllOrgs(Set
* Get the string describing the current object
*
* @return object string
*/
@Override
public String toString() {
return "{User: " + username + " Name: " + firstName + " " + lastName + ", last login: " + lastLogin + "}";
}
/**
* Rol
*
* Bitmask constants for user roles. Each constant must occupy a distinct bit.
*/
public static class Rol {
public static final int ADVANCE = 0x01;
public static final int ADMIN = 0x02;
public static final int BASIC = 0x04;
public static final int API_CLIENT= 0x80;
public static final int[] ALL = new int[] { ADVANCE, ADMIN, BASIC, API_CLIENT };
}
}