View Javadoc
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  /** Make the DJay-ing to provide a full running Suite platform */
27  public class DynamicSystemMaintenanceService implements SystemMaintenanceService {
28  	private final static Log log = LogFactory.getLog(DynamicSystemMaintenanceService.class);
29  
30  	/* DEPENDENCY INJECTION */
31  	private Repository repository;
32  	// private String workspaceName = "main";
33  	private UserAdminService userAdminService;
34  
35  	private SortedMap<ServiceRanking, AppMaintenanceService> maintenanceServices = Collections
36  			.synchronizedSortedMap(new TreeMap<>());
37  	// private List<AppMaintenanceService> maintenanceServices =
38  	// Collections.synchronizedList(new ArrayList<>());
39  
40  	public void init() {
41  //		List<String> requiredRoles = getRequiredRoles();
42  //		for (String role : requiredRoles) {
43  //			Role systemRole = userAdminService.getUserAdmin().getRole(role);
44  //			if (systemRole == null) {
45  //				try {
46  //					userAdminService.getUserTransaction().begin();
47  //					userAdminService.getUserAdmin().createRole(role, Role.GROUP);
48  //					userAdminService.getUserTransaction().commit();
49  //				} catch (Exception e) {
50  //					log.error("Cannot create role " + role, e);
51  //					try {
52  //						userAdminService.getUserTransaction().rollback();
53  //					} catch (Exception e1) {
54  //						// silent
55  //					}
56  //				}
57  //			}
58  //		}
59  
60  		Session adminSession = openAdminSession();
61  		try {
62  			// adminSession = repository.login(workspaceName);
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  //	@Override
74  //	public List<String> getRequiredRoles() {
75  //		return AbstractMaintenanceService.enumToDns(EnumSet.allOf(OfficeRole.class));
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  	// To be cleaned once first init and config mechanisms have been implemented
97  	// private final static String publicPath = "/public";
98  	// FIXME Users must have read access on the jcr:system/jcr:versionStorage
99  	// node under JackRabbit to be able to manage versions
100 	private final static String jackRabbitVersionSystemPath = "/jcr:system";
101 
102 	@Override
103 	public boolean prepareJcrTree(Session session) {
104 		boolean hasCHanged = false;
105 		try {
106 			// JcrUtils.mkdirs(session, publicPath, NodeType.NT_UNSTRUCTURED);
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 //		for (AppMaintenanceService service : maintenanceServices.values())
115 //			hasCHanged |= service.prepareJcrTree(session);
116 //		if (hasCHanged)
117 //			log.info("Repository has been initialised with Argeo Suite model");
118 		return hasCHanged;
119 	}
120 
121 	@Override
122 	public void configurePrivileges(Session session) {
123 		try {
124 			// Remove unused default JCR rights
125 			JcrUtils.clearAccessControList(session, "/", "everyone");
126 
127 			JcrUtils.addPrivilege(session, jackRabbitVersionSystemPath, OfficeRole.coworker.dn(), Privilege.JCR_READ);
128 			// Default configuration of the workspace
129 			JcrUtils.addPrivilege(session, "/", NodeConstants.ROLE_ADMIN, Privilege.JCR_ALL);
130 			// JcrUtils.addPrivilege(session, publicPath,
131 			// NodeConstants.ROLE_USER, Privilege.JCR_READ);
132 			// JcrUtils.addPrivilege(session, publicPath, "anonymous",
133 			// Privilege.JCR_READ);
134 			// JcrUtils.addPrivilege(session, publicPath,
135 			// NodeConstants.ROLE_ANONYMOUS, Privilege.JCR_READ);
136 
137 			session.save();
138 		} catch (RepositoryException e) {
139 			throw new ConnectException("Cannot build model", e);
140 		}
141 //		for (AppMaintenanceService service : maintenanceServices.values())
142 //			service.configurePrivileges(session);
143 		log.info("Access control configured");
144 	}
145 
146 	public void destroy() {
147 	}
148 
149 	/* DEPENDENCY INJECTION */
150 	public void setRepository(Repository repository) {
151 		this.repository = repository;
152 	}
153 
154 	// public void setWorkspaceName(String workspaceName) {
155 	// this.workspaceName = workspaceName;
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 		// Session adminSession = openAdminSession();
165 		// try {
166 		// if (appService.prepareJcrTree(adminSession)) {
167 		// appService.configurePrivileges(adminSession);
168 		// }
169 		// if (log.isDebugEnabled())
170 		// log.debug("Added maintenance service " + appService);
171 		// } finally {
172 		// JcrUtils.logoutQuietly(adminSession);
173 		// }
174 	}
175 
176 	public void removeAppService(AppMaintenanceService appService, Map<String, Object> properties) {
177 		maintenanceServices.remove(new ServiceRanking(properties));
178 	}
179 
180 }