• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SpiNNakerManchester / JavaSpiNNaker / 12815918623

16 Jan 2025 07:10PM UTC coverage: 37.265% (-0.03%) from 37.299%
12815918623

push

github

rowleya
Try without ignore here?

8824 of 23679 relevant lines covered (37.27%)

1.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/model/UserRecord.java
1
/*
2
 * Copyright (c) 2021 The University of Manchester
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package uk.ac.manchester.spinnaker.alloc.model;
17

18
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NON_PRIVATE;
19
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
20
import static java.util.Objects.isNull;
21
import static java.util.Objects.nonNull;
22
import static uk.ac.manchester.spinnaker.alloc.security.TrustLevel.USER;
23

24
import java.net.URI;
25
import java.time.Instant;
26
import java.util.Map;
27

28
import javax.validation.constraints.AssertTrue;
29
import javax.validation.constraints.NotBlank;
30
import javax.validation.constraints.NotNull;
31
import javax.validation.constraints.Null;
32

33
import com.fasterxml.jackson.annotation.JsonAutoDetect;
34
import com.fasterxml.jackson.annotation.JsonIgnore;
35
import com.fasterxml.jackson.annotation.JsonInclude;
36
import com.google.errorprone.annotations.CanIgnoreReturnValue;
37

38
import uk.ac.manchester.spinnaker.alloc.db.Row;
39
import uk.ac.manchester.spinnaker.alloc.db.SQLQueries;
40
import uk.ac.manchester.spinnaker.alloc.security.TrustLevel;
41
import uk.ac.manchester.spinnaker.utils.UsedInJavadocOnly;
42

43
/**
44
 * The description and model of a user. POJO class. Some things are stated to be
45
 * not settable despite having setters; they're settable <em>in instances of
46
 * this class</em> but the service itself will not respect being asked to change
47
 * them.
48
 */
49
@JsonAutoDetect(setterVisibility = NON_PRIVATE)
50
public final class UserRecord {
51
        private Integer userId;
52

53
        private String userName;
54

55
        private String password;
56

57
        private Boolean hasPassword;
58

59
        private Boolean enabled;
60

61
        private Boolean locked;
62

63
        private TrustLevel trustLevel;
64

65
        private Instant lastSuccessfulLogin;
66

67
        private Instant lastFailedLogin;
68

69
        private String openIdSubject;
70

71
        private boolean isInternal;
72

73
        private Map<String, URI> groups;
74

75
        /** Create an empty instance. */
76
        public UserRecord() {
×
77
        }
×
78

79
        /**
80
         * Inflate the result of a {@link SQLQueries#GET_USER_DETAILS} query (or
81
         * anything else that includes the same columns) into an object. Doesn't
82
         * include inflating the groups that the user is a member of.
83
         *
84
         * @param row
85
         *            The row with the result.
86
         */
87
        @UsedInJavadocOnly(SQLQueries.class)
88
        public UserRecord(Row row) {
×
89
                try {
90
                        setUserId(row.getInt("user_id"));
×
91
                        setUserName(row.getString("user_name"));
×
92
                        setHasPassword(row.getBoolean("has_password"));
×
93
                        setTrustLevel(row.getEnum("trust_level", TrustLevel.class));
×
94
                        setEnabled(!row.getBoolean("disabled"));
×
95
                        setLocked(row.getBoolean("locked"));
×
96
                        setLastSuccessfulLogin(
×
97
                                        row.getInstant("last_successful_login_timestamp"));
×
98
                        setLastFailedLogin(row.getInstant("last_fail_timestamp"));
×
99
                        setOpenIdSubject(row.getString("openid_subject"));
×
100
                        isInternal = row.getBoolean("is_internal");
×
101
                } finally {
102
                        // I mean it!
103
                        setPassword(null);
×
104
                }
105
        }
×
106

107
        /**
108
         * @return The user identifier. Read-only; cannot be set by the service.
109
         */
110
        @JsonInclude(NON_NULL)
111
        @Null
112
        public Integer getUserId() {
113
                return userId;
×
114
        }
115

116
        /**
117
         * @param userId
118
         *            The user identifier. Read-only within the administration
119
         *            interface; cannot be set by the service.
120
         */
121
        public void setUserId(Integer userId) {
122
                this.userId = userId;
×
123
        }
×
124

125
        /**
126
         * @return The user's username.
127
         */
128
        @NotBlank
129
        public String getUserName() {
130
                return userName;
×
131
        }
132

133
        /**
134
         * @param userName
135
         *            The user's username.
136
         */
137
        public void setUserName(String userName) {
138
                this.userName = userName;
×
139
        }
×
140

141
        /**
142
         * @return The user's unencrypted password. <em>Never</em> returned by the
143
         *         service, but may be written.
144
         */
145
        @JsonInclude(NON_NULL)
146
        public String getPassword() {
147
                return password;
×
148
        }
149

150
        /**
151
         * @param password
152
         *            The user's unencrypted password. <em>Never</em> returned by
153
         *            the service, but may be written.
154
         */
155
        public void setPassword(String password) {
156
                this.password = password;
×
157
        }
×
158

159
        /**
160
         * @return Whether the user has a password set. If they don't, they'll have
161
         *         to log in by other mechanisms (e.g., HBP/EBRAINS OpenID Connect).
162
         */
163
        public Boolean getHasPassword() {
164
                return hasPassword;
×
165
        }
166

167
        /**
168
         * @param hasPassword
169
         *            Whether the user has a password set. If they don't, they'll
170
         *            have to log in by other mechanisms (e.g., HBP/EBRAINS OpenID
171
         *            Connect).
172
         */
173
        public void setHasPassword(Boolean hasPassword) {
174
                this.hasPassword = hasPassword;
×
175
        }
×
176

177
        /**
178
         * @return Whether this account is enabled. Disabled accounts
179
         *         <em>cannot</em> log into the service until explicitly enabled.
180
         */
181
        public Boolean getEnabled() {
182
                return enabled;
×
183
        }
184

185
        /**
186
         * @param enabled
187
         *            Whether this account is enabled. Disabled accounts
188
         *            <em>cannot</em> log into the service until explicitly enabled.
189
         */
190
        public void setEnabled(Boolean enabled) {
191
                this.enabled = enabled;
×
192
        }
×
193

194
        /**
195
         * @return Whether this account is temporarily locked. Locked accounts
196
         *         should unlock automatically after 24 hours. Can be explicitly set
197
         *         to {@code false} to force an unlock.
198
         */
199
        public Boolean getLocked() {
200
                return locked;
×
201
        }
202

203
        /**
204
         * @param locked
205
         *            Whether this account is temporarily locked. Locked accounts
206
         *            should unlock automatically after 24 hours. Can be explicitly
207
         *            set to {@code false} to force an unlock.
208
         */
209
        public void setLocked(Boolean locked) {
210
                this.locked = locked;
×
211
        }
×
212

213
        /**
214
         * @return The permissions of the account.
215
         */
216
        @NotNull(message = "a trust level must be given")
217
        public TrustLevel getTrustLevel() {
218
                return trustLevel;
×
219
        }
220

221
        /**
222
         * @param trustLevel
223
         *            The permissions of the account.
224
         */
225
        public void setTrustLevel(TrustLevel trustLevel) {
226
                this.trustLevel = trustLevel;
×
227
        }
×
228

229
        /**
230
         * @return The time that the last successful login was. Read-only; cannot be
231
         *         set via the admin API.
232
         */
233
        @JsonInclude(NON_NULL)
234
        @Null
235
        public Instant getLastSuccessfulLogin() {
236
                return lastSuccessfulLogin;
×
237
        }
238

239
        void setLastSuccessfulLogin(Instant timestamp) {
240
                this.lastSuccessfulLogin = timestamp;
×
241
        }
×
242

243
        /**
244
         * @return The time that the last failed login was. Read-only; cannot be set
245
         *         via the admin API.
246
         */
247
        @JsonInclude(NON_NULL)
248
        @Null
249
        public Instant getLastFailedLogin() {
250
                return lastFailedLogin;
×
251
        }
252

253
        void setLastFailedLogin(Instant timestamp) {
254
                this.lastFailedLogin = timestamp;
×
255
        }
×
256

257
        /**
258
         * Note that no API that sets a user's information using a
259
         * {@link UserRecord} allows setting the groups that user is a member of at
260
         * the same time.
261
         *
262
         * @return The groups that the user is a member of. May be {@code null} if
263
         *         this information is not being reported.
264
         */
265
        public Map<String, URI> getGroups() {
266
                return groups;
×
267
        }
268

269
        /**
270
         * @param groups
271
         *            The groups that the user is a member of.
272
         */
273
        public void setGroups(Map<String, URI> groups) {
274
                this.groups = groups;
×
275
        }
×
276

277
        /** @return The OpenID subject that this user relates to, if known. */
278
        public String getOpenIdSubject() {
279
                return openIdSubject;
×
280
        }
281

282
        /**
283
         * @param subject
284
         *            The OpenID subject that this user relates to.
285
         */
286
        public void setOpenIdSubject(String subject) {
287
                this.openIdSubject = subject;
×
288
        }
×
289

290
        /** @return Whether this is an internal user. */
291
        public boolean isInternal() {
292
                return isInternal;
×
293
        }
294

295
        /**
296
         * @param internal
297
         *            Whether this is an internal user.
298
         */
299
        public void setInternal(boolean internal) {
300
                this.isInternal = internal;
×
301
        }
×
302

303
        @JsonIgnore
304
        private boolean isPasswordSetForAccount() {
305
                return nonNull(hasPassword) && hasPassword;
×
306
        }
307

308
        /**
309
         * @return Whether this represents a request to use external authentication
310
         *         (instead of just not setting the password).
311
         */
312
        @JsonIgnore
313
        public boolean isExternallyAuthenticated() {
314
                return !isInternal;
×
315
        }
316

317
        @JsonIgnore
318
        boolean isPasswordSet() {
319
                return nonNull(password) && !password.isBlank();
×
320
        }
321

322
        @AssertTrue(message = "only set a password for non-OpenID accounts")
323
        @JsonIgnore
324
        boolean isAuthenticationSane() {
325
                if (isInternal) {
×
326
                        return isPasswordSet() || isPasswordSetForAccount();
×
327
                } else {
328
                        return !isPasswordSet();
×
329
                }
330
        }
331

332
        /**
333
         * Forces correct shrouding of information.
334
         *
335
         * @return the object (for convenience)
336
         */
337
        @CanIgnoreReturnValue
338
        public UserRecord sanitise() {
339
                // Make SURE that the password doesn't go back
340
                if (nonNull(password)) {
×
341
                        hasPassword = true;
×
342
                        password = null;
×
343
                }
344
                // Never need to send the userId back
345
                userId = null;
×
346
                return this;
×
347
        }
348

349
        /**
350
         * Set up some defaults used when a user is being created.
351
         */
352
        public void initCreationDefaults() {
353
                setUserId(null);
×
354
                if (isNull(getTrustLevel())) {
×
355
                        setTrustLevel(USER);
×
356
                }
357
                if (isNull(getEnabled())) {
×
358
                        setEnabled(true);
×
359
                }
360
                if (isNull(getLocked())) {
×
361
                        setLocked(false);
×
362
                }
363
        }
×
364
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc