]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java
First draft of file system based GCR
[lgpl/argeo-commons.git] / org.argeo.cms.jcr / src / org / argeo / maintenance / AbstractMaintenanceService.java
1 package org.argeo.maintenance;
2
3 import java.io.IOException;
4 import java.util.EnumSet;
5 import java.util.HashSet;
6 import java.util.Set;
7
8 import javax.jcr.NoSuchWorkspaceException;
9 import javax.jcr.Repository;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.argeo.cms.jcr.CmsJcrUtils;
16 import org.argeo.jcr.Jcr;
17 import org.argeo.jcr.JcrUtils;
18 import org.argeo.naming.Distinguished;
19 import org.argeo.osgi.transaction.WorkTransaction;
20 import org.osgi.service.useradmin.Group;
21 import org.osgi.service.useradmin.Role;
22 import org.osgi.service.useradmin.UserAdmin;
23
24 /** Make sure roles and access rights are properly configured. */
25 public abstract class AbstractMaintenanceService {
26 private final static Log log = LogFactory.getLog(AbstractMaintenanceService.class);
27
28 private Repository repository;
29 // private UserAdminService userAdminService;
30 private UserAdmin userAdmin;
31 private WorkTransaction userTransaction;
32
33 public void init() {
34 makeSureRolesExists(getRequiredRoles());
35 configureStandardRoles();
36
37 Set<String> workspaceNames = getWorkspaceNames();
38 if (workspaceNames == null || workspaceNames.isEmpty()) {
39 configureJcr(repository, null);
40 } else {
41 for (String workspaceName : workspaceNames)
42 configureJcr(repository, workspaceName);
43 }
44 }
45
46 /** Configures a workspace. */
47 protected void configureJcr(Repository repository, String workspaceName) {
48 Session adminSession;
49 try {
50 adminSession = CmsJcrUtils.openDataAdminSession(repository, workspaceName);
51 } catch (RuntimeException e1) {
52 if (e1.getCause() != null && e1.getCause() instanceof NoSuchWorkspaceException) {
53 Session defaultAdminSession = CmsJcrUtils.openDataAdminSession(repository, null);
54 try {
55 defaultAdminSession.getWorkspace().createWorkspace(workspaceName);
56 log.info("Created JCR workspace " + workspaceName);
57 } catch (RepositoryException e) {
58 throw new IllegalStateException("Cannot create workspace " + workspaceName, e);
59 } finally {
60 Jcr.logout(defaultAdminSession);
61 }
62 adminSession = CmsJcrUtils.openDataAdminSession(repository, workspaceName);
63 } else
64 throw e1;
65 }
66 try {
67 if (prepareJcrTree(adminSession)) {
68 configurePrivileges(adminSession);
69 }
70 } catch (RepositoryException | IOException e) {
71 throw new IllegalStateException("Cannot initialise JCR data layer.", e);
72 } finally {
73 JcrUtils.logoutQuietly(adminSession);
74 }
75 }
76
77 /** To be overridden. */
78 protected Set<String> getWorkspaceNames() {
79 return null;
80 }
81
82 /**
83 * To be overridden in order to programmatically set relationships between
84 * roles. Does nothing by default.
85 */
86 protected void configureStandardRoles() {
87 }
88
89 /**
90 * Creates the base JCR tree structure expected for this app if necessary.
91 *
92 * Expects a clean session ({@link Session#hasPendingChanges()} should return
93 * false) and saves it once the changes have been done. Thus the session can be
94 * rolled back if an exception occurs.
95 *
96 * @return true if something as been updated
97 */
98 public boolean prepareJcrTree(Session adminSession) throws RepositoryException, IOException {
99 return false;
100 }
101
102 /**
103 * Adds app specific default privileges.
104 *
105 * Expects a clean session ({@link Session#hasPendingChanges()} should return
106 * false} and saves it once the changes have been done. Thus the session can be
107 * rolled back if an exception occurs.
108 *
109 * Warning: no check is done and corresponding privileges are always added, so
110 * only call this when necessary
111 */
112 public void configurePrivileges(Session session) throws RepositoryException {
113 }
114
115 /** The system roles that must be available in the system. */
116 protected Set<String> getRequiredRoles() {
117 return new HashSet<>();
118 }
119
120 public void destroy() {
121
122 }
123
124 /*
125 * UTILITIES
126 */
127
128 /** Create these roles as group if they don't exist. */
129 protected void makeSureRolesExists(EnumSet<? extends Distinguished> enumSet) {
130 makeSureRolesExists(Distinguished.enumToDns(enumSet));
131 }
132
133 /** Create these roles as group if they don't exist. */
134 protected void makeSureRolesExists(Set<String> requiredRoles) {
135 if (requiredRoles == null)
136 return;
137 if (getUserAdmin() == null) {
138 log.warn("No user admin service available, cannot make sure that role exists");
139 return;
140 }
141 for (String role : requiredRoles) {
142 Role systemRole = getUserAdmin().getRole(role);
143 if (systemRole == null) {
144 try {
145 getUserTransaction().begin();
146 getUserAdmin().createRole(role, Role.GROUP);
147 getUserTransaction().commit();
148 log.info("Created role " + role);
149 } catch (Exception e) {
150 try {
151 getUserTransaction().rollback();
152 } catch (Exception e1) {
153 // silent
154 }
155 throw new IllegalStateException("Cannot create role " + role, e);
156 }
157 }
158 }
159 }
160
161 /** Add a user or group to a group. */
162 protected void addToGroup(String groupToAddDn, String groupDn) {
163 if (groupToAddDn.contentEquals(groupDn)) {
164 if (log.isTraceEnabled())
165 log.trace("Ignore adding group " + groupDn + " to itself");
166 return;
167 }
168
169 if (getUserAdmin() == null) {
170 log.warn("No user admin service available, cannot add group " + groupToAddDn + " to " + groupDn);
171 return;
172 }
173 Group groupToAdd = (Group) getUserAdmin().getRole(groupToAddDn);
174 if (groupToAdd == null)
175 throw new IllegalArgumentException("Group " + groupToAddDn + " not found");
176 Group group = (Group) getUserAdmin().getRole(groupDn);
177 if (group == null)
178 throw new IllegalArgumentException("Group " + groupDn + " not found");
179 try {
180 getUserTransaction().begin();
181 if (group.addMember(groupToAdd))
182 log.info("Added " + groupToAddDn + " to " + group);
183 getUserTransaction().commit();
184 } catch (Exception e) {
185 try {
186 getUserTransaction().rollback();
187 } catch (Exception e1) {
188 // silent
189 }
190 throw new IllegalStateException("Cannot add " + groupToAddDn + " to " + groupDn);
191 }
192 }
193
194 /*
195 * DEPENDENCY INJECTION
196 */
197 public void setRepository(Repository repository) {
198 this.repository = repository;
199 }
200
201 // public void setUserAdminService(UserAdminService userAdminService) {
202 // this.userAdminService = userAdminService;
203 // }
204
205 protected WorkTransaction getUserTransaction() {
206 return userTransaction;
207 }
208
209 protected UserAdmin getUserAdmin() {
210 return userAdmin;
211 }
212
213 public void setUserAdmin(UserAdmin userAdmin) {
214 this.userAdmin = userAdmin;
215 }
216
217 public void setUserTransaction(WorkTransaction userTransaction) {
218 this.userTransaction = userTransaction;
219 }
220
221 }