]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java
Merge demo into sdk
[lgpl/argeo-commons.git] / org.argeo.cms.jcr / src / org / argeo / security / jackrabbit / ArgeoSecurityManager.java
1 package org.argeo.security.jackrabbit;
2
3 import java.security.Principal;
4 import java.util.HashSet;
5 import java.util.Properties;
6 import java.util.Set;
7
8 import javax.jcr.Credentials;
9 import javax.jcr.Repository;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.security.auth.Subject;
13 import javax.security.auth.callback.CallbackHandler;
14 import javax.security.auth.x500.X500Principal;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.apache.jackrabbit.api.security.user.UserManager;
19 import org.apache.jackrabbit.core.DefaultSecurityManager;
20 import org.apache.jackrabbit.core.security.AMContext;
21 import org.apache.jackrabbit.core.security.AccessManager;
22 import org.apache.jackrabbit.core.security.SecurityConstants;
23 import org.apache.jackrabbit.core.security.SystemPrincipal;
24 import org.apache.jackrabbit.core.security.authentication.AuthContext;
25 import org.apache.jackrabbit.core.security.authentication.CallbackHandlerImpl;
26 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
27 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
28 import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
29 import org.argeo.api.NodeConstants;
30 import org.argeo.api.cms.CmsSession;
31 import org.argeo.api.security.AnonymousPrincipal;
32 import org.argeo.api.security.DataAdminPrincipal;
33 import org.argeo.cms.osgi.CmsOsgiUtils;
34 import org.osgi.framework.BundleContext;
35 import org.osgi.framework.FrameworkUtil;
36
37 /** Customises Jackrabbit security. */
38 public class ArgeoSecurityManager extends DefaultSecurityManager {
39 private final static Log log = LogFactory.getLog(ArgeoSecurityManager.class);
40
41 private BundleContext cmsBundleContext = null;
42
43 public ArgeoSecurityManager() {
44 if (FrameworkUtil.getBundle(CmsSession.class) != null) {
45 cmsBundleContext = FrameworkUtil.getBundle(CmsSession.class).getBundleContext();
46 }
47 }
48
49 public AuthContext getAuthContext(Credentials creds, Subject subject, String workspaceName)
50 throws RepositoryException {
51 checkInitialized();
52
53 CallbackHandler cbHandler = new CallbackHandlerImpl(creds, getSystemSession(), getPrincipalProviderRegistry(),
54 adminId, anonymousId);
55 String appName = "Jackrabbit";
56 return new ArgeoAuthContext(appName, subject, cbHandler);
57 }
58
59 @Override
60 public AccessManager getAccessManager(Session session, AMContext amContext) throws RepositoryException {
61 synchronized (getSystemSession()) {
62 return super.getAccessManager(session, amContext);
63 }
64 }
65
66 @Override
67 public UserManager getUserManager(Session session) throws RepositoryException {
68 synchronized (getSystemSession()) {
69 return super.getUserManager(session);
70 }
71 }
72
73 @Override
74 protected PrincipalProvider createDefaultPrincipalProvider(Properties[] moduleConfig) throws RepositoryException {
75 return super.createDefaultPrincipalProvider(moduleConfig);
76 }
77
78 /** Called once when the session is created */
79 @Override
80 public String getUserID(Subject subject, String workspaceName) throws RepositoryException {
81 boolean isAnonymous = !subject.getPrincipals(AnonymousPrincipal.class).isEmpty();
82 boolean isDataAdmin = !subject.getPrincipals(DataAdminPrincipal.class).isEmpty();
83 boolean isJackrabbitSystem = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
84 Set<X500Principal> userPrincipal = subject.getPrincipals(X500Principal.class);
85 boolean isRegularUser = !userPrincipal.isEmpty();
86 CmsSession cmsSession = null;
87 if (cmsBundleContext != null) {
88 cmsSession = CmsOsgiUtils.getCmsSession(cmsBundleContext, subject);
89 if (log.isTraceEnabled())
90 log.trace("Opening JCR session for CMS session " + cmsSession);
91 }
92
93 if (isAnonymous) {
94 if (isDataAdmin || isJackrabbitSystem || isRegularUser)
95 throw new IllegalStateException("Inconsistent " + subject);
96 else
97 return NodeConstants.ROLE_ANONYMOUS;
98 } else if (isRegularUser) {// must be before DataAdmin
99 if (isAnonymous || isJackrabbitSystem)
100 throw new IllegalStateException("Inconsistent " + subject);
101 else {
102 if (userPrincipal.size() > 1) {
103 StringBuilder buf = new StringBuilder();
104 for (X500Principal principal : userPrincipal)
105 buf.append(' ').append('\"').append(principal).append('\"');
106 throw new RuntimeException("Multiple user principals:" + buf);
107 }
108 return userPrincipal.iterator().next().getName();
109 }
110 } else if (isDataAdmin) {
111 if (isAnonymous || isJackrabbitSystem || isRegularUser)
112 throw new IllegalStateException("Inconsistent " + subject);
113 else {
114 assert !subject.getPrincipals(AdminPrincipal.class).isEmpty();
115 return NodeConstants.ROLE_DATA_ADMIN;
116 }
117 } else if (isJackrabbitSystem) {
118 if (isAnonymous || isDataAdmin || isRegularUser)
119 throw new IllegalStateException("Inconsistent " + subject);
120 else
121 return super.getUserID(subject, workspaceName);
122 } else {
123 throw new IllegalStateException("Unrecognized subject type: " + subject);
124 }
125 }
126
127 @Override
128 protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
129 WorkspaceAccessManager wam = super.createDefaultWorkspaceAccessManager();
130 ArgeoWorkspaceAccessManagerImpl workspaceAccessManager = new ArgeoWorkspaceAccessManagerImpl(wam);
131 if (log.isTraceEnabled())
132 log.trace("Created workspace access manager");
133 return workspaceAccessManager;
134 }
135
136 private class ArgeoWorkspaceAccessManagerImpl implements SecurityConstants, WorkspaceAccessManager {
137 private final WorkspaceAccessManager wam;
138
139 public ArgeoWorkspaceAccessManagerImpl(WorkspaceAccessManager wam) {
140 super();
141 this.wam = wam;
142 }
143
144 public void init(Session systemSession) throws RepositoryException {
145 wam.init(systemSession);
146 Repository repository = systemSession.getRepository();
147 if (log.isTraceEnabled())
148 log.trace("Initialised workspace access manager on repository " + repository
149 + ", systemSession workspace: " + systemSession.getWorkspace().getName());
150 }
151
152 public void close() throws RepositoryException {
153 }
154
155 public boolean grants(Set<Principal> principals, String workspaceName) throws RepositoryException {
156 // TODO: implements finer access to workspaces
157 if (log.isTraceEnabled())
158 log.trace("Grants " + new HashSet<>(principals) + " access to workspace '" + workspaceName + "'");
159 return true;
160 // return wam.grants(principals, workspaceName);
161 }
162 }
163
164 }