3 import java
.security
.Principal
;
4 import java
.security
.PrivilegedAction
;
5 import java
.security
.PrivilegedActionException
;
6 import java
.security
.PrivilegedExceptionAction
;
7 import java
.util
.HashSet
;
8 import java
.util
.Iterator
;
9 import java
.util
.Locale
;
11 import java
.util
.UUID
;
13 import javax
.security
.auth
.Subject
;
14 import javax
.security
.auth
.x500
.X500Principal
;
16 import org
.argeo
.api
.acr
.NamespaceUtils
;
17 import org
.argeo
.api
.cms
.CmsConstants
;
18 import org
.argeo
.api
.cms
.CmsSession
;
19 import org
.argeo
.api
.cms
.CmsSessionId
;
20 import org
.argeo
.api
.cms
.auth
.ImpliedByPrincipal
;
21 import org
.argeo
.api
.cms
.auth
.RoleNameUtils
;
22 import org
.argeo
.api
.cms
.auth
.SystemRole
;
23 import org
.argeo
.cms
.internal
.auth
.CmsSessionImpl
;
24 import org
.argeo
.cms
.internal
.runtime
.CmsContextImpl
;
25 import org
.argeo
.cms
.util
.CurrentSubject
;
26 import org
.osgi
.service
.useradmin
.Authorization
;
29 * Programmatic access to the currently authenticated user, within a CMS
32 public final class CurrentUser
{
34 * Technical username of the currently authenticated user.
36 * @return the authenticated username or null if not authenticated / anonymous
38 public static String
getUsername() {
39 return getUsername(currentSubject());
43 * Human readable name of the currently authenticated user (typically first name
46 public static String
getDisplayName() {
47 return getDisplayName(currentSubject());
50 /** Whether a user is currently authenticated. */
51 public static boolean isAnonymous() {
52 return isAnonymous(currentSubject());
55 /** Locale of the current user */
56 public static Locale
locale() {
57 return locale(currentSubject());
60 /** Roles of the currently logged-in user */
61 public static Set
<String
> roles() {
62 return roles(currentSubject());
65 /** Returns true if the current user is in the specified role */
66 public static boolean isInRole(String role
) {
67 Set
<String
> roles
= roles();
68 return roles
.contains(role
);
71 /** Implies this {@link SystemRole} in this context. */
72 public static boolean implies(SystemRole role
, String context
) {
73 return role
.implied(currentSubject(), context
);
76 /** Implies this role name, also independently of the context. */
77 public static boolean implies(String role
, String context
) {
78 return SystemRole
.implied(NamespaceUtils
.parsePrefixedName(role
), currentSubject(), context
);
81 /** Get the primary context this user belongs to. */
82 public static boolean isUserContext(String context
) {
83 // TODO have the role context as a separated credential in the Subjecto?
84 return RoleNameUtils
.getContext(getUsername()).equalsIgnoreCase(context
);
87 /** Executes as the current user */
88 public static <T
> T
doAs(PrivilegedAction
<T
> action
) {
89 return Subject
.doAs(currentSubject(), action
);
92 /** Executes as the current user */
93 public static <T
> T
tryAs(PrivilegedExceptionAction
<T
> action
) throws PrivilegedActionException
{
94 return Subject
.doAs(currentSubject(), action
);
101 public static String
getUsername(Subject subject
) {
103 throw new IllegalArgumentException("Subject cannot be null");
104 if (subject
.getPrincipals(X500Principal
.class).size() != 1)
105 return CmsConstants
.ROLE_ANONYMOUS
;
106 Principal principal
= subject
.getPrincipals(X500Principal
.class).iterator().next();
107 return principal
.getName();
110 public static String
getDisplayName(Subject subject
) {
111 return getAuthorization(subject
).toString();
114 public static Set
<String
> roles(Subject subject
) {
115 Set
<String
> roles
= new HashSet
<String
>();
116 roles
.add(getUsername(subject
));
117 for (Principal group
: subject
.getPrincipals(ImpliedByPrincipal
.class)) {
118 roles
.add(group
.getName());
123 public static Locale
locale(Subject subject
) {
124 Set
<Locale
> locales
= subject
.getPublicCredentials(Locale
.class);
125 if (locales
.isEmpty()) {
126 Locale defaultLocale
= CmsContextImpl
.getCmsContext().getDefaultLocale();
127 return defaultLocale
;
129 return locales
.iterator().next();
132 /** Whether this user is currently authenticated. */
133 public static boolean isAnonymous(Subject subject
) {
136 String username
= getUsername(subject
);
137 return username
== null || username
.equalsIgnoreCase(CmsConstants
.ROLE_ANONYMOUS
);
140 public static CmsSession
getCmsSession() {
141 Subject subject
= currentSubject();
142 Iterator
<CmsSessionId
> it
= subject
.getPrivateCredentials(CmsSessionId
.class).iterator();
144 throw new IllegalStateException("No CMS session id available for " + subject
);
145 CmsSessionId cmsSessionId
= it
.next();
147 throw new IllegalStateException("More than one CMS session id available for " + subject
);
148 return CmsContextImpl
.getCmsContext().getCmsSessionByUuid(cmsSessionId
.getUuid());
151 public static boolean isAvailable() {
152 return CurrentSubject
.current() != null;
158 private static Subject
currentSubject() {
159 Subject subject
= CurrentSubject
.current();
161 throw new IllegalStateException("Cannot find related subject");
165 private static Authorization
getAuthorization(Subject subject
) {
166 return subject
.getPrivateCredentials(Authorization
.class).iterator().next();
169 public static boolean logoutCmsSession(Subject subject
) {
171 if (subject
.getPrivateCredentials(CmsSessionId
.class).size() == 1)
172 nodeSessionId
= subject
.getPrivateCredentials(CmsSessionId
.class).iterator().next().getUuid();
175 CmsSessionImpl cmsSession
= CmsContextImpl
.getCmsContext().getCmsSessionByUuid(nodeSessionId
);
177 // FIXME logout all views
178 // TODO check why it is sometimes null
179 if (cmsSession
!= null)
181 // if (log.isDebugEnabled())
182 // log.debug("Logged out CMS session " + cmsSession.getUuid());
187 private CurrentUser() {