1 package org.argeo.connect.core;
2
3 import java.security.PrivilegedExceptionAction;
4 import java.util.Collections;
5 import java.util.Map;
6 import java.util.SortedMap;
7 import java.util.TreeMap;
8
9 import javax.jcr.Repository;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.jcr.security.Privilege;
13 import javax.security.auth.Subject;
14 import javax.security.auth.login.LoginContext;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.argeo.connect.AppMaintenanceService;
19 import org.argeo.connect.ConnectException;
20 import org.argeo.connect.ServiceRanking;
21 import org.argeo.connect.SystemMaintenanceService;
22 import org.argeo.connect.UserAdminService;
23 import org.argeo.jcr.JcrUtils;
24 import org.argeo.node.NodeConstants;
25
26
27 public class DynamicSystemMaintenanceService implements SystemMaintenanceService {
28 private final static Log log = LogFactory.getLog(DynamicSystemMaintenanceService.class);
29
30
31 private Repository repository;
32
33 private UserAdminService userAdminService;
34
35 private SortedMap<ServiceRanking, AppMaintenanceService> maintenanceServices = Collections
36 .synchronizedSortedMap(new TreeMap<>());
37
38
39
40 public void init() {
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 Session adminSession = openAdminSession();
61 try {
62
63 if (prepareJcrTree(adminSession)) {
64 configurePrivileges(adminSession);
65 }
66 } catch (Exception e) {
67 throw new ConnectException("Cannot initialise model", e);
68 } finally {
69 JcrUtils.logoutQuietly(adminSession);
70 }
71 }
72
73
74
75
76
77
78 private Session openAdminSession() {
79 try {
80 LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
81 lc.login();
82 Session session = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Session>() {
83
84 @Override
85 public Session run() throws Exception {
86 return repository.login();
87 }
88
89 });
90 return session;
91 } catch (Exception e) {
92 throw new ConnectException("Cannot login as data admin", e);
93 }
94 }
95
96
97
98
99
100 private final static String jackRabbitVersionSystemPath = "/jcr:system";
101
102 @Override
103 public boolean prepareJcrTree(Session session) {
104 boolean hasCHanged = false;
105 try {
106
107 if (session.hasPendingChanges()) {
108 session.save();
109 hasCHanged = true;
110 }
111 } catch (RepositoryException e) {
112 throw new ConnectException("Cannot build model", e);
113 }
114
115
116
117
118 return hasCHanged;
119 }
120
121 @Override
122 public void configurePrivileges(Session session) {
123 try {
124
125 JcrUtils.clearAccessControList(session, "/", "everyone");
126
127 JcrUtils.addPrivilege(session, jackRabbitVersionSystemPath, OfficeRole.coworker.dn(), Privilege.JCR_READ);
128
129 JcrUtils.addPrivilege(session, "/", NodeConstants.ROLE_ADMIN, Privilege.JCR_ALL);
130
131
132
133
134
135
136
137 session.save();
138 } catch (RepositoryException e) {
139 throw new ConnectException("Cannot build model", e);
140 }
141
142
143 log.info("Access control configured");
144 }
145
146 public void destroy() {
147 }
148
149
150 public void setRepository(Repository repository) {
151 this.repository = repository;
152 }
153
154
155
156
157
158 public void setUserAdminService(UserAdminService userAdminService) {
159 this.userAdminService = userAdminService;
160 }
161
162 public void addAppService(AppMaintenanceService appService, Map<String, Object> properties) {
163 maintenanceServices.put(new ServiceRanking(properties), appService);
164
165
166
167
168
169
170
171
172
173
174 }
175
176 public void removeAppService(AppMaintenanceService appService, Map<String, Object> properties) {
177 maintenanceServices.remove(new ServiceRanking(properties));
178 }
179
180 }