1
2
3
4
5
6 package org.tailormap.api.persistence;
7
8 import com.fasterxml.jackson.annotation.JsonIgnore;
9 import com.fasterxml.jackson.annotation.JsonProperty;
10 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
11 import jakarta.persistence.Column;
12 import jakarta.persistence.Entity;
13 import jakarta.persistence.EntityListeners;
14 import jakarta.persistence.Id;
15 import jakarta.persistence.JoinColumn;
16 import jakarta.persistence.JoinTable;
17 import jakarta.persistence.ManyToMany;
18 import jakarta.persistence.Table;
19 import jakarta.persistence.Version;
20 import jakarta.validation.constraints.Email;
21 import jakarta.validation.constraints.NotNull;
22 import jakarta.validation.constraints.Pattern;
23 import jakarta.validation.constraints.Size;
24 import java.time.ZoneId;
25 import java.time.ZonedDateTime;
26 import java.util.ArrayList;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Set;
30 import org.hibernate.annotations.Type;
31 import org.hibernate.envers.Audited;
32 import org.tailormap.api.persistence.helper.AdminAdditionalPropertyHelper;
33 import org.tailormap.api.persistence.json.AdminAdditionalProperty;
34 import org.tailormap.api.persistence.listener.EntityEventPublisher;
35 import org.tailormap.api.util.Constants;
36 import org.tailormap.api.util.TMPasswordDeserializer;
37
38 @Audited
39 @Entity
40 @Table(name = "users")
41 @EntityListeners(EntityEventPublisher.class)
42 public class User {
43
44 @Id
45 @Pattern(regexp = Constants.NAME_REGEX, message = "User" + Constants.NAME_REGEX_INVALID_MESSAGE) private String username;
46
47 @Version
48 private Long version;
49
50 @NotNull @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
51 @JsonDeserialize(using = TMPasswordDeserializer.class)
52
53
54 @Size(max = (8 + 60))
55 private String password;
56
57 @Email private String email;
58
59 private String name;
60
61 private String organisation;
62
63 @Column(columnDefinition = "text")
64 private String notes;
65
66 @Column(columnDefinition = "timestamp with time zone")
67 private ZonedDateTime validUntil;
68
69 private boolean enabled = true;
70
71 @Type(value = io.hypersistence.utils.hibernate.type.json.JsonBinaryType.class)
72 @Column(columnDefinition = "jsonb")
73 private List<AdminAdditionalProperty> additionalProperties = new ArrayList<>();
74
75 @ManyToMany
76 @JoinTable(
77 name = "user_groups",
78 joinColumns = @JoinColumn(name = "username"),
79 inverseJoinColumns = @JoinColumn(name = "group_name"))
80 private Set<Group> groups = new HashSet<>();
81
82 public String getUsername() {
83 return username;
84 }
85
86 public User setUsername(String username) {
87 this.username = username;
88 return this;
89 }
90
91 public Long getVersion() {
92 return version;
93 }
94
95 public User setVersion(Long version) {
96 this.version = version;
97 return this;
98 }
99
100 public String getPassword() {
101 return password;
102 }
103
104 public User setPassword(String passwordHash) {
105 this.password = passwordHash;
106 return this;
107 }
108
109 public String getEmail() {
110 return email;
111 }
112
113 public User setEmail(String email) {
114 this.email = email;
115 return this;
116 }
117
118 public String getName() {
119 return name;
120 }
121
122 public User setName(String name) {
123 this.name = name;
124 return this;
125 }
126
127 public String getOrganisation() {
128 return organisation;
129 }
130
131 public User setOrganisation(String organisation) {
132 this.organisation = organisation;
133 return this;
134 }
135
136 public String getNotes() {
137 return notes;
138 }
139
140 public User setNotes(String notes) {
141 this.notes = notes;
142 return this;
143 }
144
145 public List<AdminAdditionalProperty> getAdditionalProperties() {
146 return additionalProperties;
147 }
148
149 public User setAdditionalProperties(List<AdminAdditionalProperty> additionalProperties) {
150 this.additionalProperties = additionalProperties;
151 return this;
152 }
153
154 public Set<Group> getGroups() {
155 return groups;
156 }
157
158 public User setGroups(Set<Group> groups) {
159 this.groups = groups;
160 return this;
161 }
162
163 public Set<String> getGroupNames() {
164 return groups.stream().map(Group::getName).collect(java.util.stream.Collectors.toSet());
165 }
166
167 public ZonedDateTime getValidUntil() {
168 return validUntil;
169 }
170
171 public User setValidUntil(ZonedDateTime validUntil) {
172 this.validUntil = validUntil;
173 return this;
174 }
175
176 public boolean isEnabled() {
177 return enabled;
178 }
179
180 public User setEnabled(boolean enabled) {
181 this.enabled = enabled;
182 return this;
183 }
184
185 public void addOrUpdateAdminProperty(String key, Object value, boolean isPublic) {
186 AdminAdditionalPropertyHelper.addOrUpdateAdminProperty(additionalProperties, key, value, isPublic);
187 }
188
189
190
191
192
193
194 @JsonIgnore
195 public boolean isEnabledAndValidUntil() {
196 return enabled && (validUntil == null || validUntil.isAfter(ZonedDateTime.now(ZoneId.systemDefault())));
197 }
198 }