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
;
13 import org
.argeo
.api
.cms
.CmsLog
;
14 import org
.argeo
.cms
.jcr
.CmsJcrUtils
;
15 import org
.argeo
.jcr
.Jcr
;
16 import org
.argeo
.jcr
.JcrUtils
;
17 import org
.argeo
.osgi
.transaction
.WorkTransaction
;
18 import org
.argeo
.util
.naming
.Distinguished
;
19 import org
.osgi
.service
.useradmin
.Group
;
20 import org
.osgi
.service
.useradmin
.Role
;
21 import org
.osgi
.service
.useradmin
.UserAdmin
;
23 /** Make sure roles and access rights are properly configured. */
24 public abstract class AbstractMaintenanceService
{
25 private final static CmsLog log
= CmsLog
.getLog(AbstractMaintenanceService
.class);
27 private Repository repository
;
28 // private UserAdminService userAdminService;
29 private UserAdmin userAdmin
;
30 private WorkTransaction userTransaction
;
33 makeSureRolesExists(getRequiredRoles());
34 configureStandardRoles();
36 Set
<String
> workspaceNames
= getWorkspaceNames();
37 if (workspaceNames
== null || workspaceNames
.isEmpty()) {
38 configureJcr(repository
, null);
40 for (String workspaceName
: workspaceNames
)
41 configureJcr(repository
, workspaceName
);
45 /** Configures a workspace. */
46 protected void configureJcr(Repository repository
, String workspaceName
) {
49 adminSession
= CmsJcrUtils
.openDataAdminSession(repository
, workspaceName
);
50 } catch (RuntimeException e1
) {
51 if (e1
.getCause() != null && e1
.getCause() instanceof NoSuchWorkspaceException
) {
52 Session defaultAdminSession
= CmsJcrUtils
.openDataAdminSession(repository
, null);
54 defaultAdminSession
.getWorkspace().createWorkspace(workspaceName
);
55 log
.info("Created JCR workspace " + workspaceName
);
56 } catch (RepositoryException e
) {
57 throw new IllegalStateException("Cannot create workspace " + workspaceName
, e
);
59 Jcr
.logout(defaultAdminSession
);
61 adminSession
= CmsJcrUtils
.openDataAdminSession(repository
, workspaceName
);
66 if (prepareJcrTree(adminSession
)) {
67 configurePrivileges(adminSession
);
69 } catch (RepositoryException
| IOException e
) {
70 throw new IllegalStateException("Cannot initialise JCR data layer.", e
);
72 JcrUtils
.logoutQuietly(adminSession
);
76 /** To be overridden. */
77 protected Set
<String
> getWorkspaceNames() {
82 * To be overridden in order to programmatically set relationships between
83 * roles. Does nothing by default.
85 protected void configureStandardRoles() {
89 * Creates the base JCR tree structure expected for this app if necessary.
91 * Expects a clean session ({@link Session#hasPendingChanges()} should return
92 * false) and saves it once the changes have been done. Thus the session can be
93 * rolled back if an exception occurs.
95 * @return true if something as been updated
97 public boolean prepareJcrTree(Session adminSession
) throws RepositoryException
, IOException
{
102 * Adds app specific default privileges.
104 * Expects a clean session ({@link Session#hasPendingChanges()} should return
105 * false} and saves it once the changes have been done. Thus the session can be
106 * rolled back if an exception occurs.
108 * Warning: no check is done and corresponding privileges are always added, so
109 * only call this when necessary
111 public void configurePrivileges(Session session
) throws RepositoryException
{
114 /** The system roles that must be available in the system. */
115 protected Set
<String
> getRequiredRoles() {
116 return new HashSet
<>();
119 public void destroy() {
127 /** Create these roles as group if they don't exist. */
128 protected void makeSureRolesExists(EnumSet
<?
extends Distinguished
> enumSet
) {
129 makeSureRolesExists(Distinguished
.enumToDns(enumSet
));
132 /** Create these roles as group if they don't exist. */
133 protected void makeSureRolesExists(Set
<String
> requiredRoles
) {
134 if (requiredRoles
== null)
136 if (getUserAdmin() == null) {
137 log
.warn("No user admin service available, cannot make sure that role exists");
140 for (String role
: requiredRoles
) {
141 Role systemRole
= getUserAdmin().getRole(role
);
142 if (systemRole
== null) {
144 getUserTransaction().begin();
145 getUserAdmin().createRole(role
, Role
.GROUP
);
146 getUserTransaction().commit();
147 log
.info("Created role " + role
);
148 } catch (Exception e
) {
150 getUserTransaction().rollback();
151 } catch (Exception e1
) {
154 throw new IllegalStateException("Cannot create role " + role
, e
);
160 /** Add a user or group to a group. */
161 protected void addToGroup(String groupToAddDn
, String groupDn
) {
162 if (groupToAddDn
.contentEquals(groupDn
)) {
163 if (log
.isTraceEnabled())
164 log
.trace("Ignore adding group " + groupDn
+ " to itself");
168 if (getUserAdmin() == null) {
169 log
.warn("No user admin service available, cannot add group " + groupToAddDn
+ " to " + groupDn
);
172 Group groupToAdd
= (Group
) getUserAdmin().getRole(groupToAddDn
);
173 if (groupToAdd
== null)
174 throw new IllegalArgumentException("Group " + groupToAddDn
+ " not found");
175 Group group
= (Group
) getUserAdmin().getRole(groupDn
);
177 throw new IllegalArgumentException("Group " + groupDn
+ " not found");
179 getUserTransaction().begin();
180 if (group
.addMember(groupToAdd
))
181 log
.info("Added " + groupToAddDn
+ " to " + group
);
182 getUserTransaction().commit();
183 } catch (Exception e
) {
185 getUserTransaction().rollback();
186 } catch (Exception e1
) {
189 throw new IllegalStateException("Cannot add " + groupToAddDn
+ " to " + groupDn
);
194 * DEPENDENCY INJECTION
196 public void setRepository(Repository repository
) {
197 this.repository
= repository
;
200 // public void setUserAdminService(UserAdminService userAdminService) {
201 // this.userAdminService = userAdminService;
204 protected WorkTransaction
getUserTransaction() {
205 return userTransaction
;
208 protected UserAdmin
getUserAdmin() {
212 public void setUserAdmin(UserAdmin userAdmin
) {
213 this.userAdmin
= userAdmin
;
216 public void setUserTransaction(WorkTransaction userTransaction
) {
217 this.userTransaction
= userTransaction
;