Package org.sonatype.nexus.proxy.router

Source Code of org.sonatype.nexus.proxy.router.DefaultRepositoryRouterTest

/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2007-2014 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.proxy.router;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.sonatype.nexus.NexusAppTestSupport;
import org.sonatype.nexus.configuration.application.ApplicationConfiguration;
import org.sonatype.nexus.configuration.model.CRepository;
import org.sonatype.nexus.configuration.model.DefaultCRepository;
import org.sonatype.nexus.proxy.ResourceStoreRequest;
import org.sonatype.nexus.proxy.access.Action;
import org.sonatype.nexus.proxy.item.StorageCollectionItem;
import org.sonatype.nexus.proxy.item.StorageItem;
import org.sonatype.nexus.proxy.maven.MavenGroupRepository;
import org.sonatype.nexus.proxy.maven.maven1.M1LayoutedM2ShadowRepositoryConfiguration;
import org.sonatype.nexus.proxy.maven.maven1.M1Repository;
import org.sonatype.nexus.proxy.maven.maven2.M2GroupRepository;
import org.sonatype.nexus.proxy.maven.maven2.M2LayoutedM1ShadowRepository;
import org.sonatype.nexus.proxy.maven.maven2.M2Repository;
import org.sonatype.nexus.proxy.maven.maven2.Maven2ContentClass;
import org.sonatype.nexus.proxy.registry.RepositoryRegistry;
import org.sonatype.nexus.proxy.repository.GroupRepository;
import org.sonatype.nexus.proxy.repository.Repository;
import org.sonatype.nexus.proxy.repository.ShadowRepository;
import org.sonatype.nexus.proxy.security.PlexusConfiguredRealm;
import org.sonatype.nexus.proxy.targets.Target;
import org.sonatype.nexus.proxy.targets.TargetRegistry;
import org.sonatype.nexus.security.WebSecurityUtil;
import org.sonatype.security.SecuritySystem;
import org.sonatype.security.authentication.AuthenticationException;

import com.google.common.collect.Maps;
import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.name.Names;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.junit.Assert;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;

public class DefaultRepositoryRouterTest
    extends NexusAppTestSupport
{
  private RepositoryRouter router = null;

  private RepositoryRegistry repositoryRegistry = null;

  private SecuritySystem securitySystem = null;

  private ApplicationConfiguration applicationConfiguration;

  private TargetRegistry targetRegistry;

  @Override
  protected void customizeModules(final List<Module> modules) {
    super.customizeModules(modules);
    modules.add(new Module()
    {
      @Override
      public void configure(final Binder binder) {
        final Map<String, String> privileges = Maps.newHashMap();
        privileges.put("repo1user", "nexus:target:*:repo1:*,nexus:view:repository:repo1");
        privileges.put("repo1userNoView", "nexus:target:*:repo1:*");
        privileges.put("admin", "nexus:target:*:*:*,nexus:view:repository:*");

        privileges.put("nxcm4999user", "nexus:view:repository:group1,nexus:target:maven2-all:group1:*");
        privileges.put("nxcm4999userNoSources", "nexus:view:repository:group1,nexus:target:nxcm4999:group1:*");

        final PlexusConfiguredRealm realm = new PlexusConfiguredRealm(privileges);
        binder.bind(Key.get(Realm.class, Names.named("default"))).toInstance(realm);
      }
    });
  }

  @Override
  protected void setUp()
      throws Exception
  {
    super.setUp();

    // loads up config, defaults
    nexusConfiguration().loadConfiguration(false);
    nexusConfiguration().saveConfiguration();

    applicationConfiguration = this.lookup(ApplicationConfiguration.class);
    applicationConfiguration.saveConfiguration();

    this.router = this.lookup(RepositoryRouter.class);
    this.repositoryRegistry = this.lookup(RepositoryRegistry.class);

    this.buildRepository("repo1", true).getCurrentCoreConfiguration();
    this.buildRepository("repo2", true);
    this.buildRepository("repo3-notexposed", false);

    this.buildGroupRepository("group1", true);
    this.buildGroupRepository("group2", true);
    this.buildGroupRepository("group3-notexposed", false);

    this.buildShadowRepository("repo3", true);
    this.buildShadowRepository("repo4", true);
    this.buildShadowRepository("repo5-notexposed", false);

    // copy the security-configuration
    // String resource = this.getClass().getName().replaceAll( "\\.", "\\/" ) + "-security-configuration.xml";
    // URL url = Thread.currentThread().getContextClassLoader().getResource( resource );
    // FileUtils.copyURLToFile( url, new File( getConfHomeDir(), "security-configuration.xml" ) );

    targetRegistry = this.lookup(TargetRegistry.class);

    // shave off defaults
    final Collection<Target> targets = new ArrayList<Target>(targetRegistry.getRepositoryTargets());
    for (Target t : targets) {
      targetRegistry.removeRepositoryTarget(t.getId());
    }

    // create a target
    Target t1 =
        new Target("maven2-all", "All (Maven2)", new Maven2ContentClass(), Arrays.asList(new String[]{".*"}));
    targetRegistry.addRepositoryTarget(t1);

    // flush changes
    applicationConfiguration.saveConfiguration();

    // setup security
    this.securitySystem = this.lookup(SecuritySystem.class);
    this.securitySystem.setRealms(Collections.singletonList("default"));
  }

  @Override
  public void tearDown()
      throws Exception
  {
    try {
      ThreadContext.remove();
    }
    finally {
      super.tearDown();
    }
  }

  protected boolean runWithSecurityDisabled() {
    return false;
  }

  @Test
  public void testNXCM4999UseInRepoPathForTargetMatching()
      throws Exception
  {
    // add repo1 to group1
    repositoryRegistry.getRepositoryWithFacet("group1", MavenGroupRepository.class).addMemberRepositoryId(
        "repo1");
    // create a path specific target
    Target t =
        new Target("nxcm4999", "NXCM4999", new Maven2ContentClass(),
            Arrays.asList(new String[]{"(?!/com/.*-sources.jar).*"}));
    targetRegistry.addRepositoryTarget(t);
    // flush changes
    applicationConfiguration.saveConfiguration();

    {
      final Subject subject = loginUser("nxcm4999user");
      try {
        final ResourceStoreRequest request1 =
            new ResourceStoreRequest("/repositories/repo1/com/mycorp/artifact/1.0/artifact-1.0.jar");
        assertThat("User should have access to this resource as it has all the needed perms.",
            router.authorizePath(request1, Action.read));
        final ResourceStoreRequest request2 =
            new ResourceStoreRequest("/repositories/repo1/com/mycorp/artifact/1.0/artifact-1.0-sources.jar");
        assertThat("User should have access to this resource as it has all the needed perms.",
            router.authorizePath(request2, Action.read));
      }
      finally {
        securitySystem.logout(subject);
      }
    }
    {
      final Subject subject = loginUser("nxcm4999userNoSources");
      try {
        final ResourceStoreRequest request1 =
            new ResourceStoreRequest("/repositories/repo1/com/mycorp/artifact/1.0/artifact-1.0.jar");
        assertThat("User should have access to this resource as it has no needed perms.",
            router.authorizePath(request1, Action.read));
        final ResourceStoreRequest request2 =
            new ResourceStoreRequest("/repositories/repo1/com/mycorp/artifact/1.0/artifact-1.0-sources.jar");
        assertThat("User should NOT have access to this resource as it has no needed perms.",
            !router.authorizePath(request2, Action.read));
      }
      finally {
        securitySystem.logout(subject);
      }
    }
  }

  @Test
  public void testRouterWithViewAccess()
      throws Exception
  {
    Subject subject = this.loginUser("repo1user");

    ResourceStoreRequest request = new ResourceStoreRequest("/repositories/");

    StorageItem item = router.retrieveItem(request);

    StorageCollectionItem collectionItem = (StorageCollectionItem) item;

    // this user only has access to repo1, that is all they should see
    Assert.assertEquals("User should only have access to 'repo1'", 1, collectionItem.list().size());
    Assert.assertEquals("repo1", collectionItem.list().iterator().next().getName());

    // logout user
    this.securitySystem.logout(subject);
  }

  @Test
  public void testRouterWithNoViewAccess()
      throws Exception
  {
    Subject subject = this.loginUser("repo1userNoView");

    ResourceStoreRequest request = new ResourceStoreRequest("/repositories/");

    StorageItem item = router.retrieveItem(request);

    StorageCollectionItem collectionItem = (StorageCollectionItem) item;

    // this user only has access to repo1, that is all they should see
    Assert.assertEquals("User should not have access to any repos", 0, collectionItem.list().size());

    // logout user
    this.securitySystem.logout(subject);
  }

  @Test
  public void testFilterOutNonExposedRepositories()
      throws Exception
  {
    Subject subject = this.loginUser("admin");

    ResourceStoreRequest request = new ResourceStoreRequest("/repositories/");

    StorageItem item = router.retrieveItem(request);

    StorageCollectionItem collectionItem = (StorageCollectionItem) item;
    Assert.assertEquals("User should see 8 repositories", 8, collectionItem.list().size()); // we create a new
    // repo for each
    // shadow

    List<String> repoIds = new ArrayList<String>();
    for (StorageItem tmpItem : collectionItem.list()) {
      repoIds.add(tmpItem.getName());
    }

    // now check them all
    Assert.assertTrue(repoIds.contains("repo1"));
    Assert.assertTrue(repoIds.contains("repo2"));
    Assert.assertFalse(repoIds.contains("repo3-notexposed"));

    Assert.assertTrue(repoIds.contains("group1"));
    Assert.assertTrue(repoIds.contains("group2"));
    Assert.assertFalse(repoIds.contains("group3-notexposed"));

    Assert.assertTrue(repoIds.contains("repo3"));
    Assert.assertTrue(repoIds.contains("repo4"));
    Assert.assertFalse(repoIds.contains("repo5-notexposed"));

    Assert.assertTrue(repoIds.contains("repo3-shadow"));
    Assert.assertTrue(repoIds.contains("repo4-shadow"));
    Assert.assertFalse(repoIds.contains("repo5-notexposed-shadow"));

    // logout user
    this.securitySystem.logout(subject);
  }

  @Test
  public void testFilterOutNonExposedGroups()
      throws Exception
  {
    Subject subject = this.loginUser("admin");

    ResourceStoreRequest request = new ResourceStoreRequest("/shadows/");

    StorageItem item = router.retrieveItem(request);

    StorageCollectionItem collectionItem = (StorageCollectionItem) item;
    Assert.assertEquals("User should see 2 groups", 2, collectionItem.list().size());

    List<String> repoIds = new ArrayList<String>();
    for (StorageItem tmpItem : collectionItem.list()) {
      repoIds.add(tmpItem.getName());
    }

    // now check them all
    Assert.assertTrue(repoIds.contains("repo3-shadow"));
    Assert.assertTrue(repoIds.contains("repo4-shadow"));
    Assert.assertFalse(repoIds.contains("repo5-notexposed-shadow"));

    // logout user
    this.securitySystem.logout(subject);
  }

  @Test
  public void testFilterOutNonExposedShadows()
      throws Exception
  {
    Subject subject = this.loginUser("admin");

    ResourceStoreRequest request = new ResourceStoreRequest("/groups/");

    StorageItem item = router.retrieveItem(request);

    StorageCollectionItem collectionItem = (StorageCollectionItem) item;
    Assert.assertEquals("User should see 2 groups", 2, collectionItem.list().size());

    List<String> repoIds = new ArrayList<String>();
    for (StorageItem tmpItem : collectionItem.list()) {
      repoIds.add(tmpItem.getName());
    }

    // now check them all
    Assert.assertTrue(repoIds.contains("group1"));
    Assert.assertTrue(repoIds.contains("group2"));
    Assert.assertFalse(repoIds.contains("group3-notexposed"));

    // logout user
    this.securitySystem.logout(subject);
  }

  private M2Repository buildRepository(String repoId, boolean exposed)
      throws Exception
  {
    M2Repository repo = (M2Repository) this.lookup(Repository.class, "maven2");
    CRepository repoConfig = new DefaultCRepository();
    repoConfig.setId(repoId);
    repoConfig.setExposed(exposed);
    repoConfig.setProviderRole(Repository.class.getName());
    repoConfig.setProviderHint("maven2");
    repo.configure(repoConfig);
    this.repositoryRegistry.addRepository(repo);
    this.applicationConfiguration.getConfigurationModel().addRepository(repoConfig);

    return repo;
  }

  private Repository buildGroupRepository(String repoId, boolean exposed)
      throws Exception
  {
    M2GroupRepository repo = (M2GroupRepository) this.lookup(GroupRepository.class, "maven2");
    CRepository repoConfig = new DefaultCRepository();
    repoConfig.setId(repoId);
    repoConfig.setExposed(exposed);
    repoConfig.setProviderRole(GroupRepository.class.getName());
    repoConfig.setProviderHint("maven2");
    repo.configure(repoConfig);
    this.repositoryRegistry.addRepository(repo);
    this.applicationConfiguration.getConfigurationModel().addRepository(repoConfig);

    return repo;
  }

  private Repository buildShadowRepository(String repoId, boolean exposed)
      throws Exception
  {
    M1Repository repo = (M1Repository) this.lookup(Repository.class, "maven1");
    CRepository repoConfig = new DefaultCRepository();
    repoConfig.setId(repoId);
    repoConfig.setExposed(exposed);
    repoConfig.setIndexable(false);
    repoConfig.setProviderRole(Repository.class.getName());
    repoConfig.setProviderHint("maven1");
    repo.configure(repoConfig);
    this.repositoryRegistry.addRepository(repo);
    this.applicationConfiguration.getConfigurationModel().addRepository(repoConfig);

    // now for the shadow
    M2LayoutedM1ShadowRepository shadow =
        (M2LayoutedM1ShadowRepository) this.lookup(ShadowRepository.class, "m1-m2-shadow");
    CRepository shadowConfig = new DefaultCRepository();
    shadowConfig.setId(repoId + "-shadow");
    shadowConfig.setExposed(exposed);
    shadowConfig.setProviderRole(ShadowRepository.class.getName());
    shadowConfig.setProviderHint("m2-m1-shadow");
    shadowConfig.setIndexable(false);

    Xpp3Dom exRepo = new Xpp3Dom("externalConfiguration");
    shadowConfig.setExternalConfiguration(exRepo);
    M1LayoutedM2ShadowRepositoryConfiguration exRepoConf = new M1LayoutedM2ShadowRepositoryConfiguration(exRepo);
    exRepoConf.setMasterRepositoryId(repo.getId());

    shadow.configure(shadowConfig);
    // shadow.
    this.repositoryRegistry.addRepository(shadow);
    this.applicationConfiguration.getConfigurationModel().addRepository(shadowConfig);

    return repo;

  }

  private Subject loginUser(String username)
      throws AuthenticationException
  {
    WebSecurityUtil.setupWebContext(username);
    return this.securitySystem.login(new UsernamePasswordToken(username, ""));
  }

}
TOP

Related Classes of org.sonatype.nexus.proxy.router.DefaultRepositoryRouterTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.