You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:13:26 UTC
[sling-org-apache-sling-serviceusermapper] 01/12: Working on a
prototype to deprecate loginAdministrative
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.serviceusermapper-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceusermapper.git
commit e689b69c3241b1bbe98ebecca27b5ed74d7ee774
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Wed Mar 20 09:01:22 2013 +0000
Working on a prototype to deprecate loginAdministrative
git-svn-id: https://svn.apache.org/repos/asf/sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper@1458693 13f79535-47bb-0310-9956-ffa450edef68
---
pom.xml | 158 +++++++++++++++++++++
.../serviceusermapping/ServiceUserMapper.java | 43 ++++++
.../sling/serviceusermapping/impl/Mapping.java | 90 ++++++++++++
.../impl/ServiceUserMapperImpl.java | 122 ++++++++++++++++
.../sling/serviceusermapping/package-info.java | 26 ++++
.../sling/serviceusermapping/impl/MappingTest.java | 127 +++++++++++++++++
6 files changed, 566 insertions(+)
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..fb9e2bb
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,158 @@
+<?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">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>15</version>
+ </parent>
+
+ <artifactId>org.apache.sling.serviceusermapper</artifactId>
+ <packaging>bundle</packaging>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <name>Apache Sling Service User Mapper</name>
+ <description>
+ Provides a service to map service names with
+ optional service information to user names to
+ be used to access repositories such as the JCR
+ repository or the Sling ResourceResolver.
+ </description>
+
+ <!--
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/ftpserver</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/ftpserver</developerConnection>
+ <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/ftpserver</url>
+ </scm>
+ -->
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ <version>1.11.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <version>2.3.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.osgi</artifactId>
+ <version>2.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ <version>2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-api</artifactId>
+ <version>2.4.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.scr.annotations</artifactId>
+ <version>1.9.0</version>
+ </dependency>
+ <dependency>
+ <groupId>biz.aQute</groupId>
+ <artifactId>bndlib</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.testing</artifactId>
+ <version>2.0.6</version>
+ <scope>test</scope>
+ <exclusions>
+ <!-- slf4j simple implementation logs INFO + higher to stdout (we don't want that behaviour) -->
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <!-- using log4j under slf4j to allow fine-grained logging config (see src/test/resources/log4j.properties) -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.5.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.13</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java b/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java
new file mode 100644
index 0000000..04025b4
--- /dev/null
+++ b/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+package org.apache.sling.serviceusermapping;
+
+import org.osgi.framework.Bundle;
+
+import aQute.bnd.annotation.ProviderType;
+
+@ProviderType
+public interface ServiceUserMapper {
+
+ /**
+ * Returns the name of a user to the be used to access the Sling Resource
+ * tree or the JCR Repository.
+ *
+ * @param bundle The bundle implementing the service request access to
+ * resources.
+ * @param serviceInfo Additional information about the concrete service
+ * requesting access. This parameter is optional and may be
+ * {@code null}.
+ * @return The name of the user to use to provide access to the resources
+ * for the service. This may be {@code null} to only grant guest
+ * level (or anonymous level) access to the resources.
+ */
+ String getUserForService(Bundle bundle, String serviceInfo);
+
+}
diff --git a/src/main/java/org/apache/sling/serviceusermapping/impl/Mapping.java b/src/main/java/org/apache/sling/serviceusermapping/impl/Mapping.java
new file mode 100644
index 0000000..679b5dc
--- /dev/null
+++ b/src/main/java/org/apache/sling/serviceusermapping/impl/Mapping.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+package org.apache.sling.serviceusermapping.impl;
+
+/**
+ * The <code>Mapping</code> class defines the mapping of a service's name and
+ * optional service information to a user name.
+ */
+class Mapping {
+
+ private final String serviceName;
+
+ private final String serviceInfo;
+
+ private final String userName;
+
+ /**
+ * Creates a mapping entry for the entry specification of the form:
+ *
+ * <pre>
+ * spec = serviceName [ ":" serviceInfo ] "=" userName .
+ * </pre>
+ *
+ * @param spec The mapping specification.
+ * @throws NullPointerException if {@code spec} is {@code null}.
+ * @throws IllegalArgumentException if {@code spec} does not match the
+ * expected pattern.
+ */
+ Mapping(final String spec) {
+
+ final int colon = spec.indexOf(':');
+ final int equals = spec.indexOf('=');
+
+ if (equals <= 0) {
+ throw new IllegalArgumentException("serviceName missing");
+ } else if (equals == spec.length() - 1) {
+ throw new IllegalArgumentException("userName missing");
+ }
+
+ if (colon == 0) {
+ throw new IllegalArgumentException("serviceName missing");
+ } else if (colon < 0 || colon > equals) {
+ this.serviceName = spec.substring(0, equals);
+ this.serviceInfo = null;
+ } else {
+ this.serviceName = spec.substring(0, colon);
+ this.serviceInfo = spec.substring(colon + 1, equals);
+ }
+
+ this.userName = spec.substring(equals + 1);
+ }
+
+ /**
+ * Returns the user name if the {@code serviceName} and the
+ * {@code serviceInfo} match. Otherwise {@code null} is returned.
+ *
+ * @param serviceName The name of the service to match. If this is
+ * {@code null} this mapping will not match.
+ * @param serviceInfo The info of the service to match. This may be
+ * {@code null}.
+ * @return The user name if this mapping matches or {@code null} otherwise.
+ */
+ String map(final String serviceName, final String serviceInfo) {
+ if (this.serviceName.equals(serviceName) && equals(this.serviceInfo, serviceInfo)) {
+ return userName;
+ }
+
+ return null;
+ }
+
+ private boolean equals(String str1, String str2) {
+ return ((str1 == null) ? str2 == null : str1.equals(str2));
+ }
+}
diff --git a/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java b/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java
new file mode 100644
index 0000000..b0a966d
--- /dev/null
+++ b/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+package org.apache.sling.serviceusermapping.impl;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.PropertyUnbounded;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.apache.sling.serviceusermapping.ServiceUserMapper;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(metatype = true, ds = true, policy = ConfigurationPolicy.REQUIRE)
+@Service()
+public class ServiceUserMapperImpl implements ServiceUserMapper {
+
+ @Property(
+ label = "Service Mappings",
+ description = "Provides mappings from service name to user names. "
+ + "Each entry is of the form 'serviceName [ \":\" serviceInfo ] \"=\" userName' "
+ + "where serviceName and serviceInfo identify the service and userName would "
+ + "defines the name of the user to provide to the service. Invalid entries are logged and ignored.",
+ unbounded = PropertyUnbounded.ARRAY)
+ private static final String PROP_SERVICE2USER_MAPPING = "user.mapping";
+
+ private static final String[] PROP_SERVICE2USER_MAPPING_DEFAULT = {};
+
+ private static final String PROP_DEFAULT_USER = "user.default";
+
+ @Property(
+ name = PROP_DEFAULT_USER,
+ label = "Default User",
+ description = "The name of the user to use as the default if no service mapping"
+ + "applies. If this property is missing or empty the default user name reflects "
+ + "an anonymous user.")
+ private static final String PROP_DEFAULT_USER_DEFAULT = "";
+
+ /** default log */
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private Mapping[] serviceUserMappings;
+
+ private String defaultUser;
+
+ @Activate
+ @Modified
+ private void configure(Map<String, Object> config) {
+ final String[] props = PropertiesUtil.toStringArray(config.get(PROP_SERVICE2USER_MAPPING),
+ PROP_SERVICE2USER_MAPPING_DEFAULT);
+
+ ArrayList<Mapping> mappings = new ArrayList<Mapping>(props.length);
+ for (String prop : props) {
+ if (prop != null) {
+ try {
+ Mapping mapping = new Mapping(prop);
+ mappings.add(mapping);
+ } catch (IllegalArgumentException iae) {
+ log.info("configure: Ignoring '{}': {}", prop, iae.getMessage());
+ }
+ }
+ }
+
+ this.serviceUserMappings = mappings.toArray(new Mapping[mappings.size()]);
+ this.defaultUser = PropertiesUtil.toString(config.get(PROP_DEFAULT_USER), PROP_DEFAULT_USER_DEFAULT);
+ }
+
+ public String getUserForService(Bundle bundle, String serviceInfo) {
+ final String serviceName = getServiceName(bundle);
+
+ // try with serviceInfo first
+ for (Mapping mapping : this.serviceUserMappings) {
+ final String user = mapping.map(serviceName, serviceInfo);
+ if (user != null) {
+ return user;
+ }
+ }
+
+ // second round without serviceInfo
+ for (Mapping mapping : this.serviceUserMappings) {
+ final String user = mapping.map(serviceName, null);
+ if (user != null) {
+ return user;
+ }
+ }
+
+ // finally, fall back to default user
+ return this.defaultUser;
+ }
+
+ private String getServiceName(final Bundle bundle) {
+ final String name = (String) bundle.getHeaders().get("Sling-ResourceResolver-Service");
+ if (name != null && name.trim().length() > 0) {
+ return name.trim();
+ }
+
+ return bundle.getSymbolicName();
+ }
+}
diff --git a/src/main/java/org/apache/sling/serviceusermapping/package-info.java b/src/main/java/org/apache/sling/serviceusermapping/package-info.java
new file mode 100644
index 0000000..3ebac13
--- /dev/null
+++ b/src/main/java/org/apache/sling/serviceusermapping/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+@Version("1.0")
+@Export(optional = "provide:=true")
+package org.apache.sling.serviceusermapping;
+
+import aQute.bnd.annotation.Export;
+import aQute.bnd.annotation.Version;
+
diff --git a/src/test/java/org/apache/sling/serviceusermapping/impl/MappingTest.java b/src/test/java/org/apache/sling/serviceusermapping/impl/MappingTest.java
new file mode 100644
index 0000000..7a1728a
--- /dev/null
+++ b/src/test/java/org/apache/sling/serviceusermapping/impl/MappingTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+package org.apache.sling.serviceusermapping.impl;
+
+import java.lang.reflect.Field;
+
+import junit.framework.TestCase;
+
+import org.apache.sling.serviceusermapping.impl.Mapping;
+import org.junit.Test;
+
+public class MappingTest {
+
+ @Test
+ public void test_constructor_null() {
+ try {
+ new Mapping(null);
+ TestCase.fail("NullPointerException expected");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ @Test
+ public void test_constructor_empty() {
+ try {
+ new Mapping("");
+ TestCase.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ }
+ }
+
+ @Test
+ public void test_constructor_missing_user_name() {
+ try {
+ new Mapping("serviceName");
+ TestCase.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ }
+
+ try {
+ new Mapping("serviceName=");
+ TestCase.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ }
+ }
+
+ @Test
+ public void test_constructor_missing_service_name() {
+ try {
+ new Mapping("=user");
+ TestCase.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ }
+ }
+
+ @Test
+ public void test_constructor_and_map() {
+ assertMapping("service", null, "user");
+ assertMapping("service", "serviceInfo", "user");
+ assertMapping("service", "", "user");
+ }
+
+ private void assertMapping(final String serviceName, final String serviceInfo, final String userName) {
+ StringBuilder spec = new StringBuilder();
+ spec.append(serviceName);
+ if (serviceInfo != null) {
+ spec.append(':').append(serviceInfo);
+ }
+ spec.append('=').append(userName);
+
+ // spec analysis
+ final Mapping mapping = new Mapping(spec.toString());
+ TestCase.assertEquals(getField(mapping, "serviceName"), serviceName);
+ TestCase.assertEquals(getField(mapping, "serviceInfo"), serviceInfo);
+ TestCase.assertEquals(getField(mapping, "userName"), userName);
+
+ // mapping
+ TestCase.assertEquals(userName, mapping.map(serviceName, serviceInfo));
+ if (serviceInfo == null) {
+ // Mapping without serviceInfo must not match request with any
+ // serviceInfo
+ TestCase.assertNull(mapping.map(serviceName, serviceInfo + "-garbage"));
+ } else {
+ // Mapping with serviceInfo must not match request without
+ // serviceInfo
+ TestCase.assertNull(mapping.map(serviceName, null));
+ }
+
+ // no match for different service name
+ TestCase.assertNull(mapping.map(serviceName + "-garbage", serviceInfo));
+
+ // no match for null service name
+ TestCase.assertNull(mapping.map(null, serviceInfo));
+ }
+
+ private String getField(final Object object, final String fieldName) {
+ try {
+ Field f = object.getClass().getDeclaredField(fieldName);
+ f.setAccessible(true);
+ return (String) f.get(object);
+ } catch (Exception e) {
+ TestCase.fail("Cannot get field " + fieldName + ": " + e.toString());
+ return null; // will not get here, quiesce compiler
+ }
+ }
+}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.