]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/kernel/HomeRepository.java
Fix automated Kerberos config
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / HomeRepository.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.security.PrivilegedAction;
4 import java.util.HashSet;
5 import java.util.Set;
6
7 import javax.jcr.Node;
8 import javax.jcr.Repository;
9 import javax.jcr.RepositoryException;
10 import javax.jcr.Session;
11 import javax.jcr.nodetype.NodeType;
12 import javax.jcr.security.Privilege;
13 import javax.naming.InvalidNameException;
14 import javax.naming.ldap.LdapName;
15 import javax.security.auth.Subject;
16 import javax.security.auth.login.LoginContext;
17
18 import org.argeo.cms.CmsException;
19 import org.argeo.jcr.JcrRepositoryWrapper;
20 import org.argeo.jcr.JcrUtils;
21 import org.argeo.node.NodeConstants;
22 import org.argeo.node.NodeNames;
23 import org.argeo.node.NodeTypes;
24 import org.argeo.node.NodeUtils;
25
26 /**
27 * Make sure each user has a home directory available in the default workspace.
28 */
29 class HomeRepository extends JcrRepositoryWrapper implements KernelConstants {
30 /** The home base path. */
31 private String homeBasePath = KernelConstants.DEFAULT_HOME_BASE_PATH;
32 private String groupsBasePath = KernelConstants.DEFAULT_GROUPS_BASE_PATH;
33
34 private Set<String> checkedUsers = new HashSet<String>();
35
36 public HomeRepository(Repository repository) {
37 super(repository);
38 putDescriptor(NodeConstants.CN, NodeConstants.HOME);
39 LoginContext lc;
40 try {
41 lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
42 lc.login();
43 } catch (javax.security.auth.login.LoginException e1) {
44 throw new CmsException("Cannot login as systrem", e1);
45 }
46 Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
47
48 @Override
49 public Void run() {
50 try {
51 Session adminSession = getRepository().login();
52 initJcr(adminSession);
53 } catch (RepositoryException e) {
54 throw new CmsException("Cannot init JCR home", e);
55 }
56 return null;
57 }
58
59 });
60 }
61
62 @Override
63 protected void processNewSession(Session session) {
64 String username = session.getUserID();
65 if (username == null)
66 return;
67 if (session.getUserID().equals(NodeConstants.ROLE_ANONYMOUS))
68 return;
69
70 if (checkedUsers.contains(username))
71 return;
72 Session adminSession = KernelUtils.openAdminSession(getRepository(), session.getWorkspace().getName());
73 try {
74 syncJcr(adminSession, username);
75 checkedUsers.add(username);
76 } finally {
77 JcrUtils.logoutQuietly(adminSession);
78 }
79 }
80
81 /*
82 * JCR
83 */
84 /** Session is logged out. */
85 private void initJcr(Session adminSession) {
86 try {
87 JcrUtils.mkdirs(adminSession, homeBasePath);
88 JcrUtils.mkdirs(adminSession, groupsBasePath);
89 adminSession.save();
90
91 JcrUtils.addPrivilege(adminSession, homeBasePath, NodeConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
92 JcrUtils.addPrivilege(adminSession, groupsBasePath, NodeConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
93 adminSession.save();
94 } catch (RepositoryException e) {
95 throw new CmsException("Cannot initialize node user admin", e);
96 } finally {
97 JcrUtils.logoutQuietly(adminSession);
98 }
99 }
100
101 private void syncJcr(Session session, String username) {
102 try {
103 Node userHome = NodeUtils.getUserHome(session, username);
104 if (userHome == null) {
105 String homePath = generateUserPath(homeBasePath, username);
106 if (session.itemExists(homePath))// duplicate user id
107 userHome = session.getNode(homePath).getParent().addNode(JcrUtils.lastPathElement(homePath));
108 else
109 userHome = JcrUtils.mkdirs(session, homePath);
110 // userHome = JcrUtils.mkfolders(session, homePath);
111 userHome.addMixin(NodeTypes.NODE_USER_HOME);
112 userHome.setProperty(NodeNames.LDAP_UID, username);
113 session.save();
114
115 JcrUtils.clearAccessControList(session, homePath, username);
116 JcrUtils.addPrivilege(session, homePath, username, Privilege.JCR_ALL);
117 }
118 if (session.hasPendingChanges())
119 session.save();
120 } catch (RepositoryException e) {
121 JcrUtils.discardQuietly(session);
122 throw new CmsException("Cannot sync node security model for " + username, e);
123 }
124 }
125
126 /** Generate path for a new user home */
127 private String generateUserPath(String base, String username) {
128 LdapName dn;
129 try {
130 dn = new LdapName(username);
131 } catch (InvalidNameException e) {
132 throw new CmsException("Invalid name " + username, e);
133 }
134 String userId = dn.getRdn(dn.size() - 1).getValue().toString();
135 int atIndex = userId.indexOf('@');
136 if (atIndex > 0) {
137 String domain = userId.substring(0, atIndex);
138 String name = userId.substring(atIndex + 1);
139 return base + '/' + domain + '/' + name;
140 } else if (atIndex == 0 || atIndex == (userId.length() - 1)) {
141 throw new CmsException("Unsupported username " + userId);
142 } else {
143 return base + '/' + userId;
144 }
145 }
146
147 public void createWorkgroup(LdapName dn) {
148 Session adminSession = KernelUtils.openAdminSession(this);
149 String cn = dn.getRdn(dn.size() - 1).getValue().toString();
150 Node newWorkgroup = NodeUtils.getGroupHome(adminSession, cn);
151 if (newWorkgroup != null) {
152 JcrUtils.logoutQuietly(adminSession);
153 throw new CmsException("Workgroup " + newWorkgroup + " already exists for " + dn);
154 }
155 try {
156 // TODO enhance transformation of cn to a valid node name
157 String relPath = cn.replaceAll("[^a-zA-Z0-9]", "_");
158 newWorkgroup = JcrUtils.mkdirs(adminSession.getNode(groupsBasePath), relPath, NodeType.NT_UNSTRUCTURED);
159 newWorkgroup.addMixin(NodeTypes.NODE_GROUP_HOME);
160 newWorkgroup.setProperty(NodeNames.LDAP_CN, cn);
161 adminSession.save();
162 JcrUtils.addPrivilege(adminSession, newWorkgroup.getPath(), dn.toString(), Privilege.JCR_ALL);
163 adminSession.save();
164 } catch (RepositoryException e) {
165 throw new CmsException("Cannot create workgroup", e);
166 } finally {
167 JcrUtils.logoutQuietly(adminSession);
168 }
169
170 }
171
172 }