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

openmrs / openmrs-core / 30399801741

28 Jul 2026 09:13PM UTC coverage: 64.333% (+0.2%) from 64.136%
30399801741

push

github

web-flow
Fix Mockito inline mocks on JDK 8 and 11 (#6403)

24619 of 38268 relevant lines covered (64.33%)

0.64 hits per line

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

87.5
/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 org.apache.commons.lang3.StringUtils;
13
import org.openmrs.Location;
14
import org.openmrs.PrivilegeListener;
15
import org.openmrs.Role;
16
import org.openmrs.User;
17
import org.openmrs.UserSessionListener;
18
import org.openmrs.UserSessionListener.Event;
19
import org.openmrs.UserSessionListener.Status;
20
import org.openmrs.api.APIAuthenticationException;
21
import org.openmrs.api.LocationService;
22
import org.openmrs.api.cache.RolePrivilegeCache;
23
import org.openmrs.api.cache.RolePrivileges;
24
import org.openmrs.util.LocaleUtility;
25
import org.openmrs.util.OpenmrsConstants;
26
import org.openmrs.util.RoleConstants;
27
import org.slf4j.Logger;
28
import org.slf4j.LoggerFactory;
29

30
import java.io.Serializable;
31
import java.util.ArrayList;
32
import java.util.Arrays;
33
import java.util.Collections;
34
import java.util.HashSet;
35
import java.util.List;
36
import java.util.Locale;
37
import java.util.Objects;
38
import java.util.Set;
39
import java.util.concurrent.atomic.AtomicBoolean;
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 (!Daemon.isDaemonThread() && !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);
1✔
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
         * @return true if there are any proxy privileges
328
         * @since 2.9.0
329
         */
330
        public boolean hasProxyPrivileges() {
331
                return !proxies.isEmpty();
1✔
332
        }
333
        
334
        /**
335
         * @param locale new locale for this context
336
         */
337
        public void setLocale(Locale locale) {
338
                this.locale = locale;
1✔
339
        }
1✔
340
        
341
        /**
342
         * @return current locale for this context
343
         */
344
        public Locale getLocale() {
345
                if (locale == null) {
1✔
346
                        // don't cache default locale - allows recognition of changed default at login page
347
                        return LocaleUtility.getDefaultLocale();
1✔
348
                }
349
                
350
                return locale;
1✔
351
        }
352
        
353
        /**
354
         * Gets all the roles for the (un)authenticated user. Anonymous and Authenticated roles are
355
         * appended if necessary
356
         *
357
         * @return all expanded roles for a user
358
         * @throws Exception
359
         */
360
        public Set<Role> getAllRoles() throws Exception {
361
                return getAllRoles(getAuthenticatedUser());
×
362
        }
363
        
364
        /**
365
         * Gets all the roles for a user. Anonymous and Authenticated roles are appended if necessary
366
         *
367
         * @param user
368
         * @return all expanded roles for a user
369
         * <strong>Should</strong> not fail with null user
370
         * <strong>Should</strong> add anonymous role to all users
371
         * <strong>Should</strong> add authenticated role to all authenticated users
372
         * <strong>Should</strong> return same roles as user getAllRoles method
373
         */
374
        public Set<Role> getAllRoles(User user) throws Exception {
375
                Set<Role> roles = new HashSet<>();
×
376
                
377
                // add the Anonymous Role
378
                roles.add(getAnonymousRole());
×
379
                
380
                // add the Authenticated role
381
                if (getAuthenticatedUser() != null && getAuthenticatedUser().equals(user)) {
×
382
                        roles.addAll(user.getAllRoles());
×
383
                        roles.add(getAuthenticatedRole());
×
384
                }
385
                
386
                return roles;
×
387
        }
388
        
389
        /**
390
         * Tests whether the currently authenticated user has a particular privilege
391
         *
392
         * @param privilege The privilege to check if it's available
393
         * @return true if authenticated user has given privilege
394
         * <strong>Should</strong> authorize if authenticated user has specified privilege
395
         * <strong>Should</strong> authorize if authenticated role has specified privilege
396
         * <strong>Should</strong> authorize if proxied user has specified privilege
397
         * <strong>Should</strong> authorize if anonymous user has specified privilege
398
         * <strong>Should</strong> not authorize if authenticated user does not have specified privilege
399
         * <strong>Should</strong> not authorize if authenticated role does not have specified privilege
400
         * <strong>Should</strong> not authorize if proxied user does not have specified privilege
401
         * <strong>Should</strong> not authorize if anonymous user does not have specified privilege
402
         */
403
        public boolean hasPrivilege(String privilege) {
404
                return hasPrivilege(privilege, true);
1✔
405
        }
406

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

434
                boolean hasPrivilege = resolvePrivilege(privilege);
1✔
435
                notifyPrivilegeListeners(getAuthenticatedUser(), privilege, hasPrivilege);
1✔
436
                return hasPrivilege;
1✔
437
        }
438

439
        /**
440
         * Resolves whether the current user (authenticated or anonymous) holds the given privilege by
441
         * consulting the per-role privilege cache instead of recursively re-expanding the role graph on
442
         * every call. Proxy privileges are handled separately by {@link #hasPrivilege(String)}.
443
         *
444
         * @param privilege the privilege to check
445
         * @return true if the privilege is granted
446
         */
447
        private boolean resolvePrivilege(String privilege) {
448
                RolePrivilegeCache cache = getRolePrivilegeCache();
1✔
449

450
                // if a user has logged in, check their privileges
451
                if (isAuthenticated()) {
1✔
452
                        // All authenticated users have the "" (empty) privilege, matching User.hasPrivilege.
453
                        if (StringUtils.isEmpty(privilege)) {
1✔
454
                                return true;
1✔
455
                        }
456

457
                        User authenticatedUser = getAuthenticatedUser();
1✔
458
                        if (authenticatedUser.getRoles() != null) {
1✔
459
                                for (Role role : authenticatedUser.getRoles()) {
1✔
460
                                        if (roleGrants(cache, role, privilege)) {
1✔
461
                                                return true;
1✔
462
                                        }
463
                                }
1✔
464
                        }
465

466
                        if (roleGrants(cache, getAuthenticatedRole(), privilege)) {
1✔
467
                                return true;
1✔
468
                        }
469
                }
470

471
                return roleGrants(cache, getAnonymousRole(), privilege);
1✔
472
        }
473

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

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

609
        /**
610
         * Convenience method that sets the default locale used by the currently authenticated user, using
611
         * the value of the user's default local property
612
         */
613
        private void setUserLocale(boolean useDefault) {
614
                // local should be null if no user is logged in
615
                if (this.user == null) {
1✔
616
                        this.locale = null;
×
617
                        return;
×
618
                }
619

620
                // intended to be when the user initially authenticates
621
                if (user.getUserProperties().containsKey("defaultLocale")) {
1✔
622
                        String localeString = user.getUserProperty("defaultLocale");
1✔
623
                        locale = LocaleUtility.fromSpecification(localeString);
1✔
624
                }
625

626
                if (locale == null && useDefault) {
1✔
627
                        locale = LocaleUtility.getDefaultLocale();
1✔
628
                }
629

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

649
                        Location possibleLocation = ls.getLocationByUuid(defaultLocation);
1✔
650

651
                        if (possibleLocation != null && (this.locationId == null || !this.locationId.equals(possibleLocation.getId()))) {
1✔
652
                                return possibleLocation.getId();
1✔
653
                        }
654

655
                        log.warn("The default location for user '{}' is set to '{}', which is not a valid location",
1✔
656
                                user.getUsername(), defaultLocation);
1✔
657
                }
658
                
659
                return null;
1✔
660
        }
661
        
662
        /**
663
         * Notifies privilege listener beans about any privilege check.
664
         * <p>
665
         * It is called by {@link UserContext#hasPrivilege(java.lang.String)}.
666
         *
667
         * @param user         the authenticated user or <code>null</code> if not authenticated
668
         * @param privilege    the checked privilege
669
         * @param hasPrivilege <code>true</code> if the authenticated user has the required privilege or
670
         *                     if it is a proxy privilege
671
         * @see PrivilegeListener
672
         * @since 1.8.4, 1.9.1, 1.10
673
         */
674
        private void notifyPrivilegeListeners(User user, String privilege, boolean hasPrivilege) {
675
                for (PrivilegeListener privilegeListener : Context.getRegisteredComponents(PrivilegeListener.class)) {
1✔
676
                        try {
677
                                privilegeListener.privilegeChecked(user, privilege, hasPrivilege);
1✔
678
                        }
679
                        catch (Exception e) {
×
680
                                log.error("Privilege listener has failed", e);
×
681
                        }
1✔
682
                }
1✔
683
        }
1✔
684
        
685
        private void notifyUserSessionListener(User user, Event event, Status status) {
686
                for (UserSessionListener userSessionListener : Context.getRegisteredComponents(UserSessionListener.class)) {
1✔
687
                        userSessionListener.loggedInOrOut(user, event, status);
1✔
688
                }
1✔
689
        }
1✔
690
}
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