1 package org
.argeo
.maintenance
;
3 import java
.io
.IOException
;
4 import java
.util
.EnumSet
;
5 import java
.util
.HashSet
;
8 import javax
.jcr
.NoSuchWorkspaceException
;
9 import javax
.jcr
.Repository
;
10 import javax
.jcr
.RepositoryException
;
11 import javax
.jcr
.Session
;
12 import javax
.transaction
.UserTransaction
;
14 import org
.apache
.commons
.logging
.Log
;
15 import org
.apache
.commons
.logging
.LogFactory
;
16 import org
.argeo
.api
.NodeUtils
;
17 import org
.argeo
.jcr
.Jcr
;
18 import org
.argeo
.jcr
.JcrUtils
;
19 import org
.argeo
.naming
.Distinguished
;
20 import org
.osgi
.service
.useradmin
.Group
;
21 import org
.osgi
.service
.useradmin
.Role
;
22 import org
.osgi
.service
.useradmin
.UserAdmin
;
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);
28 private Repository repository
;
29 // private UserAdminService userAdminService;
30 private UserAdmin userAdmin
;
31 private UserTransaction userTransaction
;
34 makeSureRolesExists(getRequiredRoles());
35 configureStandardRoles();
37 Set
<String
> workspaceNames
= getWorkspaceNames();
38 if (workspaceNames
== null || workspaceNames
.isEmpty()) {
39 configureJcr(repository
, null);
41 for (String workspaceName
: workspaceNames
)
42 configureJcr(repository
, workspaceName
);
46 /** Configures a workspace. */
47 protected void configureJcr(Repository repository
, String workspaceName
) {
50 adminSession
= NodeUtils
.openDataAdminSession(repository
, workspaceName
);
51 } catch (RuntimeException e1
) {
52 if (e1
.getCause() != null && e1
.getCause() instanceof NoSuchWorkspaceException
) {
53 Session defaultAdminSession
= NodeUtils
.openDataAdminSession(repository
, null);
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
);
60 Jcr
.logout(defaultAdminSession
);
62 adminSession
= NodeUtils
.openDataAdminSession(repository
, workspaceName
);
67 if (prepareJcrTree(adminSession
)) {
68 configurePrivileges(adminSession
);
70 } catch (RepositoryException
| IOException e
) {
71 throw new IllegalStateException("Cannot initialise JCR data layer.", e
);
73 JcrUtils
.logoutQuietly(adminSession
);
77 /** To be overridden. */
78 protected Set
<String
> getWorkspaceNames() {
83 * To be overridden in order to programmatically set relationships between
84 * roles. Does nothing by default.
86 protected void configureStandardRoles() {
90 * Creates the base JCR tree structure expected for this app if necessary.
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.
96 * @return true if something as been updated
98 public boolean prepareJcrTree(Session adminSession
) throws RepositoryException
, IOException
{
103 * Adds app specific default privileges.
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.
109 * Warning: no check is done and corresponding privileges are always added, so
110 * only call this when necessary
112 public void configurePrivileges(Session session
) throws RepositoryException
{
115 /** The system roles that must be available in the system. */
116 protected Set
<String
> getRequiredRoles() {
117 return new HashSet
<>();
120 public void destroy() {
128 /** Create these roles as group if they don't exist. */
129 protected void makeSureRolesExists(EnumSet
<?
extends Distinguished
> enumSet
) {
130 makeSureRolesExists(Distinguished
.enumToDns(enumSet
));
133 /** Create these roles as group if they don't exist. */
134 protected void makeSureRolesExists(Set
<String
> requiredRoles
) {
135 if (requiredRoles
== null)
137 if (getUserAdmin() == null) {
138 log
.warn("No user admin service available, cannot make sure that role exists");
141 for (String role
: requiredRoles
) {
142 Role systemRole
= getUserAdmin().getRole(role
);
143 if (systemRole
== null) {
145 getUserTransaction().begin();
146 getUserAdmin().createRole(role
, Role
.GROUP
);
147 getUserTransaction().commit();
148 log
.info("Created role " + role
);
149 } catch (Exception e
) {
151 getUserTransaction().rollback();
152 } catch (Exception e1
) {
155 throw new IllegalStateException("Cannot create role " + role
, e
);
161 /** Add a user or group to a group. */
162 protected void addToGroup(String roledDn
, String groupDn
) {
163 if (roledDn
.contentEquals(groupDn
)) {
164 if (log
.isTraceEnabled())
165 log
.trace("Ignore adding group " + groupDn
+ " to itself");
169 if (getUserAdmin() == null) {
170 log
.warn("No user admin service available, cannot add group " + roledDn
+ " to " + groupDn
);
173 Group managerGroup
= (Group
) getUserAdmin().getRole(roledDn
);
174 Group group
= (Group
) getUserAdmin().getRole(groupDn
);
176 throw new IllegalArgumentException("Group " + groupDn
+ " not found");
178 getUserTransaction().begin();
179 if (group
.addMember(managerGroup
))
180 log
.info("Added " + roledDn
+ " to " + group
);
181 getUserTransaction().commit();
182 } catch (Exception e
) {
184 getUserTransaction().rollback();
185 } catch (Exception e1
) {
188 throw new IllegalStateException("Cannot add " + managerGroup
+ " to " + group
);
193 * DEPENDENCY INJECTION
195 public void setRepository(Repository repository
) {
196 this.repository
= repository
;
199 // public void setUserAdminService(UserAdminService userAdminService) {
200 // this.userAdminService = userAdminService;
203 protected UserTransaction
getUserTransaction() {
204 return userTransaction
;
207 protected UserAdmin
getUserAdmin() {
211 public void setUserAdmin(UserAdmin userAdmin
) {
212 this.userAdmin
= userAdmin
;
215 public void setUserTransaction(UserTransaction userTransaction
) {
216 this.userTransaction
= userTransaction
;