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 groupToAddDn
, String groupDn
) {
163 if (groupToAddDn
.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 " + groupToAddDn
+ " to " + groupDn
);
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
);
178 throw new IllegalArgumentException("Group " + groupDn
+ " not found");
180 getUserTransaction().begin();
181 if (group
.addMember(groupToAdd
))
182 log
.info("Added " + groupToAddDn
+ " to " + group
);
183 getUserTransaction().commit();
184 } catch (Exception e
) {
186 getUserTransaction().rollback();
187 } catch (Exception e1
) {
190 throw new IllegalStateException("Cannot add " + groupToAddDn
+ " to " + groupDn
);
195 * DEPENDENCY INJECTION
197 public void setRepository(Repository repository
) {
198 this.repository
= repository
;
201 // public void setUserAdminService(UserAdminService userAdminService) {
202 // this.userAdminService = userAdminService;
205 protected UserTransaction
getUserTransaction() {
206 return userTransaction
;
209 protected UserAdmin
getUserAdmin() {
213 public void setUserAdmin(UserAdmin userAdmin
) {
214 this.userAdmin
= userAdmin
;
217 public void setUserTransaction(UserTransaction userTransaction
) {
218 this.userTransaction
= userTransaction
;