1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.admincentral.setup;
35
36 import info.magnolia.cms.security.operations.VoterBasedConfiguredAccessDefinition;
37 import info.magnolia.jcr.util.NodeTypes;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.module.InstallContext;
40 import info.magnolia.module.delta.AbstractRepositoryTask;
41 import info.magnolia.module.delta.TaskExecutionException;
42 import info.magnolia.repository.RepositoryConstants;
43 import info.magnolia.voting.voters.RoleBaseVoter;
44
45 import java.util.HashSet;
46 import java.util.Set;
47
48 import javax.jcr.Node;
49 import javax.jcr.NodeIterator;
50 import javax.jcr.RepositoryException;
51 import javax.jcr.Session;
52 import javax.jcr.query.Query;
53 import javax.jcr.query.QueryManager;
54 import javax.jcr.query.QueryResult;
55
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60
61
62 public class ConvertAclToAppPermissionTask extends AbstractRepositoryTask {
63
64 protected static final String APP_PERMISSIONS_PATH = "permissions/";
65 protected static final String APP_ROLES_PATH = "roles/";
66 protected static final String APP_PERMISSIONS_ROLES_PATH = APP_PERMISSIONS_PATH + APP_ROLES_PATH;
67 protected static final String APP_VOTERS_PATH = "voters/";
68 protected static final String APP_DENIED_ROLES_PATH = "deniedRoles/";
69 protected static final String APP_ALLOWED_ROLES_PATH = "allowedRoles/";
70 protected static final String PROPERTY_CLASS_NAME = "class";
71 protected static final String PROPERTY_NOT_NAME = "not";
72 protected static final String SUPERUSER_ROLE = "superuser";
73
74 private static final Logger log = LoggerFactory.getLogger(ConvertAclToAppPermissionTask.class);
75
76 private final String oldURL;
77 private final String[] newApps;
78 private final boolean removeOldPermissions;
79 private final String query;
80
81 public ConvertAclToAppPermissionTask(String name, String description, String oldURL, String[] newApps, boolean removeOldPermissions) {
82 super(name, description);
83 this.oldURL = oldURL;
84 this.newApps = newApps;
85 this.removeOldPermissions = removeOldPermissions;
86 this.query = "select * from ['" + NodeTypes.ContentNode.NAME + "'] as t " +
87 "where [path] = '" + oldURL +
88 "' OR [path] = '" + oldURL + "*" +
89 "' OR [path] = '" + oldURL + "/*'";
90 }
91
92 public ConvertAclToAppPermissionTask(String name, String description, String oldURL, String newApp, boolean removeOldPermissions) {
93 this(name, description, oldURL, new String[]{newApp}, removeOldPermissions);
94 }
95
96 @Override
97 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
98
99 Session config = installContext.getJCRSession(RepositoryConstants.CONFIG);
100 Session userRoles = installContext.getJCRSession(RepositoryConstants.USER_ROLES);
101 QueryManager qm = userRoles.getWorkspace().getQueryManager();
102 Query q = qm.createQuery(query, Query.JCR_SQL2);
103 QueryResult queryResult = q.execute();
104 NodeIterator iter = queryResult.getNodes();
105 Set<Node> permissionsToRemove = new HashSet<Node>();
106
107 while (iter.hasNext()) {
108 Node node = (Node) iter.next();
109 try {
110 Node acl_uri = node.getParent();
111 Node userRole = acl_uri.getParent();
112 if (!userRole.isNodeType(NodeTypes.Role.NAME)) {
113 continue;
114 }
115 String userRoleName = userRole.getName();
116 Long permissions = node.getProperty("permissions").getLong();
117
118 for (String newApp : newApps) {
119 Node newAppNode = config.getNode(newApp);
120
121 if (permissions == 0) {
122 if (!newAppNode.hasNode(APP_PERMISSIONS_ROLES_PATH)) {
123 NodeUtil.createPath(newAppNode, APP_PERMISSIONS_PATH, NodeTypes.ContentNode.NAME).setProperty(PROPERTY_CLASS_NAME, VoterBasedConfiguredAccessDefinition.class.getName());
124 Node deniedRoleNode = NodeUtil.createPath(newAppNode.getNode(APP_PERMISSIONS_PATH), APP_VOTERS_PATH + APP_DENIED_ROLES_PATH, NodeTypes.ContentNode.NAME);
125 deniedRoleNode.setProperty(PROPERTY_CLASS_NAME, RoleBaseVoter.class.getName());
126 deniedRoleNode.setProperty(PROPERTY_NOT_NAME, "true");
127 NodeUtil.createPath(deniedRoleNode, APP_ROLES_PATH, NodeTypes.ContentNode.NAME).setProperty(userRoleName, userRoleName);
128 log.info("Denying permission for '{}' app to role '{}'. Please add extra permissions to this app if required.", newApps, userRoleName);
129 } else if (!newAppNode.getNode(APP_PERMISSIONS_PATH).hasProperty(PROPERTY_CLASS_NAME)) {
130 NodeUtil.createPath(newAppNode, APP_PERMISSIONS_PATH, NodeTypes.ContentNode.NAME).setProperty(PROPERTY_CLASS_NAME, VoterBasedConfiguredAccessDefinition.class.getName());
131 NodeUtil.createPath(newAppNode.getNode(APP_PERMISSIONS_PATH), APP_VOTERS_PATH + APP_ALLOWED_ROLES_PATH, NodeTypes.ContentNode.NAME).setProperty(PROPERTY_CLASS_NAME, RoleBaseVoter.class.getName());
132
133
134 NodeUtil.moveNode(newAppNode.getNode(APP_PERMISSIONS_ROLES_PATH), newAppNode.getNode(APP_PERMISSIONS_PATH + APP_VOTERS_PATH + APP_ALLOWED_ROLES_PATH));
135
136
137 Node deniedRoleNode = NodeUtil.createPath(newAppNode.getNode(APP_PERMISSIONS_PATH), APP_VOTERS_PATH + APP_DENIED_ROLES_PATH, NodeTypes.ContentNode.NAME);
138 deniedRoleNode.setProperty(PROPERTY_CLASS_NAME, RoleBaseVoter.class.getName());
139 deniedRoleNode.setProperty(PROPERTY_NOT_NAME, "true");
140 NodeUtil.createPath(deniedRoleNode, APP_ROLES_PATH, NodeTypes.ContentNode.NAME).setProperty(userRoleName, userRoleName);
141 log.info("Denying permission for '{}' app to role '{}'. Please add extra permissions to this app if required.", newApps, userRoleName);
142 } else if (newAppNode.getNode(APP_PERMISSIONS_PATH).getProperty(PROPERTY_CLASS_NAME).getString().equals(VoterBasedConfiguredAccessDefinition.class.getName())) {
143 Node deniedRolesNode = NodeUtil.createPath(newAppNode.getNode(APP_PERMISSIONS_PATH), APP_VOTERS_PATH + APP_DENIED_ROLES_PATH, NodeTypes.ContentNode.NAME);
144 if (!deniedRolesNode.hasProperty(PROPERTY_CLASS_NAME) || !deniedRolesNode.getProperty(PROPERTY_CLASS_NAME).getString().equals(RoleBaseVoter.class.getName())){
145 final String warnMsg = "Unknown voter class implementation " + deniedRolesNode.getPath() + " . Cannot convert old permission '" + oldURL + "'.";
146 installContext.warn(warnMsg);
147 continue;
148 }
149
150 Node permissionsNode = NodeUtil.createPath(deniedRolesNode, APP_ROLES_PATH, NodeTypes.ContentNode.NAME);
151 if (!permissionsNode.hasProperty(userRoleName)) {
152 permissionsNode.setProperty(userRoleName, userRoleName);
153 log.info("Denying permission for '{}' app to '{}' role.", newApps, userRoleName);
154 }
155 } else {
156 final String warnMsg = "Unknown access permissions class implementation " + newAppNode.getNode(APP_PERMISSIONS_PATH).getPath() + " . Cannot convert old permission '" + oldURL + "'.";
157 installContext.warn(warnMsg);
158 }
159
160 } else {
161 if (newAppNode.hasNode(APP_PERMISSIONS_PATH) && newAppNode.getNode(APP_PERMISSIONS_PATH).hasProperty(PROPERTY_CLASS_NAME) && newAppNode.getNode(APP_PERMISSIONS_PATH).getProperty(PROPERTY_CLASS_NAME).getString().equals(VoterBasedConfiguredAccessDefinition.class.getName())) {
162 Node allowedRolesNode = NodeUtil.createPath(newAppNode.getNode(APP_PERMISSIONS_PATH), APP_VOTERS_PATH + APP_ALLOWED_ROLES_PATH, NodeTypes.ContentNode.NAME);
163 if(!allowedRolesNode.hasProperty(PROPERTY_CLASS_NAME)) {
164 allowedRolesNode.setProperty(PROPERTY_CLASS_NAME, RoleBaseVoter.class.getName());
165 } else if (!allowedRolesNode.getProperty(PROPERTY_CLASS_NAME).getString().equals(RoleBaseVoter.class.getName())){
166 final String warnMsg = "Unknown voter class implementation " + allowedRolesNode.getPath() + " . Cannot convert old permission '" + oldURL + "'.";
167 installContext.warn(warnMsg);
168 continue;
169 }
170
171 Node permissionsNode = NodeUtil.createPath(allowedRolesNode, APP_ROLES_PATH, NodeTypes.ContentNode.NAME);
172 if (!permissionsNode.hasProperty(userRoleName)) {
173 permissionsNode.setProperty(userRoleName, userRoleName);
174 log.info("Adding permission for '{}' app to '{}' role.", newApps, userRoleName);
175 }
176 } else if (!newAppNode.hasNode(APP_PERMISSIONS_PATH) || (newAppNode.hasNode(APP_PERMISSIONS_PATH) && !newAppNode.getNode(APP_PERMISSIONS_PATH).hasProperty(PROPERTY_CLASS_NAME))) {
177 Node permissionsNode = NodeUtil.createPath(newAppNode, APP_PERMISSIONS_ROLES_PATH, NodeTypes.ContentNode.NAME);
178
179 if (!permissionsNode.hasProperty(userRoleName)) {
180 permissionsNode.setProperty(userRoleName, userRoleName);
181 log.info("Adding permission for '{}' app to '{}' role.", newApps, userRoleName);
182 }
183 } else {
184 final String warnMsg = "Unknown access permissions class implementation " + newAppNode.getNode(APP_PERMISSIONS_PATH).getPath() + " . Cannot convert old permission '" + oldURL + "'.";
185 installContext.warn(warnMsg);
186 }
187 }
188 }
189
190 if (this.removeOldPermissions) {
191 permissionsToRemove.add(node);
192 log.info("Obsolete permission property '{}={}' for role '{}' will be removed.", node.getProperty("path").getString(), permissions, userRoleName);
193 }
194
195 } catch (RepositoryException e) {
196 final String errMsg = "Cannot convert old permission '" + oldURL + "' to permissions to new apps.";
197 log.error(errMsg);
198 throw new TaskExecutionException(errMsg, e);
199 }
200 }
201
202 for (Node node : permissionsToRemove) {
203 node.remove();
204 }
205 }
206 }