Author: bdelacretaz
Date: Tue Oct 11 16:05:57 2016
New Revision: 1764281

URL: http://svn.apache.org/viewvc?rev=1764281&view=rev
Log:
SLING-5135 - whitelist legit usages of loginAdministrative

Added:
    
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/LoginAdminWhitelist.java
    
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImpl.java
    
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockLoginAdminWhitelist.java
    
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/
    
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImplTest.java
    
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/WhitelistWiringTest.java
    
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminBlacklistedIT.java
Modified:
    sling/trunk/bundles/jcr/base/pom.xml
    
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
    
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
    
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java
    
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
    
sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java
    
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminWhitelistedIT.java
    
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java
    sling/trunk/bundles/jcr/resource/pom.xml
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
    
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
    
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
    
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
    
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
    
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java

Modified: sling/trunk/bundles/jcr/base/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/pom.xml?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/pom.xml (original)
+++ sling/trunk/bundles/jcr/base/pom.xml Tue Oct 11 16:05:57 2016
@@ -84,6 +84,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>javax.jcr</groupId>
             <artifactId>jcr</artifactId>
             <version>2.0</version>

Modified: 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
 (original)
+++ 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
 Tue Oct 11 16:05:57 2016
@@ -73,7 +73,7 @@ public abstract class AbstractSlingRepos
 
     /** The bundle using this repository instance. */
     private final Bundle usingBundle;
-
+    
     /**
      * Sets up this abstract SlingRepository implementation.
      *
@@ -87,7 +87,11 @@ public abstract class AbstractSlingRepos
     protected AbstractSlingRepository2(final AbstractSlingRepositoryManager 
manager, final Bundle usingBundle) {
         this.manager = manager;
         this.usingBundle = usingBundle;
-    }
+
+        if(usingBundle == null) {
+            throw new IllegalArgumentException("usingBundle is null");
+        }
+     }
 
     /**
      * @return The {@link AbstractSlingRepositoryManager} controlling this
@@ -367,7 +371,12 @@ public abstract class AbstractSlingRepos
      */
     @Override
     public final Session loginAdministrative(final String workspace) throws 
RepositoryException {
-        if (this.getSlingRepositoryManager().isDisableLoginAdministrative()) {
+        final boolean whitelisted = 
getSlingRepositoryManager().getLoginAdminWhitelist().allowLoginAdministrative(usingBundle);
+
+        if(!whitelisted) {
+            logger.error("Bundle {} is NOT whitelisted to use 
SlingRepository.loginAdministrative", usingBundle.getSymbolicName());
+            throw new LoginException();
+        } else if 
(this.getSlingRepositoryManager().isDisableLoginAdministrative()) {
             logger.error("SlingRepository.loginAdministrative is disabled. 
Please use SlingRepository.loginService.");
             throw new LoginException();
         }

Modified: 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
 (original)
+++ 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
 Tue Oct 11 16:05:57 2016
@@ -140,6 +140,12 @@ public abstract class AbstractSlingRepos
      * @see AbstractSlingRepository2#loginService(String, String)
      */
     protected abstract ServiceUserMapper getServiceUserMapper();
+    
+    /** Returns the {@code LoginAdminWhitelist} service used to decide whether
+     *  to allow bundles to use the {@code loginAdministrative} method.
+     * @return the non-null {@code LoginAdminWhitelist} service
+     */
+    protected abstract LoginAdminWhitelist getLoginAdminWhitelist();
 
     /**
      * Creates the backing JCR repository instances. It is expected for this

Added: 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/LoginAdminWhitelist.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/LoginAdminWhitelist.java?rev=1764281&view=auto
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/LoginAdminWhitelist.java
 (added)
+++ 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/LoginAdminWhitelist.java
 Tue Oct 11 16:05:57 2016
@@ -0,0 +1,33 @@
+/*
+ * 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.jcr.base;
+
+import org.apache.sling.jcr.api.SlingRepository;
+import org.osgi.framework.Bundle;
+
+import aQute.bnd.annotation.ProviderType;
+
+/**
+ * Whitelist that defines which bundles can use the 
+ * {@link SlingRepository#loginAdministrative} method.
+ */
+@ProviderType
+public interface LoginAdminWhitelist {
+    boolean allowLoginAdministrative(Bundle b);
+}

Added: 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImpl.java?rev=1764281&view=auto
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImpl.java
 (added)
+++ 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImpl.java
 Tue Oct 11 16:05:57 2016
@@ -0,0 +1,157 @@
+/*
+ * 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.jcr.base.internal;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.base.LoginAdminWhitelist;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Whitelist that defines which bundles can use the 
+ * {@link SlingRepository#loginAdministrative} method.
+ * 
+ * The default configuration lets a few trusted Sling bundles
+ * use the loginAdministrative method.
+ */
+@Service(value=LoginAdminWhitelist.class)
+@Component(
+        label="Login Admin Whitelist",
+        description="Defines which bundles can use 
SlingRepository.loginAdministrative()",
+        metatype=true)
+public class LoginAdminWhitelistImpl implements LoginAdminWhitelist {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /** Need to allow for bypassing the whitelist, for backwards
+     *  compatibility with previous Sling versions which didn't 
+     *  implement it. Setting this to true is not recommended
+     *  and logged as a warning.
+     */
+    @Property(
+            label="Bypass the whitelist",
+            description=
+                "Allow all bundles to use loginAdministrative(). " 
+                + "Should ONLY be used for backwards compatiblity reasons and 
" 
+                + "if you are aware of the related security risks.",
+            boolValue=false)
+    public static final String PROP_BYPASS_WHITELIST = "whitelist.bypass";
+    public static final boolean DEFAULT_BYPASS = false;
+    private boolean bypassWhitelist = DEFAULT_BYPASS;
+    
+    @Property(
+            label="Whitelist regexp",
+            description="Regular expression for bundle symbolic names for 
which loginAdministrative() is allowed. "
+                + " NOT recommended for production use, but useful for testing 
with generated bundles.",
+            value = "")
+    public static final String PROP_WHITELIST_REGEXP = "whitelist.regexp";
+    private Pattern whitelistRegexp;
+    
+    @Property(
+            label="Whitelisted BSNs",
+            description="List of bundle symbolic names for which 
loginAdministrative() is allowed",
+            value = {})
+    public static final String PROP_WHITELISTED_BSN = 
"whitelisted.bundle.symbolic.names";
+    private Set<String> whitelistedBsn;
+    
+    static final String [] DEFAULT_WHITELISTED_BSN = {
+            "org.apache.sling.discovery.commons",
+            "org.apache.sling.discovery.base",
+            "org.apache.sling.discovery.oak",
+            "org.apache.sling.event",
+            "org.apache.sling.event.dea",
+            "org.apache.sling.extensions.webconsolesecurityprovider",
+            "org.apache.sling.i18n",
+            "org.apache.sling.installer.provider.jcr",
+            "org.apache.sling.jcr.base",
+            "org.apache.sling.jcr.contentloader",
+            "org.apache.sling.jcr.davex",
+            "org.apache.sling.jcr.jackrabbit.usermanager",
+            "org.apache.sling.jcr.oak.server",
+            "org.apache.sling.jcr.resource",
+            "org.apache.sling.jcr.webconsole",
+            "org.apache.sling.jcr.webdav",
+            "org.apache.sling.junit.core",
+            "org.apache.sling.resourceresolver",
+            "org.apache.sling.scripting.core",
+            "org.apache.sling.scripting.sightly",
+            "org.apache.sling.servlets.post",
+            "org.apache.sling.servlets.resolver",
+            "org.apache.sling.xss"
+    };
+    
+    public void activate(Map<String, Object> config) {
+        bypassWhitelist = 
PropertiesUtil.toBoolean(config.get(PROP_BYPASS_WHITELIST), DEFAULT_BYPASS);
+        whitelistedBsn = new TreeSet<String>();
+        final Object bsns = config.get(PROP_WHITELISTED_BSN);
+        if(bsns == null) {
+            whitelistedBsn.addAll(Arrays.asList(DEFAULT_WHITELISTED_BSN));
+        } else {
+            
whitelistedBsn.addAll(Arrays.asList(PropertiesUtil.toStringArray(bsns)));
+        }
+        
+        final String regexp = 
PropertiesUtil.toString(config.get(PROP_WHITELIST_REGEXP), "");
+        if(regexp.trim().length() > 0) {
+            whitelistRegexp = Pattern.compile(regexp);
+            log.warn("A {} is configured, this is NOT RECOMMENDED for 
production: {}", PROP_WHITELIST_REGEXP, whitelistRegexp);
+        } else {
+            whitelistRegexp = null;
+        }
+        
+        if(bypassWhitelist) {
+            log.info("bypassWhitelist={}, whitelisted BSNs=<ALL>", 
bypassWhitelist);
+            log.warn(
+                "All bundles are allowed to use loginAdministrative due to the 
'bypass whitelist' configuration"
+                + " of this service. This is NOT RECOMMENDED, for security 
reasons."
+            );
+        } else {
+            log.info("bypassWhitelist={}, whitelisted BSNs({})={}", 
+                    new Object[] { bypassWhitelist, whitelistedBsn.size(), 
whitelistedBsn });
+        }
+    }
+    
+    @Override
+    public boolean allowLoginAdministrative(Bundle b) {
+        if(bypassWhitelist) {
+            log.debug("Whitelist is bypassed, all bundles allowed to use 
loginAdministrative");
+            return true;
+        }
+        
+        final String bsn = b.getSymbolicName();
+        if(whitelistRegexp != null && whitelistRegexp.matcher(bsn).matches()) {
+            log.debug("{} is whitelisted to use loginAdministrative, by 
regexp", bsn);
+            return true;
+        } else if(whitelistedBsn.contains(bsn)) {
+            log.debug("{} is whitelisted to use loginAdministrative, by 
explicit whitelist", bsn);
+            return true;
+        }
+        log.debug("{} is not whitelisted to use loginAdministrative", bsn);
+        return false;
+    }
+}
\ No newline at end of file

Modified: 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java
 (original)
+++ 
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java
 Tue Oct 11 16:05:57 2016
@@ -25,7 +25,7 @@
  * {@link org.apache.sling.jcr.base.AbstractSlingRepository2} being the
  * basis for the repository service instance handed to using bundles.
  */
-@Version("3.0")
+@Version("3.1.0")
 package org.apache.sling.jcr.base;
 
 import aQute.bnd.annotation.Version;

Added: 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockLoginAdminWhitelist.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockLoginAdminWhitelist.java?rev=1764281&view=auto
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockLoginAdminWhitelist.java
 (added)
+++ 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockLoginAdminWhitelist.java
 Tue Oct 11 16:05:57 2016
@@ -0,0 +1,30 @@
+/*
+ * 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.jcr.base;
+
+import org.osgi.framework.Bundle;
+
+/** Mock LoginAdminWhitelist */
+class MockLoginAdminWhitelist implements LoginAdminWhitelist {
+    @Override
+    public boolean allowLoginAdministrative(Bundle b) {
+        return true;
+    }
+    
+}
\ No newline at end of file

Modified: 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
 (original)
+++ 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
 Tue Oct 11 16:05:57 2016
@@ -30,14 +30,17 @@ import org.apache.sling.serviceusermappi
 import org.osgi.framework.Bundle;
 
 /** Minimal AbstractSlingRepositoryManager used for testing */
-class MockSlingRepositoryManager extends AbstractSlingRepositoryManager {
+public class MockSlingRepositoryManager extends AbstractSlingRepositoryManager 
{
 
     private final Repository repository;
+    private LoginAdminWhitelist loginAdminWhitelist; 
+    
 
-    MockSlingRepositoryManager(Repository repository) {
+    public MockSlingRepositoryManager(Repository repository) {
         this.repository = repository;
+        this.loginAdminWhitelist = new MockLoginAdminWhitelist();
     }
-
+    
     @Override
     protected ServiceUserMapper getServiceUserMapper() {
         return null;
@@ -72,4 +75,13 @@ class MockSlingRepositoryManager extends
     @Override
     protected void disposeRepository(Repository repository) {
     }
+
+    @Override
+    protected LoginAdminWhitelist getLoginAdminWhitelist() {
+        return loginAdminWhitelist;
+    }
+    
+    public void setLoginAdminWhitelist(LoginAdminWhitelist w) {
+        loginAdminWhitelist = w;
+    }
 }
\ No newline at end of file

Added: 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImplTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImplTest.java?rev=1764281&view=auto
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImplTest.java
 (added)
+++ 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistImplTest.java
 Tue Oct 11 16:05:57 2016
@@ -0,0 +1,123 @@
+/*
+ * 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.jcr.base.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+
+public class LoginAdminWhitelistImplTest {
+    private LoginAdminWhitelistImpl whitelist;
+    private Map<String, Object> config;
+    private static final String TYPICAL_DEFAULT_ALLOWED_BSN = 
"org.apache.sling.jcr.base";
+    
+    @Before
+    public void setup() {
+        whitelist = new LoginAdminWhitelistImpl();
+        config = new HashMap<String, Object>();
+    }
+    
+    private void assertAdminLogin(final String bundleSymbolicName, boolean 
expected) {
+        final Bundle b = Mockito.mock(Bundle.class);
+        when(b.getSymbolicName()).thenReturn(bundleSymbolicName);
+        final boolean actual = whitelist.allowLoginAdministrative(b);
+        assertEquals("For bundle " + bundleSymbolicName + ", expected admin 
login=" + expected, expected, actual);
+    }
+    
+    private List<String> randomBsn() {
+        final List<String> result = new ArrayList<String>();
+        for(int i=0; i < 5; i++) {
+            result.add("random.bsn." + UUID.randomUUID());
+        }
+        return result;
+    }
+ 
+    @Test
+    public void testDefaultConfig() {
+        whitelist.activate(config);
+        
+        for(String bsn : LoginAdminWhitelistImpl.DEFAULT_WHITELISTED_BSN) {
+            assertAdminLogin(bsn, true);
+        }
+        
+        assertAdminLogin(TYPICAL_DEFAULT_ALLOWED_BSN, true);
+        
+        for(String bsn : randomBsn()) {
+            assertAdminLogin(bsn, false);
+        }
+    }
+    
+    @Test
+    public void testBypassWhitelist() {
+        config.put(LoginAdminWhitelistImpl.PROP_BYPASS_WHITELIST, true);
+        whitelist.activate(config);
+        
+        for(String bsn : randomBsn()) {
+            assertAdminLogin(bsn, true);
+        }
+    }
+    
+    @Test
+    public void testConfiguredWhitelist() {
+        final String [] allowed = {
+                "bundle1", "bundle2"
+        };
+        config.put(LoginAdminWhitelistImpl.PROP_WHITELISTED_BSN, allowed);
+        whitelist.activate(config);
+        
+        assertAdminLogin("bundle1", true);
+        assertAdminLogin("bundle2", true);
+        assertAdminLogin("foo.1.bar", false);
+        assertAdminLogin(TYPICAL_DEFAULT_ALLOWED_BSN, false);
+        
+        for(String bsn : randomBsn()) {
+            assertAdminLogin(bsn, false);
+        }
+    }
+    
+    @Test
+    public void testRegexpWhitelist() {
+        final String [] allowed = {
+                "bundle3", "bundle4"
+        };
+        config.put(LoginAdminWhitelistImpl.PROP_WHITELISTED_BSN, allowed);
+        config.put(LoginAdminWhitelistImpl.PROP_WHITELIST_REGEXP, "foo.*bar");
+        whitelist.activate(config);
+        
+        assertAdminLogin("bundle3", true);
+        assertAdminLogin("bundle4", true);
+        assertAdminLogin("foo.2.bar", true);
+        assertAdminLogin("foo.somethingElse.bar", true);
+        assertAdminLogin(TYPICAL_DEFAULT_ALLOWED_BSN, false);
+        
+        for(String bsn : randomBsn()) {
+            assertAdminLogin(bsn, false);
+        }
+    }
+}
\ No newline at end of file

Added: 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/WhitelistWiringTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/WhitelistWiringTest.java?rev=1764281&view=auto
==============================================================================
--- 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/WhitelistWiringTest.java
 (added)
+++ 
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/WhitelistWiringTest.java
 Tue Oct 11 16:05:57 2016
@@ -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.jcr.base.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import javax.jcr.LoginException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.base.AbstractSlingRepository2;
+import org.apache.sling.jcr.base.AbstractSlingRepositoryManager;
+import org.apache.sling.jcr.base.LoginAdminWhitelist;
+import org.apache.sling.jcr.base.MockSlingRepositoryManager;
+import org.apache.sling.testing.mock.jcr.MockJcr;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+
+/** Verify that the AbstractSlingRepository2 uses the login admin whitelist,
+ *  as well as its combination with the global "disable login admin" flag
+ */
+@RunWith(Parameterized.class)
+public class WhitelistWiringTest {
+    @Rule
+    public final SlingContext context = new 
SlingContext(ResourceResolverType.JCR_MOCK);
+    
+    private LoginAdminWhitelist whitelist;
+    private Bundle bundle;
+    private static final String BSN = "random.bsn." + UUID.randomUUID();
+    private SlingRepository repository;
+    private final boolean managerAllowsLoginAdmin;
+    private final boolean whitelistAllowsLoginAdmin;
+    private final boolean loginAdminExpected;
+ 
+    @Parameters(name="manager {0}, whitelist {1} -> {2}")
+    public static Collection<Object[]> data() {
+        final List<Object[]> result = new ArrayList<Object[]>();
+        result.add(new Object[] { false, false, false });
+        result.add(new Object[] { false, true, false });
+        result.add(new Object[] { true, false, false });
+        result.add(new Object[] { true, true, true});
+        return result;
+    }
+
+    public WhitelistWiringTest(boolean managerAllowsLoginAdmin, boolean 
whitelistAllowsLoginAdmin, boolean loginAdminExpected) {
+        this.managerAllowsLoginAdmin = managerAllowsLoginAdmin;
+        this.whitelistAllowsLoginAdmin = whitelistAllowsLoginAdmin;
+        this.loginAdminExpected = loginAdminExpected;
+    }
+    
+    @Before
+    public void setup() throws NoSuchFieldException, Exception  {
+        bundle = Mockito.mock(Bundle.class);
+        when(bundle.getSymbolicName()).thenReturn(BSN);
+        
+        whitelist = new LoginAdminWhitelist() {
+            @Override
+            public boolean allowLoginAdministrative(Bundle b) {
+                return whitelistAllowsLoginAdmin;
+            }
+        };
+        
+        final MockSlingRepositoryManager arm = new 
MockSlingRepositoryManager(MockJcr.newRepository());
+        arm.setLoginAdminWhitelist(whitelist);
+        final Field f = 
AbstractSlingRepositoryManager.class.getDeclaredField("disableLoginAdministrative");
+        f.setAccessible(true);
+        f.set(arm, !managerAllowsLoginAdmin);
+        
+        repository = new AbstractSlingRepository2(arm, bundle) {
+            @Override
+            protected Session createAdministrativeSession(String workspace) 
throws RepositoryException {
+                return Mockito.mock(Session.class);
+            }
+        };
+    }
+    
+    @Test
+    @SuppressWarnings("deprecation")
+    public void testLoginAdmin() throws Exception {
+        boolean allowed = false;
+        try {
+            repository.loginAdministrative(null);
+            allowed = true;
+        } catch(LoginException ignored) {
+            allowed = false;
+        }
+        
+        assertEquals(loginAdminExpected, allowed);
+    }
+}
\ No newline at end of file

Modified: 
sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java
 (original)
+++ 
sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java
 Tue Oct 11 16:05:57 2016
@@ -61,6 +61,7 @@ import org.apache.sling.commons.threads.
 import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.jcr.base.AbstractSlingRepository2;
 import org.apache.sling.jcr.base.AbstractSlingRepositoryManager;
+import org.apache.sling.jcr.base.LoginAdminWhitelist;
 import org.apache.sling.serviceusermapping.ServiceUserMapper;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -110,6 +111,9 @@ public class OakSlingRepositoryManager e
 
     @Reference
     private ThreadPoolManager threadPoolManager = null;
+    
+    @Reference
+    private LoginAdminWhitelist loginAdminWhitelist;  
 
     private ThreadPool threadPool;
 
@@ -243,6 +247,11 @@ public class OakSlingRepositoryManager e
         this.oakExecutorServiceReference = null;
         ((JackrabbitRepository) repository).shutdown();
     }
+    
+    @Override
+    protected LoginAdminWhitelist getLoginAdminWhitelist() {
+        return loginAdminWhitelist;
+    }
 
     @Activate
     private void activate(final OakSlingRepositoryManagerConfiguration 
configuration, final ComponentContext componentContext) {

Added: 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminBlacklistedIT.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminBlacklistedIT.java?rev=1764281&view=auto
==============================================================================
--- 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminBlacklistedIT.java
 (added)
+++ 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminBlacklistedIT.java
 Tue Oct 11 16:05:57 2016
@@ -0,0 +1,61 @@
+/*
+ * 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.jcr.oak.server.it;
+
+import javax.inject.Inject;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import static org.ops4j.pax.exam.CoreOptions.composite;
+
+
+/** Test login admin without whitelisting the test bundle,
+ *  so both variants of getting admin session should fail.
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class LoginAdminBlacklistedIT extends OakServerTestSupport {
+
+    @Inject
+    private SlingRepository repository;
+            
+    @Inject
+    private ResourceResolverFactory resolverFactory;
+    
+    @Override
+    protected Option getWhitelistRegexpOption() {
+        // Do not whitelist this test bundle
+        return composite();
+    }
+    
+    @Test(expected = javax.jcr.LoginException.class)
+    public void testLoginAdmin() throws Exception {
+        repository.loginAdministrative(null);
+    }
+    
+    @Test(expected = org.apache.sling.api.resource.LoginException.class)
+    public void testGetAdminResourceResolver() throws Exception {
+        resolverFactory.getAdministrativeResourceResolver(null);
+    }
+}

Modified: 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminWhitelistedIT.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminWhitelistedIT.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminWhitelistedIT.java
 (original)
+++ 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/LoginAdminWhitelistedIT.java
 Tue Oct 11 16:05:57 2016
@@ -20,24 +20,27 @@ package org.apache.sling.jcr.oak.server.
 
 import javax.inject.Inject;
 import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.jcr.api.SlingRepository;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
 import org.ops4j.pax.exam.spi.reactors.PerClass;
 
-/** Test login admin and get admin resource resolver - will be
- *  expanded to test the SLING-5135 whitelist later.
+/** Test login admin with the test bundle whitelisted (which
+ *  is a default from our base class)
  */
 @RunWith(PaxExam.class)
 @ExamReactorStrategy(PerClass.class)
 public class LoginAdminWhitelistedIT extends OakServerTestSupport {
 
     @Inject
+    private SlingRepository repository;
+            
+    @Inject
     private ResourceResolverFactory resolverFactory;
     
     @Test
-    @SuppressWarnings("deprecation")
     public void testLoginAdmin() throws Exception {
         repository.loginAdministrative(null);
     }

Modified: 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java
 (original)
+++ 
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java
 Tue Oct 11 16:05:57 2016
@@ -21,7 +21,6 @@ package org.apache.sling.jcr.oak.server.
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
-
 import javax.inject.Inject;
 import javax.jcr.Item;
 import javax.jcr.Node;
@@ -30,26 +29,24 @@ import javax.jcr.Session;
 import javax.jcr.observation.EventIterator;
 import javax.jcr.observation.EventListener;
 import javax.jcr.observation.ObservationManager;
-
 import org.apache.jackrabbit.commons.JcrUtils;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.testing.paxexam.SlingOptions;
-import org.apache.sling.testing.paxexam.TestSupport;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.osgi.framework.BundleContext;
-
 import static org.apache.sling.testing.paxexam.SlingOptions.jackrabbitSling;
 import static org.apache.sling.testing.paxexam.SlingOptions.scr;
 import static org.apache.sling.testing.paxexam.SlingOptions.slingJcr;
 import static org.apache.sling.testing.paxexam.SlingOptions.tikaSling;
+import org.apache.sling.testing.paxexam.TestSupport;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import org.ops4j.pax.exam.Configuration;
 import static org.ops4j.pax.exam.CoreOptions.composite;
 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import org.ops4j.pax.exam.Option;
 import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.newConfiguration;
+import org.osgi.framework.BundleContext;
 
 public abstract class OakServerTestSupport extends TestSupport {
 
@@ -191,7 +188,14 @@ public abstract class OakServerTestSuppo
                 .asOption(),
             
newConfiguration("org.apache.sling.resourceresolver.impl.observation.OsgiObservationBridge")
                 .put("enabled", true)
-                .asOption()
+                .asOption(),
+            getWhitelistRegexpOption()
         );
     }
+    
+    protected Option getWhitelistRegexpOption() {
+        return 
newConfiguration("org.apache.sling.jcr.base.internal.LoginAdminWhitelistImpl")
+            .put("whitelist.regexp", "PAXEXAM-PROBE-.*")
+            .asOption();
+    }
 }

Modified: sling/trunk/bundles/jcr/resource/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/pom.xml?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/pom.xml (original)
+++ sling/trunk/bundles/jcr/resource/pom.xml Tue Oct 11 16:05:57 2016
@@ -170,6 +170,12 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.base</artifactId>
+            <version>2.4.1-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
             <version>2.11.0</version>
             <scope>provided</scope>

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java
 Tue Oct 11 16:05:57 2016
@@ -35,6 +35,7 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.base.LoginAdminWhitelist;
 import org.apache.sling.jcr.resource.api.JcrResourceConstants;
 import org.apache.sling.jcr.resource.internal.HelperData;
 import org.apache.sling.spi.resource.provider.ResourceProvider;
@@ -55,15 +56,42 @@ public class JcrProviderStateFactory {
     private final AtomicReference<DynamicClassLoaderManager> 
dynamicClassLoaderManagerReference;
 
     private final PathMapper pathMapper;
+    
+    private final LoginAdminWhitelist loginAdminWhitelist;
 
     public JcrProviderStateFactory(final ServiceReference repositoryReference,
             final SlingRepository repository,
             final AtomicReference<DynamicClassLoaderManager> 
dynamicClassLoaderManagerReference,
-            final PathMapper pathMapper) {
+            final PathMapper pathMapper,
+            final LoginAdminWhitelist loginAdminWhitelist) {
         this.repository = repository;
         this.repositoryReference = repositoryReference;
         this.dynamicClassLoaderManagerReference = 
dynamicClassLoaderManagerReference;
         this.pathMapper = pathMapper;
+        this.loginAdminWhitelist = loginAdminWhitelist;
+    }
+    
+    /** Get the calling Bundle from auth info, fail if not provided 
+     *  @throws LoginException if no calling bundle info provided
+     */
+    private Bundle requireCallingBundle(@Nonnull Map<String, Object> 
authenticationInfo) throws LoginException {
+        final Object obj = 
authenticationInfo.get(ResourceProvider.AUTH_SERVICE_BUNDLE);
+        if(obj == null) {
+            throw new LoginException("Calling bundle missing in authentication 
info");
+        } else if(!(obj instanceof Bundle)) {
+            throw new LoginException("Invalid calling bundle object in 
authentication info");
+        }
+        return (Bundle)obj;
+    }
+    
+    /** Fail if the calling bundle is not whitelisted for loginAdministrative 
+     *  @throws LoginException if bundle not whitelisted or no calling bundle 
info provided
+     */
+    private void checkLoginAdminWhitelist(@Nonnull Map<String, Object> 
authenticationInfo) throws LoginException {
+        final Bundle b = requireCallingBundle(authenticationInfo);
+        if(!loginAdminWhitelist.allowLoginAdministrative(b)) {
+            throw new LoginException("Bundle is not whitelisted for 
loginAdministrative:" + b.getSymbolicName());
+        }
     }
 
     @SuppressWarnings("deprecation")
@@ -77,6 +105,10 @@ public class JcrProviderStateFactory {
         BundleContext bc = null;
         try {
             if 
(Boolean.TRUE.equals(authenticationInfo.get(ResourceProvider.AUTH_ADMIN))) {
+                // We need to do our own whitelist check here as the repository
+                // considers this bundle as the calling bundle but we want to 
whitelist
+                // according to the bundle that's calling us.
+                checkLoginAdminWhitelist(authenticationInfo);
                 session = repository.loginAdministrative(null);
             } else {
                 session = getSession(authenticationInfo);

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
 Tue Oct 11 16:05:57 2016
@@ -59,6 +59,7 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.base.LoginAdminWhitelist;
 import org.apache.sling.jcr.resource.api.JcrResourceConstants;
 import org.apache.sling.jcr.resource.internal.JcrModifiableValueMap;
 import org.apache.sling.jcr.resource.internal.JcrResourceListener;
@@ -124,6 +125,9 @@ public class JcrResourceProvider extends
 
     @Reference
     private PathMapper pathMapper;
+    
+    @Reference
+    private LoginAdminWhitelist loginAdminWhitelist;
 
     /** This service is only available on OAK, therefore optional and static) 
*/
     @Reference(policy=ReferencePolicy.STATIC, 
cardinality=ReferenceCardinality.OPTIONAL_UNARY)
@@ -164,7 +168,8 @@ public class JcrResourceProvider extends
         this.root = 
PropertiesUtil.toString(context.getProperties().get(ResourceProvider.PROPERTY_ROOT),
 "/");
         this.bundleCtx = context.getBundleContext();
 
-        this.stateFactory = new JcrProviderStateFactory(repositoryReference, 
repository, classLoaderManagerReference, pathMapper);
+        this.stateFactory = new JcrProviderStateFactory(repositoryReference, 
repository, 
+                classLoaderManagerReference, pathMapper, loginAdminWhitelist);
     }
 
     @Deactivate

Modified: 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
 (original)
+++ 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
 Tue Oct 11 16:05:57 2016
@@ -133,8 +133,8 @@ public class CommonResourceResolverFacto
         authenticationInfo.put(ResourceProvider.AUTH_ADMIN, Boolean.TRUE);
         if ( passedAuthenticationInfo != null ) {
             authenticationInfo.putAll(passedAuthenticationInfo);
-            // make sure there is no leaking of service bundle and info props
-            authenticationInfo.remove(ResourceProvider.AUTH_SERVICE_BUNDLE);
+            // make sure there is no leaking of service info props
+            // (but the bundle info is passed on as we need it downstream)
             authenticationInfo.remove(SUBSERVICE);
         }
 

Modified: 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
 (original)
+++ 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
 Tue Oct 11 16:05:57 2016
@@ -27,6 +27,8 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.serviceusermapping.ServiceUserMapper;
 import org.apache.sling.spi.resource.provider.ResourceProvider;
 import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The <code>ResourceResolverFactoryImpl</code> is the {@link 
ResourceResolverFactory} service
@@ -45,6 +47,8 @@ public class ResourceResolverFactoryImpl
     private final ServiceUserMapper serviceUserMapper;
 
     private final Bundle usingBundle;
+    
+    private final Logger log = LoggerFactory.getLogger(getClass());
 
     public ResourceResolverFactoryImpl(
             final CommonResourceResolverFactoryImpl commonFactory,
@@ -107,7 +111,15 @@ public class ResourceResolverFactoryImpl
     @Override
     @SuppressWarnings("deprecation")
     public ResourceResolver getAdministrativeResourceResolver(
-            final Map<String, Object> authenticationInfo) throws 
LoginException {
+            Map<String, Object> authenticationInfo) throws LoginException {
+        // usingBundle is required as bundles must now be whitelisted to use 
this method
+        if(usingBundle == null) {
+            throw new LoginException("usingBundle is null");
+        }
+        if(authenticationInfo == null) {
+            authenticationInfo = new HashMap<String, Object>();
+        }
+        authenticationInfo.put(ResourceProvider.AUTH_SERVICE_BUNDLE, 
this.usingBundle);
         return 
commonFactory.getAdministrativeResourceResolver(authenticationInfo);
     }
 

Modified: 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
 (original)
+++ 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
 Tue Oct 11 16:05:57 2016
@@ -62,6 +62,7 @@ import org.apache.sling.api.resource.obs
 import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryImpl;
 import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
 import 
org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider.VanityPathConfig;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
@@ -175,7 +176,9 @@ public class MapEntries implements Resou
     @SuppressWarnings({ "unchecked", "deprecation" })
     public MapEntries(final MapConfigurationProvider factory, final 
BundleContext bundleContext, final EventAdmin eventAdmin)
                     throws LoginException, IOException {
-        this.resolver = factory.getAdministrativeResourceResolver(null);
+        final Map<String, Object> authInfo = new HashMap<String, Object>();
+        authInfo.put(ResourceProvider.AUTH_SERVICE_BUNDLE, 
bundleContext.getBundle());
+        this.resolver = factory.getAdministrativeResourceResolver(authInfo);
         this.factory = factory;
         this.mapRoot = factory.getMapRoot();
         this.enabledVanityPaths = factory.isVanityPathEnabled();

Modified: 
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
 (original)
+++ 
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
 Tue Oct 11 16:05:57 2016
@@ -57,6 +57,7 @@ import org.apache.sling.spi.resource.pro
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.internal.util.reflection.Whitebox;
+import org.osgi.framework.Bundle;
 
 public class ResourceResolverImplTest {
 
@@ -90,7 +91,8 @@ public class ResourceResolverImplTest {
         activator.resourceProviderTracker = resourceProviderTracker;
         activator.resourceAccessSecurityTracker = new 
ResourceAccessSecurityTracker();
         commonFactory = new CommonResourceResolverFactoryImpl(activator);
-        resFac = new ResourceResolverFactoryImpl(commonFactory, /* TODO: using 
Bundle */ null, null);
+        final Bundle usingBundle = mock(Bundle.class);
+        resFac = new ResourceResolverFactoryImpl(commonFactory, usingBundle, 
null);
         resResolver = resFac.getAdministrativeResourceResolver(null);
     }
 

Modified: 
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java?rev=1764281&r1=1764280&r2=1764281&view=diff
==============================================================================
--- 
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
 (original)
+++ 
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
 Tue Oct 11 16:05:57 2016
@@ -54,10 +54,12 @@ import org.apache.sling.resourceresolver
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import static org.mockito.Matchers.any;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.event.EventAdmin;
 
@@ -74,6 +76,9 @@ public class MapEntriesTest {
     private BundleContext bundleContext;
 
     @Mock
+    private Bundle bundle;
+
+    @Mock
     private ResourceResolver resourceResolver;
 
     @Mock
@@ -98,8 +103,10 @@ public class MapEntriesTest {
 
         Collections.sort(configs);
         vanityBloomFilterFile = new 
File("src/main/resourcesvanityBloomFilter.txt");
+        when(bundle.getSymbolicName()).thenReturn("TESTBUNDLE");
+        when(bundleContext.getBundle()).thenReturn(bundle);
         
when(bundleContext.getDataFile("vanityBloomFilter.txt")).thenReturn(vanityBloomFilterFile);
-        
when(resourceResolverFactory.getAdministrativeResourceResolver(null)).thenReturn(resourceResolver);
+        
when(resourceResolverFactory.getAdministrativeResourceResolver(any(Map.class))).thenReturn(resourceResolver);
         when(resourceResolverFactory.isVanityPathEnabled()).thenReturn(true);
         
when(resourceResolverFactory.getVanityPathConfig()).thenReturn(configs);
         
when(resourceResolverFactory.isOptimizeAliasResolutionEnabled()).thenReturn(true);


Reply via email to