]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.ext.jackrabbit/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java
Give admin role to OS user.
[lgpl/argeo-commons.git] / org.argeo.ext.jackrabbit / src / org / argeo / security / jackrabbit / ArgeoSecurityManager.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.security.jackrabbit;
17
18 import java.security.Principal;
19 import java.util.HashSet;
20 import java.util.Properties;
21 import java.util.Set;
22
23 import javax.jcr.Repository;
24 import javax.jcr.RepositoryException;
25 import javax.jcr.Session;
26 import javax.security.auth.Subject;
27 import javax.security.auth.x500.X500Principal;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.jackrabbit.api.security.user.UserManager;
32 import org.apache.jackrabbit.core.DefaultSecurityManager;
33 import org.apache.jackrabbit.core.security.AMContext;
34 import org.apache.jackrabbit.core.security.AccessManager;
35 import org.apache.jackrabbit.core.security.SecurityConstants;
36 import org.apache.jackrabbit.core.security.SystemPrincipal;
37 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
38 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
39 import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
40 import org.argeo.api.NodeConstants;
41 import org.argeo.api.security.AnonymousPrincipal;
42 import org.argeo.api.security.DataAdminPrincipal;
43 import org.argeo.cms.auth.CmsSession;
44 import org.osgi.framework.BundleContext;
45 import org.osgi.framework.FrameworkUtil;
46
47 /** Customises Jackrabbit security. */
48 public class ArgeoSecurityManager extends DefaultSecurityManager {
49 private final static Log log = LogFactory.getLog(ArgeoSecurityManager.class);
50
51 private BundleContext cmsBundleContext = null;
52
53 public ArgeoSecurityManager() {
54 if (FrameworkUtil.getBundle(CmsSession.class) != null) {
55 cmsBundleContext = FrameworkUtil.getBundle(CmsSession.class).getBundleContext();
56 }
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 = CmsSession.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 }