]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/CurrentUser.java
Releasing
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / CurrentUser.java
1 package org.argeo.cms;
2
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;
10 import java.util.Set;
11 import java.util.UUID;
12
13 import javax.security.auth.Subject;
14 import javax.security.auth.x500.X500Principal;
15
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.cms.internal.auth.CmsSessionImpl;
21 import org.argeo.cms.internal.auth.ImpliedByPrincipal;
22 import org.argeo.cms.internal.runtime.CmsContextImpl;
23 import org.argeo.cms.util.CurrentSubject;
24 import org.osgi.service.useradmin.Authorization;
25
26 /**
27 * Programmatic access to the currently authenticated user, within a CMS
28 * context.
29 */
30 public final class CurrentUser {
31 /**
32 * Technical username of the currently authenticated user.
33 *
34 * @return the authenticated username or null if not authenticated / anonymous
35 */
36 public static String getUsername() {
37 return getUsername(currentSubject());
38 }
39
40 /**
41 * Human readable name of the currently authenticated user (typically first name
42 * and last name).
43 */
44 public static String getDisplayName() {
45 return getDisplayName(currentSubject());
46 }
47
48 /** Whether a user is currently authenticated. */
49 public static boolean isAnonymous() {
50 return isAnonymous(currentSubject());
51 }
52
53 /** Locale of the current user */
54 public static Locale locale() {
55 return locale(currentSubject());
56 }
57
58 /** Roles of the currently logged-in user */
59 public static Set<String> roles() {
60 return roles(currentSubject());
61 }
62
63 /** Returns true if the current user is in the specified role */
64 public static boolean isInRole(String role) {
65 Set<String> roles = roles();
66 return roles.contains(role);
67 }
68
69 /** Implies this {@link SystemRole} in this context. */
70 public static boolean implies(SystemRole role, String context) {
71 return role.implied(currentSubject(), context);
72 }
73
74 /** Implies this role name, also independently of the context. */
75 public static boolean implies(String role, String context) {
76 return SystemRole.implied(NamespaceUtils.parsePrefixedName(role), currentSubject(), context);
77 }
78
79 /** Get the primary context this user belongs to. */
80 public static boolean isUserContext(String context) {
81 // TODO have the role context as a separated credential in the Subjecto?
82 return RoleNameUtils.getContext(getUsername()).equalsIgnoreCase(context);
83 }
84
85 /** Executes as the current user */
86 public static <T> T doAs(PrivilegedAction<T> action) {
87 return Subject.doAs(currentSubject(), action);
88 }
89
90 /** Executes as the current user */
91 public static <T> T tryAs(PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
92 return Subject.doAs(currentSubject(), action);
93 }
94
95 /*
96 * WRAPPERS
97 */
98
99 public static String getUsername(Subject subject) {
100 if (subject == null)
101 throw new IllegalArgumentException("Subject cannot be null");
102 if (subject.getPrincipals(X500Principal.class).size() != 1)
103 return CmsConstants.ROLE_ANONYMOUS;
104 Principal principal = subject.getPrincipals(X500Principal.class).iterator().next();
105 return principal.getName();
106 }
107
108 public static String getDisplayName(Subject subject) {
109 return getAuthorization(subject).toString();
110 }
111
112 public static Set<String> roles(Subject subject) {
113 Set<String> roles = new HashSet<String>();
114 roles.add(getUsername(subject));
115 for (Principal group : subject.getPrincipals(ImpliedByPrincipal.class)) {
116 roles.add(group.getName());
117 }
118 return roles;
119 }
120
121 public static Locale locale(Subject subject) {
122 Set<Locale> locales = subject.getPublicCredentials(Locale.class);
123 if (locales.isEmpty()) {
124 Locale defaultLocale = CmsContextImpl.getCmsContext().getDefaultLocale();
125 return defaultLocale;
126 } else
127 return locales.iterator().next();
128 }
129
130 /** Whether this user is currently authenticated. */
131 public static boolean isAnonymous(Subject subject) {
132 if (subject == null)
133 return true;
134 String username = getUsername(subject);
135 return username == null || username.equalsIgnoreCase(CmsConstants.ROLE_ANONYMOUS);
136 }
137
138 public static CmsSession getCmsSession() {
139 Subject subject = currentSubject();
140 Iterator<CmsSessionId> it = subject.getPrivateCredentials(CmsSessionId.class).iterator();
141 if (!it.hasNext())
142 throw new IllegalStateException("No CMS session id available for " + subject);
143 CmsSessionId cmsSessionId = it.next();
144 if (it.hasNext())
145 throw new IllegalStateException("More than one CMS session id available for " + subject);
146 return CmsContextImpl.getCmsContext().getCmsSessionByUuid(cmsSessionId.getUuid());
147 }
148
149 public static boolean isAvailable() {
150 return CurrentSubject.current() != null;
151 }
152
153 /*
154 * HELPERS
155 */
156 private static Subject currentSubject() {
157 Subject subject = CurrentSubject.current();
158 if (subject == null)
159 throw new IllegalStateException("Cannot find related subject");
160 return subject;
161 }
162
163 private static Authorization getAuthorization(Subject subject) {
164 return subject.getPrivateCredentials(Authorization.class).iterator().next();
165 }
166
167 public static boolean logoutCmsSession(Subject subject) {
168 UUID nodeSessionId;
169 if (subject.getPrivateCredentials(CmsSessionId.class).size() == 1)
170 nodeSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next().getUuid();
171 else
172 return false;
173 CmsSessionImpl cmsSession = CmsContextImpl.getCmsContext().getCmsSessionByUuid(nodeSessionId);
174
175 // FIXME logout all views
176 // TODO check why it is sometimes null
177 if (cmsSession != null)
178 cmsSession.close();
179 // if (log.isDebugEnabled())
180 // log.debug("Logged out CMS session " + cmsSession.getUuid());
181 return true;
182 }
183
184 /** singleton */
185 private CurrentUser() {
186 }
187 }