1 package org
.argeo
.cms
.internal
.auth
;
3 import java
.io
.Serializable
;
4 import java
.security
.AccessControlContext
;
5 import java
.security
.AccessController
;
6 import java
.security
.PrivilegedAction
;
7 import java
.time
.ZonedDateTime
;
8 import java
.util
.ArrayList
;
9 import java
.util
.Collections
;
10 import java
.util
.HashMap
;
11 import java
.util
.List
;
12 import java
.util
.Locale
;
14 import java
.util
.Objects
;
16 import java
.util
.UUID
;
17 import java
.util
.function
.Consumer
;
19 import javax
.crypto
.SecretKey
;
20 import javax
.naming
.InvalidNameException
;
21 import javax
.naming
.ldap
.LdapName
;
22 import javax
.security
.auth
.Subject
;
23 import javax
.security
.auth
.login
.LoginContext
;
24 import javax
.security
.auth
.login
.LoginException
;
25 import javax
.security
.auth
.x500
.X500Principal
;
27 import org
.argeo
.api
.cms
.CmsAuth
;
28 import org
.argeo
.api
.cms
.CmsLog
;
29 import org
.argeo
.api
.cms
.CmsSession
;
30 import org
.argeo
.cms
.internal
.runtime
.CmsContextImpl
;
31 import org
.argeo
.cms
.security
.NodeSecurityUtils
;
32 import org
.osgi
.framework
.ServiceRegistration
;
33 import org
.osgi
.service
.useradmin
.Authorization
;
35 /** Default CMS session implementation. */
36 public class CmsSessionImpl
implements CmsSession
, Serializable
{
37 private static final long serialVersionUID
= 1867719354246307225L;
38 // private final static BundleContext bc = FrameworkUtil.getBundle(CmsSessionImpl.class).getBundleContext();
39 private final static CmsLog log
= CmsLog
.getLog(CmsSessionImpl
.class);
41 // private final Subject initialSubject;
42 private transient AccessControlContext accessControlContext
;
43 private final UUID uuid
;
44 private final String localSessionId
;
45 private Authorization authorization
;
46 private final LdapName userDn
;
47 private final boolean anonymous
;
49 private final ZonedDateTime creationTime
;
50 private ZonedDateTime end
;
51 private final Locale locale
;
53 private ServiceRegistration
<CmsSession
> serviceRegistration
;
55 private Map
<String
, Object
> views
= new HashMap
<>();
57 private List
<Consumer
<CmsSession
>> onCloseCallbacks
= Collections
.synchronizedList(new ArrayList
<>());
59 public CmsSessionImpl(UUID uuid
, Subject initialSubject
, Authorization authorization
, Locale locale
,
60 String localSessionId
) {
61 Objects
.requireNonNull(uuid
);
63 this.creationTime
= ZonedDateTime
.now();
65 this.accessControlContext
= Subject
.doAs(initialSubject
, new PrivilegedAction
<AccessControlContext
>() {
68 public AccessControlContext
run() {
69 return AccessController
.getContext();
73 // this.initialSubject = initialSubject;
74 this.localSessionId
= localSessionId
;
75 this.authorization
= authorization
;
76 if (authorization
.getName() != null)
78 this.userDn
= new LdapName(authorization
.getName());
79 this.anonymous
= false;
80 } catch (InvalidNameException e
) {
81 throw new IllegalArgumentException("Invalid user name " + authorization
.getName(), e
);
84 this.userDn
= NodeSecurityUtils
.ROLE_ANONYMOUS_NAME
;
85 this.anonymous
= true;
91 end
= ZonedDateTime
.now();
92 CmsContextImpl
.getCmsContext().unregisterCmsSession(this);
93 // serviceRegistration.unregister();
95 for (Consumer
<CmsSession
> onClose
: onCloseCallbacks
) {
102 lc
= new LoginContext(CmsAuth
.LOGIN_CONTEXT_ANONYMOUS
, getSubject());
104 lc
= new LoginContext(CmsAuth
.LOGIN_CONTEXT_USER
, getSubject());
107 } catch (LoginException e
) {
108 log
.warn("Could not logout " + getSubject() + ": " + e
);
110 accessControlContext
= null;
112 log
.debug("Closed " + this);
116 public void addOnCloseCallback(Consumer
<CmsSession
> onClose
) {
117 onCloseCallbacks
.add(onClose
);
120 public Subject
getSubject() {
121 return Subject
.getSubject(accessControlContext
);
124 public Set
<SecretKey
> getSecretKeys() {
126 return getSubject().getPrivateCredentials(SecretKey
.class);
130 public boolean isValid() {
134 private void checkValid() {
136 throw new IllegalStateException("CMS session " + uuid
+ " is not valid since " + end
);
139 final protected boolean isClosed() {
140 return getEnd() != null;
143 public Authorization
getAuthorization() {
145 return authorization
;
149 public String
getDisplayName() {
150 return authorization
.toString();
154 public UUID
getUuid() {
159 public LdapName
getUserDn() {
164 public String
getUserRole() {
165 return new X500Principal(authorization
.getName()).getName();
169 public String
getLocalId() {
170 return localSessionId
;
174 public boolean isAnonymous() {
179 public Locale
getLocale() {
184 public ZonedDateTime
getCreationTime() {
189 public ZonedDateTime
getEnd() {
194 public void registerView(String uid
, Object view
) {
196 if (views
.containsKey(uid
))
197 throw new IllegalArgumentException("View " + uid
+ " is already registered.");
198 views
.put(uid
, view
);
201 public String
toString() {
202 return "CMS Session " + userDn
+ " localId=" + localSessionId
+ ", uuid=" + uuid
;