View Javadoc
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 						// silent
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 				// silent
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 }