1 package org.argeo.connect.core;
2
3 import java.security.PrivilegedExceptionAction;
4 import java.util.ArrayList;
5 import java.util.EnumSet;
6 import java.util.List;
7
8 import javax.jcr.Repository;
9 import javax.jcr.Session;
10 import javax.security.auth.Subject;
11 import javax.security.auth.login.LoginContext;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.argeo.connect.AppMaintenanceService;
16 import org.argeo.connect.ConnectException;
17 import org.argeo.connect.UserAdminService;
18 import org.argeo.jcr.JcrUtils;
19 import org.argeo.naming.Distinguished;
20 import org.argeo.node.NodeConstants;
21 import org.osgi.service.useradmin.Group;
22 import org.osgi.service.useradmin.Role;
23
24 public abstract class AbstractMaintenanceService implements AppMaintenanceService {
25 private final static Log log = LogFactory.getLog(AbstractMaintenanceService.class);
26
27 private Repository repository;
28 private UserAdminService userAdminService;
29
30 public void init() {
31 makeSureRolesExists(EnumSet.allOf(OfficeRole.class));
32 addManagersToGroup(OfficeRole.coworker.dn());
33 makeSureRolesExists(getRequiredRoles());
34 addOfficeGroups();
35
36 Session adminSession = openAdminSession();
37 try {
38 if (prepareJcrTree(adminSession)) {
39 configurePrivileges(adminSession);
40 }
41 } finally {
42 JcrUtils.logoutQuietly(adminSession);
43 }
44 }
45
46 protected void addOfficeGroups() {
47
48 }
49
50 public void destroy() {
51
52 }
53
54 private Session openAdminSession() {
55 try {
56 LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
57 lc.login();
58 Session session = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Session>() {
59
60 @Override
61 public Session run() throws Exception {
62 return repository.login();
63 }
64
65 });
66 return session;
67 } catch (Exception e) {
68 throw new ConnectException("Cannot login as data admin", e);
69 }
70 }
71
72 protected static List<String> enumToDns(EnumSet<? extends Distinguished> enumSet) {
73 List<String> res = new ArrayList<>();
74 for (Enum<? extends Distinguished> enm : enumSet) {
75 res.add(((Distinguished) enm).dn());
76 }
77 return res;
78 }
79
80 protected void makeSureRolesExists(EnumSet<? extends Distinguished> enumSet) {
81 makeSureRolesExists(enumToDns(enumSet));
82 }
83
84 protected void makeSureRolesExists(List<String> requiredRoles) {
85 if (requiredRoles == null)
86 return;
87 if (userAdminService == null) {
88 log.warn("No user admin service available, cannot make sure that role exists");
89 return;
90 }
91 for (String role : requiredRoles) {
92 Role systemRole = userAdminService.getUserAdmin().getRole(role);
93 if (systemRole == null) {
94 try {
95 userAdminService.getUserTransaction().begin();
96 userAdminService.getUserAdmin().createRole(role, Role.GROUP);
97 userAdminService.getUserTransaction().commit();
98 log.info("Created role " + role);
99 } catch (Exception e) {
100 try {
101 userAdminService.getUserTransaction().rollback();
102 } catch (Exception e1) {
103
104 }
105 throw new ConnectException("Cannot create role " + role, e);
106 }
107 }
108 }
109 }
110
111 protected void addManagersToGroup(String groupDn) {
112 addToGroup(OfficeRole.manager.dn(), groupDn);
113 }
114
115 protected void addCoworkersToGroup(String groupDn) {
116 addToGroup(OfficeRole.coworker.dn(), groupDn);
117 }
118
119 private void addToGroup(String officeGroup, String groupDn) {
120 if (userAdminService == null) {
121 log.warn("No user admin service available, cannot add group " + officeGroup + " to " + groupDn);
122 return;
123 }
124 Group managerGroup = (Group) userAdminService.getUserAdmin().getRole(officeGroup);
125 Group group = (Group) userAdminService.getUserAdmin().getRole(groupDn);
126 if (group == null)
127 throw new ConnectException("Group " + groupDn + " not found");
128 try {
129 userAdminService.getUserTransaction().begin();
130 if (group.addMember(managerGroup))
131 log.info("Added " + officeGroup + " to " + group);
132 userAdminService.getUserTransaction().commit();
133 } catch (Exception e) {
134 try {
135 userAdminService.getUserTransaction().rollback();
136 } catch (Exception e1) {
137
138 }
139 throw new ConnectException("Cannot add " + managerGroup + " to " + group);
140 }
141 }
142
143 public void setRepository(Repository repository) {
144 this.repository = repository;
145 }
146
147 public void setUserAdminService(UserAdminService userAdminService) {
148 this.userAdminService = userAdminService;
149 }
150
151 }