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

openmrs / openmrs-core / 30399987753

28 Jul 2026 09:16PM UTC coverage: 66.493% (+0.2%) from 66.313%
30399987753

push

github

ibacher
Fix Mockito inline mocks on JDK 8 and 11 (#6403)

24796 of 37291 relevant lines covered (66.49%)

0.67 hits per line

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

86.89
/api/src/main/java/org/openmrs/api/context/UserContext.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.api.context;
11

12
import java.io.Serializable;
13
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.Collections;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Locale;
19
import java.util.Objects;
20
import java.util.Set;
21
import java.util.concurrent.atomic.AtomicBoolean;
22

23
import org.apache.commons.lang3.StringUtils;
24
import org.openmrs.Location;
25
import org.openmrs.PrivilegeListener;
26
import org.openmrs.Role;
27
import org.openmrs.User;
28
import org.openmrs.UserSessionListener;
29
import org.openmrs.UserSessionListener.Event;
30
import org.openmrs.UserSessionListener.Status;
31
import org.openmrs.api.APIAuthenticationException;
32
import org.openmrs.api.LocationService;
33
import org.openmrs.api.cache.RolePrivilegeCache;
34
import org.openmrs.api.cache.RolePrivileges;
35
import org.openmrs.util.LocaleUtility;
36
import org.openmrs.util.OpenmrsConstants;
37
import org.openmrs.util.RoleConstants;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

41
/**
42
 * Represents an OpenMRS <code>User Context</code> which stores the current user information. Only
43
 * one <code>User</code> may be authenticated within a UserContext at any given time. The
44
 * UserContext should not be accessed directly, but rather used through the <code>Context</code>.
45
 * This class should be kept light-weight. There is one instance of this class per user that is
46
 * logged into the system.
47
 *
48
 * @see org.openmrs.api.context.Context
49
 */
50
public class UserContext implements Serializable {
51
        
52
        private static final long serialVersionUID = -806631231941890648L;
53
        
54
        /**
55
         * Logger - shared by entire class
56
         */
57
        private static final Logger log = LoggerFactory.getLogger(UserContext.class);
1✔
58
        
59
        /**
60
         * Guards the one-time warning emitted when the role privilege cache component cannot be obtained
61
         * outside of a context refresh. Static so the warning is emitted once across all user contexts
62
         * rather than once per session.
63
         */
64
        private static final AtomicBoolean rolePrivilegeCacheUnavailableWarned = new AtomicBoolean(false);
1✔
65

66
        /**
67
         * User object containing details about the authenticated user
68
         */
69
        private User user = null;
1✔
70
        
71
        /**
72
         * User's permission proxies
73
         */
74
        private final List<String> proxies = Collections.synchronizedList(new ArrayList<>());
1✔
75
        
76
        /**
77
         * User's locale
78
         */
79
        private Locale locale = null;
1✔
80
        
81
        /**
82
         * Cached Role given to all authenticated users
83
         */
84
        private Role authenticatedRole = null;
1✔
85
        
86
        /**
87
         * Cache Role given to all users
88
         */
89
        private Role anonymousRole = null;
1✔
90
        
91
        /**
92
         * User's defined location
93
         */
94
        private Integer locationId;
95
        
96
        /**
97
         * The authentication scheme for this user
98
         */
99
        private final AuthenticationScheme authenticationScheme;
100
        
101
        /**
102
         * Creates a user context based on the provided auth. scheme.
103
         *
104
         * @param authenticationScheme The auth. scheme that applies for this user context.
105
         * @since 2.3.0
106
         */
107
        public UserContext(AuthenticationScheme authenticationScheme) {
1✔
108
                this.authenticationScheme = authenticationScheme;
1✔
109
        }
1✔
110
        
111
        /**
112
         * Authenticate user with the provided credentials. The authentication scheme must be Spring wired, see {@link Context#getAuthenticationScheme()}.
113
         *
114
         * @param credentials The credentials to use to authenticate
115
         * @return The authenticated client information
116
         * @throws ContextAuthenticationException if authentication fails
117
         * @since 2.3.0
118
         */
119
        public Authenticated authenticate(Credentials credentials)
120
                throws ContextAuthenticationException {
121
                
122
                log.debug("Authenticating client '{}' with scheme '{}'", credentials.getClientName(),
1✔
123
                        credentials.getAuthenticationScheme());
1✔
124
                
125
                Authenticated authenticated = null;
1✔
126
                try {
127
                        authenticated = authenticationScheme.authenticate(credentials);
1✔
128
                        this.user = authenticated.getUser();
1✔
129
                        notifyUserSessionListener(this.user, Event.LOGIN, Status.SUCCESS);
1✔
130
                }
131
                catch (ContextAuthenticationException e) {
1✔
132
                        User loggingInUser = new User();
1✔
133
                        loggingInUser.setUsername(credentials.getClientName());
1✔
134
                        notifyUserSessionListener(loggingInUser, Event.LOGIN, Status.FAIL);
1✔
135
                        throw e;
1✔
136
                }
1✔
137
                
138
                setUserLocation(true);
1✔
139
                setUserLocale(true);
1✔
140
                
141
                log.debug("Authenticated as: {}", this.user);
1✔
142
                
143
                return authenticated;
1✔
144
        }
145
        
146
        /**
147
         * Refresh the authenticated user object in this UserContext. This should be used when updating
148
         * information in the database about the current user and it needs to be reflecting in the
149
         * (cached) {@link #getAuthenticatedUser()} User object.
150
         *
151
         * @since 1.5
152
         */
153
        public void refreshAuthenticatedUser() {
154
                log.debug("Refreshing authenticated user");
1✔
155
                
156
                if (user != null) {
1✔
157
                        user = Context.getUserService().getUser(user.getUserId());
1✔
158
                        //update the stored location in the user's session
159
                        setUserLocation(false);
1✔
160
                        setUserLocale(false);
1✔
161
                }
162
        }
1✔
163
        
164
        /**
165
         * Change current authentication to become another user. (You can only do this if you're already
166
         * authenticated as a superuser.)
167
         *
168
         * @param systemId
169
         * @return The new user that this context has been set to. (null means no change was made)
170
         * @throws ContextAuthenticationException
171
         */
172
        public User becomeUser(String systemId) throws ContextAuthenticationException {
173
                if (!Context.getAuthenticatedUser().isSuperUser()) {
1✔
174
                        throw new APIAuthenticationException("You must be a superuser to assume another user's identity");
×
175
                }
176
                
177
                log.debug("Turning the authenticated user into user with systemId: {}", systemId);
1✔
178
                
179
                User userToBecome = Context.getUserService().getUserByUsername(systemId);
1✔
180
                
181
                if (userToBecome == null) {
1✔
182
                        throw new ContextAuthenticationException("User not found with systemId: " + systemId);
×
183
                }
184
                
185
                // hydrate the user object
186
                if (userToBecome.getAllRoles() != null) {
1✔
187
                        userToBecome.getAllRoles().size();
1✔
188
                }
189
                
190
                if (userToBecome.getUserProperties() != null) {
1✔
191
                        userToBecome.getUserProperties().size();
1✔
192
                }
193
                
194
                if (userToBecome.getPrivileges() != null) {
1✔
195
                        userToBecome.getPrivileges().size();
1✔
196
                }
197
                
198
                this.user = userToBecome;
1✔
199
                
200
                //update the user's location and locale
201
                setUserLocation(false);
1✔
202
                setUserLocale(false);
1✔
203
                
204
                log.debug("Becoming user: {}", user);
1✔
205
                
206
                return userToBecome;
1✔
207
        }
208
        
209
        /**
210
         * @return "active" user who has been authenticated, otherwise <code>null</code>
211
         */
212
        public User getAuthenticatedUser() {
213
                return user;
1✔
214
        }
215
        
216
        /**
217
         * @return true if user has been authenticated in this UserContext
218
         */
219
        public boolean isAuthenticated() {
220
                return user != null;
1✔
221
        }
222
        
223
        /**
224
         * logs out the "active" (authenticated) user within this UserContext
225
         *
226
         * @see #authenticate
227
         */
228
        public void logout() {
229
                log.debug("setting user to null on logout");
1✔
230
                notifyUserSessionListener(user, Event.LOGOUT, Status.SUCCESS);
1✔
231
                user = null;
1✔
232
                locationId = null;
1✔
233
                locale = null;
1✔
234
                proxies.clear();
1✔
235
        }
1✔
236
        
237
        /**
238
         * Gives the given privilege to all calls to hasPrivilege. This method was visualized as being
239
         * used as follows (try/finally is important):
240
         *
241
         * <pre>
242
         * try {
243
         *   Context.addProxyPrivilege(&quot;AAA&quot;);
244
         *   Context.get*Service().methodRequiringAAAPrivilege();
245
         * }
246
         * finally {
247
         *   Context.removeProxyPrivilege(&quot;AAA&quot;);
248
         * }
249
         * </pre>
250
         *
251
         * @param privilege to give to users
252
         */
253
        public void addProxyPrivilege(String privilege) {
254
                addProxyPrivilege(new String[] {privilege});
1✔
255
        }
1✔
256
        
257
        /**
258
         * Will remove one instance of privilege from the privileges that are currently proxied
259
         *
260
         * @param privilege Privilege to remove in string form
261
         */
262
        public void removeProxyPrivilege(String privilege) {
263
                removeProxyPrivilege(new String[] {privilege});
1✔
264
        }
1✔
265
        
266
        /**
267
         * Adds one or more privileges to the list of privileges that that {@link #hasPrivilege(String)} will
268
         * regard as available regardless of whether the user would otherwise have the privilege.
269
         * <p/>
270
         * This is useful for situations where a system process may need access to some piece of data that the
271
         * user would not otherwise have access to, like a GlobalProperty. <strong>This facility should not be
272
         * used to return data to the user that they otherwise would be unable to see.</strong>
273
         * <p/>
274
         * The expected usage is:
275
         * <p/>
276
         * <pre>{@code
277
         * try {
278
         *   Context.addProxyPrivilege(&quot;AAA&quot;);
279
         *   Context.get*Service().methodRequiringAAAPrivilege();
280
         * }
281
         * finally {
282
         *   Context.removeProxyPrivilege(&quot;AAA&quot;);
283
         * }}
284
         * </pre>
285
         * <p/>
286
         *
287
         * @param privileges privileges to add in string form
288
         * @see #hasPrivilege(String)
289
         * @see #removeProxyPrivilege(String...)
290
         */
291
        public void addProxyPrivilege(String... privileges) {
292
                if (privileges == null || Arrays.stream(privileges).anyMatch(Objects::isNull)) {
1✔
293
                        throw new IllegalArgumentException("UserContext.addProxyPrivilege does not accept null privileges");
1✔
294
                }
295
                
296
                for (String privilege : privileges) {
1✔
297
                        log.debug("Adding proxy privilege: {}", privilege);
1✔
298
                        proxies.add(privilege);
1✔
299
                }
300
        }
1✔
301
        
302
        /**
303
         * Removes one or more privileges to the list of privileges that that {@link #hasPrivilege(String)} will
304
         * regard as available regardless of whether the user would otherwise have the privilege.
305
         * <p/>
306
         * This is the compliment for {@link #addProxyPrivilege(String...)} to clean-up the context.
307
         * <p/>
308
         *
309
         * @param privileges privileges to remove in string form
310
         * @see #hasPrivilege(String)
311
         * @see #addProxyPrivilege(String...)
312
         */
313
        public void removeProxyPrivilege(String... privileges) {
314
                if (privileges == null || Arrays.stream(privileges).allMatch(Objects::isNull)) {
1✔
315
                        return;
1✔
316
                }
317
                
318
                for (String privilege : privileges) {
1✔
319
                        if (privilege != null) {
1✔
320
                                log.debug("Removing privilege: {}", privilege);
1✔
321
                                proxies.remove(privilege);
1✔
322
                        }
323
                }
324
        }
1✔
325
        
326
        /**
327
         * @param locale new locale for this context
328
         */
329
        public void setLocale(Locale locale) {
330
                this.locale = locale;
1✔
331
        }
1✔
332
        
333
        /**
334
         * @return current locale for this context
335
         */
336
        public Locale getLocale() {
337
                if (locale == null) {
1✔
338
                        // don't cache default locale - allows recognition of changed default at login page
339
                        return LocaleUtility.getDefaultLocale();
1✔
340
                }
341
                
342
                return locale;
1✔
343
        }
344
        
345
        /**
346
         * Gets all the roles for the (un)authenticated user. Anonymous and Authenticated roles are
347
         * appended if necessary
348
         *
349
         * @return all expanded roles for a user
350
         * @throws Exception
351
         */
352
        public Set<Role> getAllRoles() throws Exception {
353
                return getAllRoles(getAuthenticatedUser());
×
354
        }
355
        
356
        /**
357
         * Gets all the roles for a user. Anonymous and Authenticated roles are appended if necessary
358
         *
359
         * @param user
360
         * @return all expanded roles for a user
361
         * <strong>Should</strong> not fail with null user
362
         * <strong>Should</strong> add anonymous role to all users
363
         * <strong>Should</strong> add authenticated role to all authenticated users
364
         * <strong>Should</strong> return same roles as user getAllRoles method
365
         */
366
        public Set<Role> getAllRoles(User user) throws Exception {
367
                Set<Role> roles = new HashSet<>();
×
368
                
369
                // add the Anonymous Role
370
                roles.add(getAnonymousRole());
×
371
                
372
                // add the Authenticated role
373
                if (getAuthenticatedUser() != null && getAuthenticatedUser().equals(user)) {
×
374
                        roles.addAll(user.getAllRoles());
×
375
                        roles.add(getAuthenticatedRole());
×
376
                }
377
                
378
                return roles;
×
379
        }
380
        
381
        /**
382
         * Tests whether the currently authenticated user has a particular privilege
383
         *
384
         * @param privilege The privilege to check if it's available
385
         * @return true if authenticated user has given privilege
386
         * <strong>Should</strong> authorize if authenticated user has specified privilege
387
         * <strong>Should</strong> authorize if authenticated role has specified privilege
388
         * <strong>Should</strong> authorize if proxied user has specified privilege
389
         * <strong>Should</strong> authorize if anonymous user has specified privilege
390
         * <strong>Should</strong> not authorize if authenticated user does not have specified privilege
391
         * <strong>Should</strong> not authorize if authenticated role does not have specified privilege
392
         * <strong>Should</strong> not authorize if proxied user does not have specified privilege
393
         * <strong>Should</strong> not authorize if anonymous user does not have specified privilege
394
         */
395
        public boolean hasPrivilege(String privilege) {
396
                return hasPrivilege(privilege, true);
1✔
397
        }
398

399
        /**
400
         * Tests whether the current user has a particular privilege, optionally excluding proxy privileges.
401
         * <p>
402
         * Passing <code>false</code> resolves the privilege only from the user's roles (and the anonymous
403
         * and authenticated roles), ignoring any {@link #addProxyPrivilege(String...) proxy privileges}.
404
         * This is intended for per-resource access checks that must reflect the user's actual granted roles
405
         * and must not be satisfied by a proxy privilege added merely to invoke the surrounding service
406
         * method. Role privileges are still resolved authoritatively (from the role privilege cache),
407
         * unlike {@link User#hasPrivilege(String)} which reads a potentially stale in-memory role graph.
408
         *
409
         * @param privilege The privilege to check if it's available
410
         * @param includeProxyPrivileges whether proxy privileges may satisfy the check
411
         * @return true if the current user has the given privilege
412
         * @since 3.0.0, 2.9.0, 2.8.9
413
         */
414
        public boolean hasPrivilege(String privilege, boolean includeProxyPrivileges) {
415
                if (includeProxyPrivileges) {
1✔
416
                        log.debug("Checking '{}' against proxies: {}", privilege, proxies);
1✔
417
                        // check proxied privileges
418
                        for (String s : new ArrayList<>(proxies)) {
1✔
419
                                if (s.equals(privilege)) {
1✔
420
                                        notifyPrivilegeListeners(getAuthenticatedUser(), privilege, true);
1✔
421
                                        return true;
1✔
422
                                }
423
                        }
1✔
424
                }
425

426
                boolean hasPrivilege = resolvePrivilege(privilege);
1✔
427
                notifyPrivilegeListeners(getAuthenticatedUser(), privilege, hasPrivilege);
1✔
428
                return hasPrivilege;
1✔
429
        }
430

431
        /**
432
         * Resolves whether the current user (authenticated or anonymous) holds the given privilege by
433
         * consulting the per-role privilege cache instead of recursively re-expanding the role graph on
434
         * every call. Proxy privileges are handled separately by {@link #hasPrivilege(String)}.
435
         *
436
         * @param privilege the privilege to check
437
         * @return true if the privilege is granted
438
         */
439
        private boolean resolvePrivilege(String privilege) {
440
                RolePrivilegeCache cache = getRolePrivilegeCache();
1✔
441

442
                // if a user has logged in, check their privileges
443
                if (isAuthenticated()) {
1✔
444
                        // All authenticated users have the "" (empty) privilege, matching User.hasPrivilege.
445
                        if (StringUtils.isEmpty(privilege)) {
1✔
446
                                return true;
1✔
447
                        }
448

449
                        User authenticatedUser = getAuthenticatedUser();
1✔
450
                        if (authenticatedUser.getRoles() != null) {
1✔
451
                                for (Role role : authenticatedUser.getRoles()) {
1✔
452
                                        if (roleGrants(cache, role, privilege)) {
1✔
453
                                                return true;
1✔
454
                                        }
455
                                }
1✔
456
                        }
457

458
                        if (roleGrants(cache, getAuthenticatedRole(), privilege)) {
1✔
459
                                return true;
1✔
460
                        }
461
                }
462

463
                return roleGrants(cache, getAnonymousRole(), privilege);
1✔
464
        }
465

466
        /**
467
         * Tests whether a single role (and its inherited closure) grants the given privilege, using the
468
         * cached flattening when available and falling back to a direct computation otherwise.
469
         *
470
         * @param cache the role privilege cache, or <code>null</code> if unavailable
471
         * @param role the directly assigned role to test
472
         * @param privilege the privilege to check
473
         * @return true if the role grants superuser status or contains the privilege
474
         */
475
        private boolean roleGrants(RolePrivilegeCache cache, Role role, String privilege) {
476
                RolePrivileges rolePrivileges = (cache != null) ? cache.getRolePrivileges(role)
1✔
477
                        : RolePrivilegeCache.computeRolePrivileges(role);
1✔
478
                return rolePrivileges.grantsSuperuser() || rolePrivileges.containsPrivilege(privilege);
1✔
479
        }
480

481
        /**
482
         * Looks up the {@link RolePrivilegeCache} component, or returns <code>null</code> so callers fall
483
         * back to direct computation. Absence during a context refresh is expected (logged at debug);
484
         * absence otherwise is a misconfiguration that silently drops every check to the uncached path, so
485
         * it is warned once.
486
         *
487
         * @return the cache component, or <code>null</code> if unavailable
488
         */
489
        private RolePrivilegeCache getRolePrivilegeCache() {
490
                try {
491
                        return Context.getRegisteredComponent("rolePrivilegeCache", RolePrivilegeCache.class);
1✔
492
                } catch (Exception e) {
×
493
                        if (Context.isRefreshingContext()) {
×
494
                                log.debug("Role privilege cache is unavailable while the context is refreshing; "
×
495
                                        + "computing role privileges directly",
496
                                    e);
497
                        } else if (rolePrivilegeCacheUnavailableWarned.compareAndSet(false, true)) {
×
498
                                log.warn("Could not obtain the rolePrivilegeCache component; privilege checks will recompute role "
×
499
                                        + "privileges on every call until this is resolved",
500
                                    e);
501
                        }
502
                        return null;
×
503
                }
504
        }
505
        
506
        /**
507
         * Convenience method to get the Role in the system designed to be given to all users
508
         *
509
         * @return Role
510
         * <strong>Should</strong> fail if database doesn't contain anonymous role
511
         */
512
        private Role getAnonymousRole() {
513
                if (anonymousRole != null) {
1✔
514
                        return anonymousRole;
1✔
515
                }
516
                
517
                anonymousRole = Context.getUserService().getRole(RoleConstants.ANONYMOUS);
1✔
518
                if (anonymousRole == null) {
1✔
519
                        throw new RuntimeException(
×
520
                                "Database out of sync with code: " + RoleConstants.ANONYMOUS + " role does not exist");
521
                }
522
                
523
                return anonymousRole;
1✔
524
        }
525
        
526
        /**
527
         * Convenience method to get the Role in the system designed to be given to all users that have
528
         * authenticated in some manner
529
         *
530
         * @return Role
531
         * <strong>Should</strong> fail if database doesn't contain authenticated role
532
         */
533
        private Role getAuthenticatedRole() {
534
                if (authenticatedRole != null) {
1✔
535
                        return authenticatedRole;
1✔
536
                }
537
                
538
                authenticatedRole = Context.getUserService().getRole(RoleConstants.AUTHENTICATED);
1✔
539
                if (authenticatedRole == null) {
1✔
540
                        throw new RuntimeException("Database out of sync with code: " + RoleConstants.AUTHENTICATED
×
541
                                + " role does not exist");
542
                }
543
                
544
                return authenticatedRole;
1✔
545
        }
546
        
547
        /**
548
         * @return locationId for this user context if any is set
549
         * @since 1.10
550
         */
551
        public Integer getLocationId() {
552
                return locationId;
×
553
        }
554
        
555
        /**
556
         * @param locationId locationId to set
557
         * @since 1.10
558
         */
559
        public void setLocationId(Integer locationId) {
560
                this.locationId = locationId;
1✔
561
        }
1✔
562
        
563
        /**
564
         * @return current location for this user context if any is set
565
         * @since 1.9
566
         */
567
        public Location getLocation() {
568
                if (locationId == null) {
1✔
569
                        return null;
1✔
570
                }
571
                return Context.getLocationService().getLocation(locationId);
1✔
572
        }
573
        
574
        /**
575
         * @param location the location to set to
576
         * @since 1.9
577
         */
578
        public void setLocation(Location location) {
579
                if (location != null) {
1✔
580
                        this.locationId = location.getLocationId();
1✔
581
                }
582
        }
1✔
583
        
584
        /**
585
         * Convenience method that sets the default location of the currently authenticated user using
586
         * the value of the user's default location property
587
         */
588
        private void setUserLocation(boolean useDefault) {
589
                // location should be null if no user is logged in
590
                if (this.user == null) {
1✔
591
                        this.locationId = null;
×
592
                        return;
×
593
                }
594
                
595
                // intended to be when the user initially authenticates
596
                if (this.locationId == null && useDefault) {
1✔
597
                        this.locationId = getDefaultLocationId(this.user);
1✔
598
                }
599
        }
1✔
600

601
        /**
602
         * Convenience method that sets the default locale used by the currently authenticated user, using
603
         * the value of the user's default local property
604
         */
605
        private void setUserLocale(boolean useDefault) {
606
                // local should be null if no user is logged in
607
                if (this.user == null) {
1✔
608
                        this.locale = null;
×
609
                        return;
×
610
                }
611

612
                // intended to be when the user initially authenticates
613
                if (user.getUserProperties().containsKey("defaultLocale")) {
1✔
614
                        String localeString = user.getUserProperty("defaultLocale");
1✔
615
                        locale = LocaleUtility.fromSpecification(localeString);
1✔
616
                }
617

618
                if (locale == null && useDefault) {
1✔
619
                        locale = LocaleUtility.getDefaultLocale();
1✔
620
                }
621

622
        }
1✔
623
        
624
        protected Integer getDefaultLocationId(User user) {
625
                String defaultLocation = user.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCATION);
1✔
626
                if (StringUtils.isNotBlank(defaultLocation)) {
1✔
627
                        LocationService ls = Context.getLocationService();
1✔
628
                        //only go ahead if it has actually changed OR if wasn't set before
629
                        try {
630
                                int defaultId = Integer.parseInt(defaultLocation);
1✔
631
                                if (this.locationId == null || this.locationId != defaultId) {
1✔
632
                                        // validate that the id is a valid id
633
                                        if (ls.getLocation(defaultId) != null) {
1✔
634
                                                return defaultId;
1✔
635
                                        }
636
                                }
637
                        }
638
                        catch (NumberFormatException ignored) {
1✔
639
                        }
1✔
640

641
                        Location possibleLocation = ls.getLocationByUuid(defaultLocation);
1✔
642

643
                        if (possibleLocation != null && (this.locationId == null || !this.locationId.equals(possibleLocation.getId()))) {
1✔
644
                                return possibleLocation.getId();
1✔
645
                        }
646

647
                        log.warn("The default location for user '{}' is set to '{}', which is not a valid location",
1✔
648
                                user.getUsername(), defaultLocation);
1✔
649
                }
650
                
651
                return null;
1✔
652
        }
653
        
654
        /**
655
         * Notifies privilege listener beans about any privilege check.
656
         * <p>
657
         * It is called by {@link UserContext#hasPrivilege(java.lang.String)}.
658
         *
659
         * @param user         the authenticated user or <code>null</code> if not authenticated
660
         * @param privilege    the checked privilege
661
         * @param hasPrivilege <code>true</code> if the authenticated user has the required privilege or
662
         *                     if it is a proxy privilege
663
         * @see PrivilegeListener
664
         * @since 1.8.4, 1.9.1, 1.10
665
         */
666
        private void notifyPrivilegeListeners(User user, String privilege, boolean hasPrivilege) {
667
                for (PrivilegeListener privilegeListener : Context.getRegisteredComponents(PrivilegeListener.class)) {
1✔
668
                        try {
669
                                privilegeListener.privilegeChecked(user, privilege, hasPrivilege);
1✔
670
                        }
671
                        catch (Exception e) {
×
672
                                log.error("Privilege listener has failed", e);
×
673
                        }
1✔
674
                }
1✔
675
        }
1✔
676
        
677
        private void notifyUserSessionListener(User user, Event event, Status status) {
678
                for (UserSessionListener userSessionListener : Context.getRegisteredComponents(UserSessionListener.class)) {
1✔
679
                        userSessionListener.loggedInOrOut(user, event, status);
1✔
680
                }
1✔
681
        }
1✔
682
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc