]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java
Force use of permission admin (with all permissions)
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / CurrentUser.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
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 * http://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 org.argeo.cms.auth;
17
18 import java.security.AccessController;
19 import java.security.Principal;
20 import java.security.PrivilegedAction;
21 import java.security.PrivilegedActionException;
22 import java.security.PrivilegedExceptionAction;
23 import java.security.acl.Group;
24 import java.util.Collection;
25 import java.util.HashSet;
26 import java.util.Set;
27 import java.util.UUID;
28
29 import javax.security.auth.Subject;
30 import javax.security.auth.x500.X500Principal;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.argeo.cms.CmsException;
35 import org.argeo.cms.internal.http.WebCmsSessionImpl;
36 import org.argeo.eclipse.ui.specific.UiContext;
37 import org.argeo.node.NodeConstants;
38 import org.argeo.node.security.NodeAuthenticated;
39 import org.osgi.framework.BundleContext;
40 import org.osgi.framework.FrameworkUtil;
41 import org.osgi.framework.InvalidSyntaxException;
42 import org.osgi.framework.ServiceReference;
43 import org.osgi.service.useradmin.Authorization;
44
45 /**
46 * Programmatic access to the currently authenticated user, within a CMS
47 * context.
48 */
49 public final class CurrentUser {
50 private final static Log log = LogFactory.getLog(CurrentUser.class);
51 private final static BundleContext bc = FrameworkUtil.getBundle(CurrentUser.class).getBundleContext();
52 /*
53 * CURRENT USER API
54 */
55
56 /**
57 * Technical username of the currently authenticated user.
58 *
59 * @return the authenticated username or null if not authenticated /
60 * anonymous
61 */
62 public static String getUsername() {
63 return getUsername(currentSubject());
64 }
65
66 /**
67 * Human readable name of the currently authenticated user (typically first
68 * name and last name).
69 */
70 public static String getDisplayName() {
71 return getDisplayName(currentSubject());
72 }
73
74 /** Whether a user is currently authenticated. */
75 public static boolean isAnonymous() {
76 return isAnonymous(currentSubject());
77 }
78
79 /** Roles of the currently logged-in user */
80 public final static Set<String> roles() {
81 return roles(currentSubject());
82 }
83
84 /** Returns true if the current user is in the specified role */
85 public static boolean isInRole(String role) {
86 Set<String> roles = roles();
87 return roles.contains(role);
88 }
89
90 /** Executes as the current user */
91 public final static <T> T doAs(PrivilegedAction<T> action) {
92 return Subject.doAs(currentSubject(), action);
93 }
94
95 /** Executes as the current user */
96 public final static <T> T tryAs(PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
97 return Subject.doAs(currentSubject(), action);
98 }
99
100 /*
101 * WRAPPERS
102 */
103
104 public final static String getUsername(Subject subject) {
105 if (subject == null)
106 throw new CmsException("Subject cannot be null");
107 if (subject.getPrincipals(X500Principal.class).size() != 1)
108 return NodeConstants.ROLE_ANONYMOUS;
109 Principal principal = subject.getPrincipals(X500Principal.class).iterator().next();
110 return principal.getName();
111 }
112
113 public final static String getDisplayName(Subject subject) {
114 return getAuthorization(subject).toString();
115 }
116
117 public final static Set<String> roles(Subject subject) {
118 Set<String> roles = new HashSet<String>();
119 roles.add(getUsername(subject));
120 for (Principal group : subject.getPrincipals(Group.class)) {
121 roles.add(group.getName());
122 }
123 return roles;
124 }
125
126 /** Whether this user is currently authenticated. */
127 public static boolean isAnonymous(Subject subject) {
128 if (subject == null)
129 return true;
130 String username = getUsername(subject);
131 return username == null || username.equalsIgnoreCase(NodeConstants.ROLE_ANONYMOUS);
132 }
133 /*
134 * HELPERS
135 */
136
137 private static Subject currentSubject() {
138 NodeAuthenticated cmsView = getNodeAuthenticated();
139 if (cmsView != null)
140 return cmsView.getLoginContext().getSubject();
141 Subject subject = Subject.getSubject(AccessController.getContext());
142 if (subject != null)
143 return subject;
144 throw new CmsException("Cannot find related subject");
145 }
146
147 /**
148 * The node authenticated component (typically a CMS view) related to this
149 * display, or null if none is available from this call. <b>Not API: Only
150 * for low-level access.</b>
151 */
152 private static NodeAuthenticated getNodeAuthenticated() {
153 return UiContext.getData(NodeAuthenticated.KEY);
154 }
155
156 private static Authorization getAuthorization(Subject subject) {
157 return subject.getPrivateCredentials(Authorization.class).iterator().next();
158 }
159
160 public static boolean logoutCmsSession(Subject subject) {
161 UUID nodeSessionId;
162 if (subject.getPrivateCredentials(CmsSessionId.class).size() == 1)
163 nodeSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next().getUuid();
164 else
165 return false;
166 Collection<ServiceReference<CmsSession>> srs;
167 try {
168 srs = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + nodeSessionId + ")");
169 } catch (InvalidSyntaxException e) {
170 throw new CmsException("Cannot retrieve CMS session #" + nodeSessionId, e);
171 }
172
173 if (srs.size() == 0) {
174 // if (log.isTraceEnabled())
175 // log.warn("No CMS web session found for http session " +
176 // nodeSessionId);
177 return false;
178 } else if (srs.size() > 1)
179 throw new CmsException(srs.size() + " CMS web sessions found for http session " + nodeSessionId);
180
181 WebCmsSessionImpl cmsSession = (WebCmsSessionImpl) bc.getService(srs.iterator().next());
182 cmsSession.cleanUp();
183 // subject.getPrivateCredentials().removeAll(subject.getPrivateCredentials(CmsSessionId.class));
184 if (log.isDebugEnabled())
185 log.debug("Logged out CMS session " + cmsSession.getUuid());
186 return true;
187 }
188
189 private CurrentUser() {
190 }
191 }