This is an automated email from the ASF dual-hosted git repository.
dklco pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceuser-webconsole.git
The following commit(s) were added to refs/heads/master by this push:
new 26b6663 Fixing an issue where it failed to start without xss compat,
wasn't serving the js file and didn't create the app folder correctly
26b6663 is described below
commit 26b6663275b7f636f0eaaa397a82c3c51c602cea
Author: Dan Klco <[email protected]>
AuthorDate: Fri Jan 12 17:44:11 2018 -0500
Fixing an issue where it failed to start without xss compat, wasn't serving
the js file and didn't create the app folder correctly
---
pom.xml | 290 +++++++-------
.../impl/ServiceUserWebConsolePlugin.java | 417 ++++++++++++---------
2 files changed, 379 insertions(+), 328 deletions(-)
diff --git a/pom.xml b/pom.xml
index aa6e3d4..97e097e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,154 +1,162 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor
+ license agreements. See the NOTICE file distributed with this work for
additional
+ information regarding copyright ownership. The ASF licenses this file
to
+ you under the Apache License, Version 2.0 (the "License"); you may not
use
+ this file except in compliance with the License. You may obtain a copy
of
+ the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
required
+ by applicable law or agreed to in writing, software distributed under
the
+ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS
+ OF ANY KIND, either express or implied. See the License for the
specific
+ language governing permissions and limitations under the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.sling</groupId>
- <artifactId>sling</artifactId>
- <version>30</version>
- <relativePath />
- </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>30</version>
+ <relativePath />
+ </parent>
- <artifactId>org.apache.sling.serviceuser.webconsole</artifactId>
- <packaging>bundle</packaging>
- <version>1.0.1-SNAPSHOT</version>
+ <artifactId>org.apache.sling.serviceuser.webconsole</artifactId>
+ <packaging>bundle</packaging>
+ <version>1.0.0-SNAPSHOT</version>
- <name>Apache Sling Service User Web Console</name>
- <description>
+ <name>Apache Sling Service User Web Console</name>
+ <description>
Provides an OSGi Web Console for creating, updating and viewing
Service Users.
</description>
- <scm>
-
<connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceuser-webconsole.git</connection>
-
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceuser-webconsole.git</developerConnection>
-
<url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-serviceuser-webconsole.git</url>
- <tag>HEAD</tag>
- </scm>
+ <scm>
+
<connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceuser-webconsole.git</connection>
+
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceuser-webconsole.git</developerConnection>
+
<url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-serviceuser-webconsole.git</url>
+ <tag>HEAD</tag>
+ </scm>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <configuration>
- <excludePackageNames>
- org.apache.sling.serviceuser.console.impl
- </excludePackageNames>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.api</artifactId>
- <version>2.5.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ <!-- Support XSS API
1.x and 2.x - we use only classes from the API
+ with same
signature in both versions -->
+
org.apache.sling.xss;version="[1.0.0,3)",
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <excludePackageNames>
+
org.apache.sling.serviceuser.console.impl
+ </excludePackageNames>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <version>2.5.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.serviceusermapper</artifactId>
<version>1.4.0</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- JCR Specific items -->
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-api</artifactId>
- <version>2.10.6</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.jcr</groupId>
- <artifactId>jcr</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.jcr.base</artifactId>
- <version>2.1.0</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
+ <scope>provided</scope>
+ </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <version>4.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.3.2</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- Webconsole Dependencies -->
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.webconsole</artifactId>
- <version>4.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.xss</artifactId>
- <version>1.0.0</version>
- <scope>provided</scope>
- </dependency>
+ <!-- JCR Specific items -->
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-api</artifactId>
+ <version>2.10.6</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.jcr.base</artifactId>
+ <version>2.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-jcr-commons</artifactId>
+ <version>2.0.0</version>
+ <scope>provided</scope>
+ </dependency>
- <!-- Testing -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>1.9.5</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>4.2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.3.2</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Webconsole Dependencies -->
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.webconsole</artifactId>
+ <version>4.2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.xss</artifactId>
+ <version>1.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.9.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
</project>
diff --git
a/src/main/java/org/apache/sling/serviceuser/webconsole/impl/ServiceUserWebConsolePlugin.java
b/src/main/java/org/apache/sling/serviceuser/webconsole/impl/ServiceUserWebConsolePlugin.java
index fd9ab5f..5d952fa 100644
---
a/src/main/java/org/apache/sling/serviceuser/webconsole/impl/ServiceUserWebConsolePlugin.java
+++
b/src/main/java/org/apache/sling/serviceuser/webconsole/impl/ServiceUserWebConsolePlugin.java
@@ -21,6 +21,7 @@ package org.apache.sling.serviceuser.webconsole.impl;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Array;
+import java.net.URL;
import java.net.URLEncoder;
import java.security.Principal;
import java.util.ArrayList;
@@ -35,7 +36,6 @@ import java.util.Map;
import java.util.Map.Entry;
import javax.jcr.AccessDeniedException;
-import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
@@ -56,17 +56,20 @@ import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
-import org.apache.felix.webconsole.SimpleWebConsolePlugin;
+import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.felix.webconsole.WebConsoleUtil;
+import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.base.util.AccessControlUtil;
@@ -93,11 +96,7 @@ import org.slf4j.LoggerFactory;
WebConsoleConstants.PLUGIN_TITLE + "=" +
ServiceUserWebConsolePlugin.TITLE,
WebConsoleConstants.PLUGIN_CATEGORY + "=Sling" })
@SuppressWarnings("serial")
-public class ServiceUserWebConsolePlugin extends SimpleWebConsolePlugin {
-
- public ServiceUserWebConsolePlugin() {
- super(LABEL, TITLE, "Sling", new String[0]);
- }
+public class ServiceUserWebConsolePlugin extends AbstractWebConsolePlugin {
public static final String COMPONENT_NAME =
"org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended";
public static final String LABEL = "serviceusers";
@@ -119,6 +118,9 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
@Reference(policyOption = ReferencePolicyOption.GREEDY)
private XSSAPI xss;
+ @Reference(policyOption = ReferencePolicyOption.GREEDY)
+ private ResourceResolverFactory resolverFactory;
+
@Reference
private ServiceUserMapper mapper;
@@ -137,11 +139,11 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
config = configs.next();
log.debug("Using existing configuration {}",
config);
} else {
- String path = appPath + "/config/" +
COMPONENT_NAME + "-" + appPath.substring(appPath.lastIndexOf('/'));
+ String path = appPath + "/config/" +
COMPONENT_NAME + "-" + appPath.substring(appPath.lastIndexOf('/') + 1);
log.debug("Creating new configuration {}",
path);
config =
ResourceUtil.getOrCreateResource(resolver, path, new HashMap<String, Object>() {
{
- put(Property.JCR_PRIMARY_TYPE,
"sling:OsgiConfig");
+
put(JcrConstants.JCR_PRIMARYTYPE, "sling:OsgiConfig");
}
}, NodeType.NT_FOLDER, false);
dirty = true;
@@ -223,102 +225,6 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
}
- private boolean updatePrivileges(HttpServletRequest request,
ResourceResolver resolver) {
-
- List<Pair<String, String>> privileges =
this.getPrivileges(request);
- String name = getParameter(request, PN_NAME, "");
-
- List<String> currentPolicies = new ArrayList<String>();
- findACLs(resolver, name, currentPolicies);
- for (int i = 0; i < currentPolicies.size(); i++) {
- String path =
StringUtils.substringBefore(currentPolicies.get(i), "/rep:policy");
- currentPolicies.set(i, StringUtils.isNotBlank(path) ?
path : "/");
- }
- log.debug("Loaded current policy paths: {}", currentPolicies);
-
- Map<String, List<String>> toSet = new HashMap<String,
List<String>>();
- for (Pair<String, String> privilege : privileges) {
- if (!toSet.containsKey(privilege.getKey())) {
- toSet.put(privilege.getKey(), new
ArrayList<String>());
- }
- toSet.get(privilege.getKey()).add(privilege.getValue());
- }
- log.debug("Loaded updated policy paths: {}", currentPolicies);
-
- String lastEntry = null;
-
- try {
-
- Session session = resolver.adaptTo(Session.class);
- AccessControlManager accessManager =
session.getAccessControlManager();
- PrincipalManager principalManager =
AccessControlUtil.getPrincipalManager(session);
-
- for (Entry<String, List<String>> pol :
toSet.entrySet()) {
- lastEntry = pol.getKey();
- currentPolicies.remove(pol.getKey());
- log.debug("Updating policies for {}",
pol.getKey());
-
- AccessControlPolicy[] policies =
accessManager.getPolicies(pol.getKey());
- List<String> toRemove = new ArrayList<String>();
- for (AccessControlPolicy p : policies) {
- if (p instanceof AccessControlList) {
- AccessControlList policy =
(AccessControlList) p;
- for (AccessControlEntry entry :
policy.getAccessControlEntries()) {
- Principal prin =
entry.getPrincipal();
- if
(prin.getName().equals(name)) {
- for (Privilege
privilege : entry.getPrivileges()) {
- if
(!pol.getValue().contains(privilege.getName())) {
-
log.debug("Removing privilege {}", privilege);
-
toRemove.add(privilege.getName());
- }
- }
- }
- }
- }
- }
- Principal principal =
principalManager.getPrincipal(name);
-
AccessControlUtil.replaceAccessControlEntry(session, pol.getKey(), principal,
- pol.getValue().toArray(new
String[pol.getValue().size()]), new String[0],
- toRemove.toArray(new
String[toRemove.size()]), null);
- }
- session.save();
-
- for (String oldPolicy : currentPolicies) {
- boolean removed = false;
- log.debug("Removing policy for {}", oldPolicy);
- AccessControlPolicy[] policies =
accessManager.getPolicies(oldPolicy);
- AccessControlEntry toRemove = null;
- for (AccessControlPolicy p : policies) {
- if (p instanceof AccessControlList) {
- AccessControlList policy =
(AccessControlList) p;
- for (AccessControlEntry entry :
policy.getAccessControlEntries()) {
- Principal prin =
entry.getPrincipal();
- if
(prin.getName().equals(name)) {
- toRemove =
entry;
- break;
- }
- }
- if (toRemove != null) {
- removed = true;
-
policy.removeAccessControlEntry(toRemove);
-
accessManager.setPolicy(oldPolicy, policy);
- session.save();
- log.debug("Removed
access control entry {}", toRemove);
- }
- }
- }
- if (!removed) {
- log.warn("No policy found for {}",
oldPolicy);
- }
- }
- } catch (RepositoryException e) {
- log.error("Exception updating principals with {},
failed on {}", toSet, lastEntry, e);
- return false;
- }
-
- return true;
- }
-
private List<String> extractPrincipals(Mapping mapping) {
List<String> principals = new ArrayList<String>();
String userName = mapping.map(mapping.getServiceName(),
mapping.getSubServiceName());
@@ -404,6 +310,11 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
return bundles;
}
+ @Override
+ public String getLabel() {
+ return LABEL;
+ }
+
private Resource getOrCreateServiceUser(HttpServletRequest request,
ResourceResolver resolver) {
final String name = getParameter(request, PN_NAME, "");
@@ -450,12 +361,86 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
return defaultValue;
}
+ private List<Pair<String, String>> getPrivileges(HttpServletRequest
request) {
+ List<Pair<String, String>> privileges = new
ArrayList<Pair<String, String>>();
+ List<String> params =
Collections.list(request.getParameterNames());
+
+ for (String param : params) {
+ if (param.startsWith("acl-path-")) {
+ String path = request.getParameter(param);
+ String privilege =
request.getParameter(param.replace("-path-", "-privilege-"));
+ if (StringUtils.isNotBlank(path) &&
StringUtils.isNotBlank(privilege)) {
+ privileges.add(new
ImmutablePair<String, String>(path, privilege));
+ } else {
+ log.warn("Unable to load ACL due to
missing value {}={}", path, privilege);
+ }
+ }
+ }
+
+ return privileges;
+ }
+
+ @SuppressWarnings("deprecation")
private ResourceResolver getResourceResolver(HttpServletRequest
request) {
- ResourceResolver resolver = (ResourceResolver) request
-
.getAttribute("org.apache.sling.auth.core.ResourceResolver");
+ ResourceResolver resolver = null;
+ try {
+ resolver = (ResourceResolver)
request.getAttribute("org.apache.sling.auth.core.ResourceResolver");
+ if (resolver == null) {
+ log.warn("Resource resolver not available in
request, falling back to adminstrative resource resolver");
+ resolver =
resolverFactory.getAdministrativeResourceResolver(null);
+ }
+ } catch (LoginException le) {
+ throw new RuntimeException(
+ "Unable to get Administrative Resource
Resolver, add the bundle org.apache.sling.serviceuser.webconsole in the Apache
Sling Login Admin Whitelist",
+ le);
+ }
return resolver;
}
+ /**
+ * Called internally by {@link AbstractWebConsolePlugin} to load
resources.
+ *
+ * This particular implementation depends on the label. As example, if
the
+ * plugin is accessed as <code>/system/console/abc</code>, and the
plugin
+ * resources are accessed like
+ * <code>/system/console/abc/res/logo.gif</code>, the code here will try
+ * load resource <code>/res/logo.gif</code> from the bundle, providing
the
+ * plugin.
+ *
+ *
+ * @param path
+ * the path to read.
+ * @return the URL of the resource or <code>null</code> if not found.
+ */
+ protected URL getResource(String path) {
+ String base = "/" + LABEL + "/";
+ return (path != null && path.startsWith(base)) ?
getClass().getResource(path.substring(base.length() - 1))
+ : null;
+ }
+
+ private String[] getSupportedPrivileges(HttpServletRequest request) {
+ String[] names = null;
+ try {
+ ResourceResolver resolver =
getResourceResolver(request);
+ Session session = resolver.adaptTo(Session.class);
+ AccessControlManager accessControl =
session.getAccessControlManager();
+ Privilege[] privileges =
accessControl.getSupportedPrivileges("/");
+ names = new String[privileges.length];
+ for (int i = 0; i < privileges.length; i++) {
+ names[i] = privileges[i].getName();
+ }
+ Arrays.sort(names);
+ } catch (RepositoryException re) {
+ log.error("Exception loading Supported Privileges", re);
+ }
+ return names;
+ }
+
+ @Override
+ public String getTitle() {
+ return TITLE;
+ }
+
private boolean hasPrincipal(Mapping map, String name) {
Iterable<String> principals =
map.mapPrincipals(map.getServiceName(), map.getSubServiceName());
if (principals != null) {
@@ -533,6 +518,48 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
}
+ private void printPrivilegeSelect(PrintWriter pw, String label,
List<Pair<String, String>> privileges,
+ String[] supportedPrivileges, String alertMessage) {
+ pw.print("<td style='width:20%'>");
+ pw.print(xss.encodeForHTMLAttr(label));
+ pw.println("</td>");
+ pw.print("<td><table class=\"repeating-container\"
style=\"width: 100%\" data-length=\"" + privileges.size()
+ +
"\"><tr><td>Path</td><td>Privilege</td><td></td>");
+
+ int idx = 0;
+ for (Pair<String, String> privilege : privileges) {
+ pw.print("</tr><tr class=\"repeating-item\"><td>");
+
+ pw.print("<input type=\"text\" name=\"acl-path-" + idx
+ "\" value='");
+
pw.print(xss.encodeForHTMLAttr(StringUtils.defaultString(privilege.getKey())));
+ pw.print("' style='width:100%' />");
+
+ pw.print("</td><td>");
+
+ pw.print("<input type=\"text\" list=\"data-privileges\"
name=\"acl-privilege-" + idx + "\" value='");
+
pw.print(xss.encodeForHTMLAttr(StringUtils.defaultString(privilege.getValue())));
+ pw.print("' style='width:100%' />");
+
+ pw.print("</td><td>");
+
+ pw.print("<input type=\"button\"
value=\" - \" class=\"repeating-remove\" /></td>");
+ }
+ pw.print("</tr></table>");
+
+ pw.print("<input type=\"button\" value=\" + \"
class=\"repeating-add\" />");
+
+ pw.print("<datalist id=\"data-privileges\">");
+ for (String option : supportedPrivileges) {
+ pw.print("<option");
+ pw.print(">");
+ pw.print(xss.encodeForHTMLAttr(option));
+ pw.print("</option>");
+ }
+ pw.print("</datalist><script
src=\"/system/console/serviceusers/res/ui/serviceusermanager.js\"></script>");
+ infoDiv(pw, alertMessage);
+ pw.println("</td>");
+ }
+
private void printServiceUserDetails(HttpServletRequest request,
PrintWriter pw)
throws AccessDeniedException,
UnsupportedRepositoryOperationException, RepositoryException {
String name = getParameter(request, PN_USER, "");
@@ -676,44 +703,6 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
}
}
- private List<Pair<String, String>> getPrivileges(HttpServletRequest
request) {
- List<Pair<String, String>> privileges = new
ArrayList<Pair<String, String>>();
- List<String> params =
Collections.list(request.getParameterNames());
-
- for (String param : params) {
- if (param.startsWith("acl-path-")) {
- String path = request.getParameter(param);
- String privilege =
request.getParameter(param.replace("-path-", "-privilege-"));
- if (StringUtils.isNotBlank(path) &&
StringUtils.isNotBlank(privilege)) {
- privileges.add(new
ImmutablePair<String, String>(path, privilege));
- } else {
- log.warn("Unable to load ACL due to
missing value {}={}", path, privilege);
- }
- }
- }
-
- return privileges;
- }
-
- private String[] getSupportedPrivileges(HttpServletRequest request) {
- String[] names = null;
- try {
- ResourceResolver resolver =
getResourceResolver(request);
- Session session = resolver.adaptTo(Session.class);
- AccessControlManager accessControl =
session.getAccessControlManager();
- Privilege[] privileges =
accessControl.getSupportedPrivileges("/");
- names = new String[privileges.length];
- for (int i = 0; i < privileges.length; i++) {
- names[i] = privileges[i].getName();
- }
- Arrays.sort(names);
- } catch (RepositoryException re) {
- log.error("Exception loading Supported Privileges", re);
- }
- return names;
-
- }
-
@Override
protected void renderContent(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
@@ -745,48 +734,6 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
}
}
- private void printPrivilegeSelect(PrintWriter pw, String label,
List<Pair<String, String>> privileges,
- String[] supportedPrivileges, String alertMessage) {
- pw.print("<td style='width:20%'>");
- pw.print(xss.encodeForHTMLAttr(label));
- pw.println("</td>");
- pw.print("<td><table class=\"repeating-container\"
style=\"width: 100%\" data-length=\"" + privileges.size()
- +
"\"><tr><td>Path</td><td>Privilege</td><td></td>");
-
- int idx = 0;
- for (Pair<String, String> privilege : privileges) {
- pw.print("</tr><tr class=\"repeating-item\"><td>");
-
- pw.print("<input type=\"text\" name=\"acl-path-" + idx
+ "\" value='");
-
pw.print(xss.encodeForHTMLAttr(StringUtils.defaultString(privilege.getKey())));
- pw.print("' style='width:100%' />");
-
- pw.print("</td><td>");
-
- pw.print("<input type=\"text\" list=\"data-privileges\"
name=\"acl-privilege-" + idx + "\" value='");
-
pw.print(xss.encodeForHTMLAttr(StringUtils.defaultString(privilege.getValue())));
- pw.print("' style='width:100%' />");
-
- pw.print("</td><td>");
-
- pw.print("<input type=\"button\"
value=\" - \" class=\"repeating-remove\" /></td>");
- }
- pw.print("</tr></table>");
-
- pw.print("<input type=\"button\" value=\" + \"
class=\"repeating-add\" />");
-
- pw.print("<datalist id=\"data-privileges\">");
- for (String option : supportedPrivileges) {
- pw.print("<option");
- pw.print(">");
- pw.print(xss.encodeForHTMLAttr(option));
- pw.print("</option>");
- }
- pw.print("</datalist><script
src=\"/system/console/serviceusers/res/ui/serviceusermanager.js\"></script>");
- infoDiv(pw, alertMessage);
- pw.println("</td>");
- }
-
private void selectField(PrintWriter pw, String label, String
fieldName, String value, Collection<String> options,
String... alertMessages) {
pw.print("<td style='width:20%'>");
@@ -902,4 +849,100 @@ public class ServiceUserWebConsolePlugin extends
SimpleWebConsolePlugin {
pw.println("</td>");
}
+ private boolean updatePrivileges(HttpServletRequest request,
ResourceResolver resolver) {
+
+ List<Pair<String, String>> privileges =
this.getPrivileges(request);
+ String name = getParameter(request, PN_NAME, "");
+
+ List<String> currentPolicies = new ArrayList<String>();
+ findACLs(resolver, name, currentPolicies);
+ for (int i = 0; i < currentPolicies.size(); i++) {
+ String path =
StringUtils.substringBefore(currentPolicies.get(i), "/rep:policy");
+ currentPolicies.set(i, StringUtils.isNotBlank(path) ?
path : "/");
+ }
+ log.debug("Loaded current policy paths: {}", currentPolicies);
+
+ Map<String, List<String>> toSet = new HashMap<String,
List<String>>();
+ for (Pair<String, String> privilege : privileges) {
+ if (!toSet.containsKey(privilege.getKey())) {
+ toSet.put(privilege.getKey(), new
ArrayList<String>());
+ }
+ toSet.get(privilege.getKey()).add(privilege.getValue());
+ }
+ log.debug("Loaded updated policy paths: {}", currentPolicies);
+
+ String lastEntry = null;
+
+ try {
+
+ Session session = resolver.adaptTo(Session.class);
+ AccessControlManager accessManager =
session.getAccessControlManager();
+ PrincipalManager principalManager =
AccessControlUtil.getPrincipalManager(session);
+
+ for (Entry<String, List<String>> pol :
toSet.entrySet()) {
+ lastEntry = pol.getKey();
+ currentPolicies.remove(pol.getKey());
+ log.debug("Updating policies for {}",
pol.getKey());
+
+ AccessControlPolicy[] policies =
accessManager.getPolicies(pol.getKey());
+ List<String> toRemove = new ArrayList<String>();
+ for (AccessControlPolicy p : policies) {
+ if (p instanceof AccessControlList) {
+ AccessControlList policy =
(AccessControlList) p;
+ for (AccessControlEntry entry :
policy.getAccessControlEntries()) {
+ Principal prin =
entry.getPrincipal();
+ if
(prin.getName().equals(name)) {
+ for (Privilege
privilege : entry.getPrivileges()) {
+ if
(!pol.getValue().contains(privilege.getName())) {
+
log.debug("Removing privilege {}", privilege);
+
toRemove.add(privilege.getName());
+ }
+ }
+ }
+ }
+ }
+ }
+ Principal principal =
principalManager.getPrincipal(name);
+
AccessControlUtil.replaceAccessControlEntry(session, pol.getKey(), principal,
+ pol.getValue().toArray(new
String[pol.getValue().size()]), new String[0],
+ toRemove.toArray(new
String[toRemove.size()]), null);
+ }
+ session.save();
+
+ for (String oldPolicy : currentPolicies) {
+ boolean removed = false;
+ log.debug("Removing policy for {}", oldPolicy);
+ AccessControlPolicy[] policies =
accessManager.getPolicies(oldPolicy);
+ AccessControlEntry toRemove = null;
+ for (AccessControlPolicy p : policies) {
+ if (p instanceof AccessControlList) {
+ AccessControlList policy =
(AccessControlList) p;
+ for (AccessControlEntry entry :
policy.getAccessControlEntries()) {
+ Principal prin =
entry.getPrincipal();
+ if
(prin.getName().equals(name)) {
+ toRemove =
entry;
+ break;
+ }
+ }
+ if (toRemove != null) {
+ removed = true;
+
policy.removeAccessControlEntry(toRemove);
+
accessManager.setPolicy(oldPolicy, policy);
+ session.save();
+ log.debug("Removed
access control entry {}", toRemove);
+ }
+ }
+ }
+ if (!removed) {
+ log.warn("No policy found for {}",
oldPolicy);
+ }
+ }
+ } catch (RepositoryException e) {
+ log.error("Exception updating principals with {},
failed on {}", toSet, lastEntry, e);
+ return false;
+ }
+
+ return true;
+ }
+
}
--
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].