]> source.dussan.org Git - archiva.git/commitdiff
[MRM-516] Search results return results for all repositories, regardless of security.
authorJoakim Erdfelt <joakime@apache.org>
Tue, 6 Nov 2007 18:26:04 +0000 (18:26 +0000)
committerJoakim Erdfelt <joakime@apache.org>
Tue, 6 Nov 2007 18:26:04 +0000 (18:26 +0000)
[MRM-569] Browse shows results for all repositories, regardless of security.
Merge of https://svn.apache.org/repos/asf/maven/archiva/branches/archiva-backend-security changes from revision 590763 to HEAD

git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@592513 13f79535-47bb-0310-9956-ffa450edef68

49 files changed:
archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/CrossRepositorySearch.java
archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearch.java
archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/AllTests.java [deleted file]
archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/AllTests.java [deleted file]
archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/BytecodeIndexPopulator.java
archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.java
archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/FileContentIndexPopulator.java
archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/HashcodesIndexPopulator.java
archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/IndexPopulator.java
archiva-base/archiva-indexer/src/test/resources/org/apache/maven/archiva/indexer/search/DefaultCrossRepositorySearchTest.xml
archiva-database/src/main/java/org/apache/maven/archiva/database/ProjectModelDAO.java
archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/BrowsingResults.java
archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/DefaultRepositoryBrowsing.java
archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/GroupIdFilter.java
archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/RepositoryBrowsing.java
archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/SqlBuilder.java [new file with mode: 0644]
archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraint.java
archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/UniqueGroupIdConstraint.java
archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/UniqueVersionConstraint.java
archiva-database/src/main/java/org/apache/maven/archiva/database/jdo/JdoProjectModelDAO.java
archiva-database/src/test/java/org/apache/maven/archiva/database/browsing/RepositoryBrowsingTest.java
archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueGroupIdConstraintTest.java
archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueVersionConstraintTest.java
archiva-web/archiva-security/pom.xml
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/AccessDeniedException.java [new file with mode: 0644]
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaRoleConstants.java
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaSecurityException.java [new file with mode: 0644]
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaStandardRolesCheck.java [new file with mode: 0644]
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaUser.java [new file with mode: 0644]
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/DefaultUserRepositories.java [new file with mode: 0644]
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/PrincipalNotFoundException.java [new file with mode: 0644]
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/SecurityStartup.java [new file with mode: 0644]
archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/UserRepositories.java [new file with mode: 0644]
archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/DefaultUserRepositoriesTest.java [new file with mode: 0644]
archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/SecurityStartupTest.java [new file with mode: 0644]
archiva-web/archiva-security/src/test/resources/META-INF/redback/redback-core.xml [new file with mode: 0644]
archiva-web/archiva-security/src/test/resources/org/apache/maven/archiva/security/DefaultUserRepositoriesTest.xml [new file with mode: 0644]
archiva-web/archiva-security/src/test/resources/org/apache/maven/archiva/security/RoleManagerTest.xml
archiva-web/archiva-security/src/test/resources/org/apache/maven/archiva/security/SecurityStartupTest.xml [new file with mode: 0644]
archiva-web/archiva-security/src/test/resources/repository-archiva.xml [new file with mode: 0644]
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/BrowseAction.java
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/GlobalResults.java [new file with mode: 0644]
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ShowArtifactAction.java
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/SecuritySynchronization.java
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java [new file with mode: 0644]
archiva-web/archiva-webapp/src/main/resources/xwork.xml
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/accessToNoRepos.jsp [new file with mode: 0644]
pom.xml

index 647e572fb5561a1cde42903ee5bf989730462d64..bf560d1a23179c09b3af53e02952d7d2bbb538d0 100644 (file)
@@ -1,5 +1,7 @@
 package org.apache.maven.archiva.indexer.search;
 
+import java.util.List;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -35,7 +37,7 @@ public interface CrossRepositorySearch
      * @param limits the limits to apply to the search results.
      * @return the results.
      */
-    public SearchResults searchForTerm( String term, SearchResultLimits limits );
+    public SearchResults searchForTerm( String principal, List<String> selectedRepos, String term, SearchResultLimits limits );
     
     /**
      * Search for the specific bytecode across all repositories.
@@ -44,7 +46,7 @@ public interface CrossRepositorySearch
      * @param limits the limits to apply to the search results.
      * @return the results.
      */
-    public SearchResults searchForBytecode( String term, SearchResultLimits limits );
+    public SearchResults searchForBytecode( String principal, List<String> selectedRepos, String term, SearchResultLimits limits );
 
     /**
      * Search for the specific checksum string across all repositories.
@@ -53,5 +55,5 @@ public interface CrossRepositorySearch
      * @param limits the limits to apply to the search results.
      * @return the results.
      */
-    public SearchResults searchForChecksum( String checksum, SearchResultLimits limits );
+    public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum, SearchResultLimits limits );
 }
index 3021ab2a58c9a57da6a6e105abc5674fda437997..2b67d9caac744645427dbcdd3b96fa7be1e6b75b 100644 (file)
@@ -33,6 +33,9 @@ import org.apache.maven.archiva.configuration.ArchivaConfiguration;
 import org.apache.maven.archiva.configuration.ConfigurationNames;
 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
 import org.apache.maven.archiva.indexer.RepositoryContentIndex;
+import org.apache.maven.archiva.indexer.RepositoryContentIndexFactory;
+import org.apache.maven.archiva.indexer.RepositoryIndexException;
+import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
 import org.apache.maven.archiva.indexer.bytecode.BytecodeHandlers;
 import org.apache.maven.archiva.indexer.filecontent.FileContentHandlers;
 import org.apache.maven.archiva.indexer.functors.UserAllowedToSearchRepositoryPredicate;
@@ -63,40 +66,20 @@ public class DefaultCrossRepositorySearch
     implements CrossRepositorySearch, RegistryListener, Initializable
 {
     /**
-     * @plexus.requirement role-hint="bytecode"
+     * @plexus.requirement role-hint="lucene"
      */
-    private Transformer bytecodeIndexTransformer;
-
-    /**
-     * @plexus.requirement role-hint="filecontent"
-     */
-    private Transformer filecontentIndexTransformer;
-
-    /**
-     * @plexus.requirement role-hint="hashcodes"
-     */
-    private Transformer hashcodesIndexTransformer;
-
-    /**
-     * @plexus.requirement role-hint="searchable"
-     */
-    private Transformer searchableTransformer;
-
-    /**
-     * @plexus.requirement role-hint="index-exists"
-     */
-    private Predicate indexExistsPredicate;
-
+    private RepositoryContentIndexFactory indexFactory;
+    
     /**
      * @plexus.requirement
      */
     private ArchivaConfiguration configuration;
 
-    private List localIndexedRepositories = new ArrayList();
+    private List<ManagedRepositoryConfiguration> localIndexedRepositories = new ArrayList<ManagedRepositoryConfiguration>();
 
-    public SearchResults searchForChecksum( String checksum, SearchResultLimits limits )
+    public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum, SearchResultLimits limits )
     {
-        List indexes = getHashcodeIndexes();
+        List<RepositoryContentIndex> indexes = getHashcodeIndexes( principal, selectedRepos );
 
         try
         {
@@ -117,9 +100,9 @@ public class DefaultCrossRepositorySearch
         return new SearchResults();
     }
 
-    public SearchResults searchForBytecode( String term, SearchResultLimits limits )
+    public SearchResults searchForBytecode( String principal, List<String> selectedRepos, String term, SearchResultLimits limits )
     {
-        List indexes = getHashcodeIndexes();
+        List<RepositoryContentIndex> indexes = getHashcodeIndexes( principal, selectedRepos );
 
         try
         {
@@ -139,9 +122,9 @@ public class DefaultCrossRepositorySearch
         return new SearchResults();
     }
 
-    public SearchResults searchForTerm( String term, SearchResultLimits limits )
+    public SearchResults searchForTerm( String principal, List<String> selectedRepos, String term, SearchResultLimits limits )
     {
-        List indexes = getFileContentIndexes();
+        List<RepositoryContentIndex> indexes = getFileContentIndexes( principal, selectedRepos );
 
         try
         {
@@ -161,7 +144,7 @@ public class DefaultCrossRepositorySearch
         return new SearchResults();
     }
 
-    private SearchResults searchAll( LuceneQuery luceneQuery, SearchResultLimits limits, List indexes )
+    private SearchResults searchAll( LuceneQuery luceneQuery, SearchResultLimits limits, List<RepositoryContentIndex> indexes )
     {
         org.apache.lucene.search.Query specificQuery = luceneQuery.getLuceneQuery();
 
@@ -175,12 +158,11 @@ public class DefaultCrossRepositorySearch
 
         // Setup the converter
         LuceneEntryConverter converter = null;
-        RepositoryContentIndex index = (RepositoryContentIndex) indexes.get( 0 );
+        RepositoryContentIndex index = indexes.get( 0 );
         converter = index.getEntryConverter();
 
         // Process indexes into an array of Searchables.
-        List searchableList = new ArrayList( indexes );
-        CollectionUtils.transform( searchableList, searchableTransformer );
+        List<Searchable> searchableList = toSearchables( indexes );
 
         Searchable searchables[] = new Searchable[searchableList.size()];
         searchableList.toArray( searchables );
@@ -258,52 +240,102 @@ public class DefaultCrossRepositorySearch
         return results;
     }
 
-    private Predicate getAllowedToSearchReposPredicate()
+    private List<Searchable> toSearchables( List<RepositoryContentIndex> indexes )
     {
-        return new UserAllowedToSearchRepositoryPredicate();
+        List<Searchable> searchableList = new ArrayList<Searchable>();
+        for ( RepositoryContentIndex contentIndex : indexes )
+        {
+            try
+            {
+                searchableList.add( contentIndex.getSearchable() );
+            }
+            catch ( RepositoryIndexSearchException e )
+            {
+                getLogger().warn( "Unable to get searchable for index [" + contentIndex.getId() + "] :"
+                                      + e.getMessage(), e );
+            }
+        }
+        return searchableList;
     }
 
-    public List getBytecodeIndexes()
+    public List<RepositoryContentIndex> getBytecodeIndexes( String principal, List<String> selectedRepos )
     {
-        List ret = new ArrayList();
+        List<RepositoryContentIndex> ret = new ArrayList<RepositoryContentIndex>();
 
-        synchronized ( this.localIndexedRepositories )
+        for ( ManagedRepositoryConfiguration repoConfig : localIndexedRepositories )
         {
-            ret.addAll( CollectionUtils.select( this.localIndexedRepositories, getAllowedToSearchReposPredicate() ) );
-            CollectionUtils.transform( ret, bytecodeIndexTransformer );
-            CollectionUtils.filter( ret, indexExistsPredicate );
+            // Only used selected repo
+            if ( selectedRepos.contains( repoConfig.getId() ) )
+            {
+                RepositoryContentIndex index = indexFactory.createBytecodeIndex( repoConfig );
+                // If they exist.
+                if ( indexExists( index ) )
+                {
+                    ret.add( index );
+                }
+            }
         }
 
         return ret;
     }
 
-    public List getFileContentIndexes()
+    public List<RepositoryContentIndex> getFileContentIndexes( String principal, List<String> selectedRepos )
     {
-        List ret = new ArrayList();
+        List<RepositoryContentIndex> ret = new ArrayList<RepositoryContentIndex>();
 
-        synchronized ( this.localIndexedRepositories )
+        for ( ManagedRepositoryConfiguration repoConfig : localIndexedRepositories )
         {
-            ret.addAll( CollectionUtils.select( this.localIndexedRepositories, getAllowedToSearchReposPredicate() ) );
-            CollectionUtils.transform( ret, filecontentIndexTransformer );
-            CollectionUtils.filter( ret, indexExistsPredicate );
+            // Only used selected repo
+            if ( selectedRepos.contains( repoConfig.getId() ) )
+            {
+                RepositoryContentIndex index = indexFactory.createFileContentIndex( repoConfig );
+                // If they exist.
+                if ( indexExists( index ) )
+                {
+                    ret.add( index );
+                }
+            }
         }
 
         return ret;
     }
 
-    public List getHashcodeIndexes()
+    public List<RepositoryContentIndex> getHashcodeIndexes( String principal, List<String> selectedRepos )
     {
-        List ret = new ArrayList();
+        List<RepositoryContentIndex> ret = new ArrayList<RepositoryContentIndex>();
 
-        synchronized ( this.localIndexedRepositories )
+        for ( ManagedRepositoryConfiguration repoConfig : localIndexedRepositories )
         {
-            ret.addAll( CollectionUtils.select( this.localIndexedRepositories, getAllowedToSearchReposPredicate() ) );
-            CollectionUtils.transform( ret, hashcodesIndexTransformer );
-            CollectionUtils.filter( ret, indexExistsPredicate );
+            // Only used selected repo
+            if ( selectedRepos.contains( repoConfig.getId() ) )
+            {
+                RepositoryContentIndex index = indexFactory.createHashcodeIndex( repoConfig );
+                // If they exist.
+                if ( indexExists( index ) )
+                {
+                    ret.add( index );
+                }
+            }
         }
 
         return ret;
     }
+    
+    private boolean indexExists( RepositoryContentIndex index )
+    {
+        try
+        {
+            return index.exists();
+        }
+        catch ( RepositoryIndexException e )
+        {
+            getLogger().info(
+                              "Repository Content Index [" + index.getId() + "] for repository ["
+                                  + index.getRepository().getId() + "] does not exist yet in ["
+                                  + index.getIndexDirectory().getAbsolutePath() + "]." );
+            return false;
+        }
+    }
 
     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
     {
diff --git a/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/AllTests.java b/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/AllTests.java
deleted file mode 100644 (file)
index 2160e8e..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.apache.maven.archiva.indexer;
-
-/*
- * 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.
- */
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * AllTests - conveinence test suite for IDE users. 
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class AllTests
-{
-
-    public static Test suite()
-    {
-        TestSuite suite = new TestSuite( "Test for org.apache.maven.archiva.indexer" );
-        //$JUnit-BEGIN$
-        suite.addTest( org.apache.maven.archiva.indexer.bytecode.AllTests.suite() );
-        suite.addTest( org.apache.maven.archiva.indexer.hashcodes.AllTests.suite() );
-        suite.addTest( org.apache.maven.archiva.indexer.query.AllTests.suite() );
-        suite.addTest( org.apache.maven.archiva.indexer.search.AllTests.suite() );
-        //$JUnit-END$
-        return suite;
-    }
-
-}
diff --git a/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/AllTests.java b/archiva-base/archiva-indexer/src/test/java/org/apache/maven/archiva/indexer/search/AllTests.java
deleted file mode 100644 (file)
index 9c2a8f2..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.apache.maven.archiva.indexer.search;
-
-/*
- * 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.
- */
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * AllTests - conveinence test suite for IDE users. 
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class AllTests
-{
-    public static Test suite()
-    {
-        TestSuite suite = new TestSuite( "Test for org.apache.maven.archiva.indexer.search" );
-        //$JUnit-BEGIN$
-        suite.addTestSuite( DefaultCrossRepositorySearchTest.class );
-        //$JUnit-END$
-        return suite;
-    }
-}
index eec1a08d5eb9c44c99803ea402315b1d749fd23a..4587ef7a70b4988d7123d945de82fab6d42bc6e9 100644 (file)
@@ -19,15 +19,16 @@ package org.apache.maven.archiva.indexer.search;
  * under the License.
  */
 
-import junit.framework.AssertionFailedError;
 import org.apache.maven.archiva.indexer.bytecode.BytecodeRecord;
 import org.apache.maven.archiva.indexer.bytecode.BytecodeRecordLoader;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 
 import java.io.File;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
+import java.util.Map.Entry;
+
+import junit.framework.AssertionFailedError;
 
 /**
  * BytecodeIndexPopulator
@@ -39,10 +40,10 @@ public class BytecodeIndexPopulator
     implements IndexPopulator
 {
 
-    public Map getObjectMap()
+    public Map<String,ArchivaArtifact> getObjectMap()
     {
 
-        Map dumps = new HashMap();
+        Map<String,ArchivaArtifact> dumps = new HashMap<String,ArchivaArtifact>();
 
         // archiva-common-1.0.jar.txt
         dumps.put( "archiva-common",
@@ -86,15 +87,13 @@ public class BytecodeIndexPopulator
         return artifact;
     }
 
-    public Map populate( File basedir )
+    public Map<String, BytecodeRecord> populate( File basedir )
     {
-        Map records = new HashMap();
+        Map<String, BytecodeRecord> records = new HashMap<String, BytecodeRecord>();
 
-        Map artifactDumps = getObjectMap();
-        for ( Iterator iter = artifactDumps.entrySet().iterator(); iter.hasNext(); )
+        for ( Entry<String, ArchivaArtifact> entry : getObjectMap().entrySet() )
         {
-            Map.Entry entry = (Map.Entry) iter.next();
-            ArchivaArtifact artifact = (ArchivaArtifact) entry.getValue();
+            ArchivaArtifact artifact = entry.getValue();
             File dumpFile = getDumpFile( basedir, artifact );
             BytecodeRecord record = BytecodeRecordLoader.loadRecord( dumpFile, artifact );
             record.setRepositoryId( "test-repo" );
index fef16cba778e3b188c678b21f0aa4157f4af8047..cee75ec0a6afc3441397369ab9dd18f4331258ca 100644 (file)
@@ -28,10 +28,16 @@ import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
 import org.apache.maven.archiva.indexer.MockConfiguration;
 import org.apache.maven.archiva.indexer.RepositoryContentIndex;
 import org.apache.maven.archiva.indexer.RepositoryContentIndexFactory;
+import org.apache.maven.archiva.indexer.bytecode.BytecodeRecord;
+import org.apache.maven.archiva.indexer.filecontent.FileContentRecord;
+import org.apache.maven.archiva.indexer.hashcodes.HashcodesRecord;
 import org.codehaus.plexus.PlexusTestCase;
 import org.codehaus.plexus.util.FileUtils;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -47,6 +53,7 @@ public class DefaultCrossRepositorySearchTest
 
     private static final String TEST_DEFAULT_REPO_ID = "testDefaultRepo";
 
+    @Override
     protected void setUp()
         throws Exception
     {
@@ -86,17 +93,17 @@ public class DefaultCrossRepositorySearchTest
         RepositoryContentIndex indexContents = indexFactory.createFileContentIndex( repository );
 
         // Now populate them.
-        Map hashcodesMap = ( new HashcodesIndexPopulator() ).populate( new File( getBasedir() ) );
+        Map<String, HashcodesRecord> hashcodesMap = new HashcodesIndexPopulator().populate( new File( getBasedir() ) );
         indexHashcode.indexRecords( hashcodesMap.values() );
         assertEquals( "Hashcode Key Count", hashcodesMap.size(), indexHashcode.getAllRecordKeys().size() );
         assertRecordCount( indexHashcode, hashcodesMap.size() );
 
-        Map bytecodeMap = ( new BytecodeIndexPopulator() ).populate( new File( getBasedir() ) );
+        Map<String, BytecodeRecord> bytecodeMap = new BytecodeIndexPopulator().populate( new File( getBasedir() ) );
         indexBytecode.indexRecords( bytecodeMap.values() );
         assertEquals( "Bytecode Key Count", bytecodeMap.size(), indexBytecode.getAllRecordKeys().size() );
         assertRecordCount( indexBytecode, bytecodeMap.size() );
 
-        Map contentMap = ( new FileContentIndexPopulator() ).populate( new File( getBasedir() ) );
+        Map<String, FileContentRecord> contentMap = new FileContentIndexPopulator().populate( new File( getBasedir() ) );
         indexContents.indexRecords( contentMap.values() );
         assertEquals( "File Content Key Count", contentMap.size(), indexContents.getAllRecordKeys().size() );
         assertRecordCount( indexContents, contentMap.size() );
@@ -125,23 +132,31 @@ public class DefaultCrossRepositorySearchTest
     {
         CrossRepositorySearch search = lookupCrossRepositorySearch();
 
-        SearchResultLimits limits = new SearchResultLimits( 0 );
-        limits.setPageSize( 20 );
-
-        SearchResults results = search.searchForTerm( "org", limits );
-        assertResults( 1, 7, results );
+        String expectedRepos[] = new String[] {
+            TEST_DEFAULT_REPO_ID
+        };
+        
+        String expectedResults[] = new String[] { 
+            "org","org2","org3","org4","org5","org6","org7"
+        };
+        
+        assertSearchResults( expectedRepos, expectedResults, search, "org" );
     }
 
     public void testSearchTerm_Junit()
         throws Exception
     {
         CrossRepositorySearch search = lookupCrossRepositorySearch();
-
-        SearchResultLimits limits = new SearchResultLimits( 0 );
-        limits.setPageSize( 20 );
-
-        SearchResults results = search.searchForTerm( "junit", limits );
-        assertResults( 1, 3, results );
+        
+        String expectedRepos[] = new String[] {
+            TEST_DEFAULT_REPO_ID
+        };
+        
+        String expectedResults[] = new String[] { 
+            "junit","junit2","junit3"
+        };
+        
+        assertSearchResults( expectedRepos, expectedResults, search, "junit" );
     }
 
     public void testSearchInvalidTerm()
@@ -149,21 +164,37 @@ public class DefaultCrossRepositorySearchTest
     {
         CrossRepositorySearch search = lookupCrossRepositorySearch();
 
-        SearchResultLimits limits = new SearchResultLimits( 0 );
-        limits.setPageSize( 20 );
-
-        SearchResults results = search.searchForTerm( "monosodium", limits );
-        assertResults( 1, 0, results );
+        String expectedRepos[] = new String[] {
+            TEST_DEFAULT_REPO_ID
+        };
+        
+        String expectedResults[] = new String[] { 
+            // Nothing.
+        };
+        
+        assertSearchResults( expectedRepos, expectedResults, search, "monosodium" );
     }
-
-    private void assertResults( int repoCount, int hitCount, SearchResults results )
+    
+    private void assertSearchResults( String expectedRepos[], String expectedResults[], CrossRepositorySearch search, String term )
+        throws Exception
     {
+        SearchResultLimits limits = new SearchResultLimits( 0 );
+        limits.setPageSize( 20 );
+        
+        List<String> selectedRepos = new ArrayList<String>();
+        selectedRepos.addAll( Arrays.asList( expectedRepos ) );
+        
+        SearchResults results = search.searchForTerm( "guest", selectedRepos, term, limits );
+        
         assertNotNull( "Search Results should not be null.", results );
-        assertEquals( "Repository Hits", repoCount, results.getRepositories().size() );
+        assertEquals( "Repository Hits", expectedRepos.length, results.getRepositories().size() );
+        // TODO: test the repository ids returned.
 
-        assertEquals( "Search Result Hits", hitCount, results.getHits().size() );
+        assertEquals( "Search Result Hits", expectedResults.length, results.getHits().size() );
+        // TODO: test the order of hits.
+        // TODO: test the value of the hits.
     }
-    
+
     protected ManagedRepositoryConfiguration createRepository( String id, String name, File location )
     {
         ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();
index d9b1c38467f28bcec68b8ddc4c1d4be3654446d0..326061d56c88f58eeabf73cbd660c95cabf9f947 100644 (file)
@@ -21,6 +21,7 @@ package org.apache.maven.archiva.indexer.search;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.archiva.indexer.filecontent.FileContentRecord;
+import org.apache.maven.archiva.model.ArchivaArtifact;
 
 import java.io.File;
 import java.io.IOException;
@@ -38,14 +39,14 @@ import junit.framework.AssertionFailedError;
 public class FileContentIndexPopulator
     implements IndexPopulator
 {
-    public Map getObjectMap()
+    public Map<String, ArchivaArtifact> getObjectMap()
     {
         return null;
     }
 
-    public Map populate( File basedir )
+    public Map<String, FileContentRecord> populate( File basedir )
     {
-        Map map = new HashMap();
+        Map<String, FileContentRecord> map = new HashMap<String, FileContentRecord>();
 
         File repoDir = new File( basedir, "src/test/managed-repository" );
 
index 4fa9f6034acb54d4c96e7dd6b493e9c8f855eb1f..6dcb146a60cefe6bbb714b23e2d039725b557959 100644 (file)
@@ -1,22 +1,48 @@
 package org.apache.maven.archiva.indexer.search;
 
-import junit.framework.AssertionFailedError;
+/*
+ * 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.
+ */
+
 import org.apache.maven.archiva.indexer.hashcodes.HashcodesRecord;
 import org.apache.maven.archiva.indexer.hashcodes.HashcodesRecordLoader;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 
 import java.io.File;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
+import java.util.Map.Entry;
+
+import junit.framework.AssertionFailedError;
 
+/**
+ * HashcodesIndexPopulator 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
 public class HashcodesIndexPopulator
     implements IndexPopulator
 {
 
-    public Map getObjectMap()
+    public Map<String, ArchivaArtifact> getObjectMap()
     {
-        Map dumps = new HashMap();
+        Map<String, ArchivaArtifact> dumps = new HashMap<String, ArchivaArtifact>();
 
         // archiva-common-1.0.jar.txt
         dumps.put( "archiva-common",
@@ -52,15 +78,13 @@ public class HashcodesIndexPopulator
         return dumps;
     }
 
-    public Map populate( File basedir )
+    public Map<String, HashcodesRecord> populate( File basedir )
     {
-        Map records = new HashMap();
+        Map<String, HashcodesRecord> records = new HashMap<String, HashcodesRecord>();
 
-        Map artifactDumps = getObjectMap();
-        for ( Iterator iter = artifactDumps.entrySet().iterator(); iter.hasNext(); )
+        for ( Entry<String, ArchivaArtifact> entry : getObjectMap().entrySet() )
         {
-            Map.Entry entry = (Map.Entry) iter.next();
-            ArchivaArtifact artifact = (ArchivaArtifact) entry.getValue();
+            ArchivaArtifact artifact = entry.getValue();
             File dumpFile = getDumpFile( basedir, artifact );
             HashcodesRecord record = HashcodesRecordLoader.loadRecord( dumpFile, artifact );
             record.setRepositoryId( "test-repo" );
index a483f717c6423305740dfb7832f3b056148f35a0..6f4892dac77e314f488ee37783fed0dc5bed6e22 100644 (file)
@@ -19,6 +19,9 @@ package org.apache.maven.archiva.indexer.search;
  * under the License.
  */
 
+import org.apache.maven.archiva.indexer.lucene.LuceneRepositoryContentRecord;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+
 import java.io.File;
 import java.util.Map;
 
@@ -30,7 +33,7 @@ import java.util.Map;
  */
 public interface IndexPopulator
 {
-    public Map getObjectMap();
+    public Map<String, ArchivaArtifact> getObjectMap();
 
-    public Map populate( File basedir );
+    public Map<String, ? extends LuceneRepositoryContentRecord> populate( File basedir );
 }
index 4b078f6a82ef1d8a1682a0a048dc1f4ac76507f1..61a859c7a05fada55a3faef3dac156390a58ac23 100644 (file)
       <description>DefaultCrossRepositorySearch</description>
       <requirements>
         <requirement>
-          <role>org.apache.commons.collections.Transformer</role>
-          <role-hint>bytecode</role-hint>
-          <field-name>bytecodeIndexTransformer</field-name>
-        </requirement>
-        <requirement>
-          <role>org.apache.commons.collections.Transformer</role>
-          <role-hint>filecontent</role-hint>
-          <field-name>filecontentIndexTransformer</field-name>
-        </requirement>
-        <requirement>
-          <role>org.apache.commons.collections.Transformer</role>
-          <role-hint>hashcodes</role-hint>
-          <field-name>hashcodesIndexTransformer</field-name>
-        </requirement>
-        <requirement>
-          <role>org.apache.commons.collections.Transformer</role>
-          <role-hint>searchable</role-hint>
-          <field-name>searchableTransformer</field-name>
-        </requirement>
-        <requirement>
-          <role>org.apache.commons.collections.Predicate</role>
-          <role-hint>index-exists</role-hint>
-          <field-name>indexExistsPredicate</field-name>
+          <role>org.apache.maven.archiva.indexer.RepositoryContentIndexFactory</role>
+          <role-hint>lucene</role-hint>
+          <field-name>indexFactory</field-name>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
index 318e4a4ad33d867bb0b19e06765e5523cac5fe9a..492d6d7bf8a2553ad1d9e56307b64df8ad4601c4 100644 (file)
@@ -57,7 +57,7 @@ public interface ProjectModelDAO
     public ArchivaProjectModel getProjectModel( String groupId, String artifactId, String version )
         throws ObjectNotFoundException, ArchivaDatabaseException;
 
-    public List /*<ArchivaProjectModel>*/queryProjectModels( Constraint constraint )
+    public List<ArchivaProjectModel> queryProjectModels( Constraint constraint )
         throws ObjectNotFoundException, ArchivaDatabaseException;
 
     public ArchivaProjectModel saveProjectModel( ArchivaProjectModel model )
index 6cc7f8a7ec2634aa0f77d694baa53a7c70e286bc..ccf526662401ec67cf6cb0006ab4f7471780fca7 100644 (file)
@@ -32,14 +32,16 @@ import java.util.List;
 public class BrowsingResults
 {
     private String selectedGroupId;
-    
+
     private String selectedArtifactId;
 
-    private List groupIds = null;
+    private List<String> selectedRepositoryIds = null;
+
+    private List<String> groupIds = null;
 
-    private List artifacts = null;
+    private List<String> artifacts = null;
 
-    private List versions = null;
+    private List<String> versions = null;
 
     public BrowsingResults()
     {
@@ -50,19 +52,19 @@ public class BrowsingResults
     {
         this.selectedGroupId = groupId;
     }
-    
+
     public BrowsingResults( String groupId, String artifactId )
     {
         this.selectedGroupId = groupId;
         this.selectedArtifactId = artifactId;
     }
 
-    public List getArtifacts()
+    public List<String> getArtifacts()
     {
         return artifacts;
     }
 
-    public List getGroupIds()
+    public List<String> getGroupIds()
     {
         return groupIds;
     }
@@ -77,7 +79,7 @@ public class BrowsingResults
         return selectedGroupId;
     }
 
-    public List getVersions()
+    public List<String> getVersions()
     {
         return versions;
     }
@@ -97,18 +99,28 @@ public class BrowsingResults
         return CollectionUtils.isNotEmpty( versions );
     }
 
-    public void setArtifacts( List artifacts )
+    public void setArtifacts( List<String> artifacts )
     {
         this.artifacts = artifacts;
     }
 
-    public void setGroupIds( List groupIds )
+    public void setGroupIds( List<String> groupIds )
     {
         this.groupIds = groupIds;
     }
 
-    public void setVersions( List versions )
+    public void setVersions( List<String> versions )
     {
         this.versions = versions;
     }
+
+    public List<String> getSelectedRepositoryIds()
+    {
+        return selectedRepositoryIds;
+    }
+
+    public void setSelectedRepositoryIds( List<String> selectedRepositoryIds )
+    {
+        this.selectedRepositoryIds = selectedRepositoryIds;
+    }
 }
index c3b1058ca89d8a368415107d2a0189971fdb11b2..6249352a03d2cc15870e4d94f29818bb1485fd4d 100644 (file)
@@ -22,6 +22,8 @@ package org.apache.maven.archiva.database.browsing;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.PredicateUtils;
 import org.apache.commons.collections.functors.NotPredicate;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.common.utils.VersionUtil;
 import org.apache.maven.archiva.database.ArchivaDAO;
 import org.apache.maven.archiva.database.ArchivaDatabaseException;
 import org.apache.maven.archiva.database.ObjectNotFoundException;
@@ -32,14 +34,14 @@ import org.apache.maven.archiva.database.constraints.UniqueVersionConstraint;
 import org.apache.maven.archiva.database.updater.DatabaseUpdater;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 import org.apache.maven.archiva.model.ArchivaProjectModel;
-import org.apache.maven.archiva.common.utils.VersionUtil;
+import org.apache.maven.archiva.model.Keys;
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.HashMap;
+import java.util.Map.Entry;
 
 /**
  * DefaultRepositoryBrowsing
@@ -62,23 +64,26 @@ public class DefaultRepositoryBrowsing
      */
     private DatabaseUpdater dbUpdater;
 
-    public BrowsingResults getRoot()
+    public BrowsingResults getRoot( String principle, List<String> observableRepositoryIds )
     {
-        List groups = dao.query( new UniqueGroupIdConstraint() );
+        List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds ) );
 
         BrowsingResults results = new BrowsingResults();
+        results.setSelectedRepositoryIds( observableRepositoryIds );
 
         results.setGroupIds( GroupIdFilter.filterGroups( groups ) );
 
         return results;
     }
 
-    public BrowsingResults selectArtifactId( String groupId, String artifactId )
+    public BrowsingResults selectArtifactId( String principle, List<String> observableRepositoryIds, String groupId,
+                                             String artifactId )
     {
         // NOTE: No group Id or artifact Id's should be returned here. 
-        List versions = dao.query( new UniqueVersionConstraint( groupId, artifactId ) );
+        List<String> versions = dao.query( new UniqueVersionConstraint( observableRepositoryIds, groupId, artifactId ) );
 
         BrowsingResults results = new BrowsingResults( groupId, artifactId );
+        results.setSelectedRepositoryIds( observableRepositoryIds );
 
         processSnapshots( versions );
 
@@ -87,10 +92,10 @@ public class DefaultRepositoryBrowsing
         return results;
     }
 
-    public BrowsingResults selectGroupId( String groupId )
+    public BrowsingResults selectGroupId( String principle, List<String> observableRepositoryIds, String groupId )
     {
-        List groups = dao.query( new UniqueGroupIdConstraint( groupId ) );
-        List artifacts = dao.query( new UniqueArtifactIdConstraint( groupId ) );
+        List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds, groupId ) );
+        List<String> artifacts = dao.query( new UniqueArtifactIdConstraint( observableRepositoryIds, groupId ) );
 
         BrowsingResults results = new BrowsingResults( groupId );
 
@@ -104,10 +109,11 @@ public class DefaultRepositoryBrowsing
         return results;
     }
 
-    public ArchivaProjectModel selectVersion( String groupId, String artifactId, String version )
+    public ArchivaProjectModel selectVersion( String principle, List<String> observableRepositoryIds, String groupId,
+                                              String artifactId, String version )
         throws ObjectNotFoundException, ArchivaDatabaseException
     {
-        ArchivaArtifact pomArtifact = getArtifact( groupId, artifactId, version );
+        ArchivaArtifact pomArtifact = getArtifact( principle, observableRepositoryIds, groupId, artifactId, version );
 
         ArchivaProjectModel model;
         version = pomArtifact.getVersion();
@@ -123,7 +129,8 @@ public class DefaultRepositoryBrowsing
         return model;
     }
 
-    private ArchivaArtifact getArtifact( String groupId, String artifactId, String version )
+    private ArchivaArtifact getArtifact( String principle, List<String> observableRepositoryIds, String groupId,
+                                         String artifactId, String version )
         throws ObjectNotFoundException, ArchivaDatabaseException
     {
         ArchivaArtifact pomArtifact = null;
@@ -139,18 +146,30 @@ public class DefaultRepositoryBrowsing
 
         if ( pomArtifact == null )
         {
-            throw new ObjectNotFoundException(
-                "Unable to find artifact [" + groupId + ":" + artifactId + ":" + version + "]" );
+            throw new ObjectNotFoundException( "Unable to find artifact [" + Keys.toKey( groupId, artifactId, version )
+                + "]" );
+        }
+
+        // Allowed to see this?
+        if ( observableRepositoryIds.contains( pomArtifact.getModel().getRepositoryId() ) )
+        {
+            return pomArtifact;
+        }
+        else
+        {
+            throw new ObjectNotFoundException( "Unable to find artifact " + Keys.toKey( groupId, artifactId, version )
+                + " in observable repository [" + StringUtils.join( observableRepositoryIds.iterator(), ", " )
+                + "] for user " + principle );
         }
-        return pomArtifact;
     }
 
-    public List getUsedBy( String groupId, String artifactId, String version )
+    public List<ArchivaProjectModel> getUsedBy( String principle, List<String> observableRepositoryIds, String groupId,
+                                                String artifactId, String version )
         throws ArchivaDatabaseException
     {
-        ProjectsByArtifactUsageConstraint constraint =
-            new ProjectsByArtifactUsageConstraint( groupId, artifactId, version );
-        List results = dao.getProjectModelDAO().queryProjectModels( constraint );
+        ProjectsByArtifactUsageConstraint constraint = new ProjectsByArtifactUsageConstraint( groupId, artifactId,
+                                                                                              version );
+        List<ArchivaProjectModel> results = dao.getProjectModelDAO().queryProjectModels( constraint );
         if ( results == null )
         {
             // defensive. to honor contract as specified. never null.
@@ -178,15 +197,14 @@ public class DefaultRepositoryBrowsing
      *
      * @param versions
      */
-    private void processSnapshots( List versions )
+    private void processSnapshots( List<String> versions )
     {
-        Map snapshots = new HashMap();
+        Map<String, String> snapshots = new HashMap<String, String>();
 
         getLogger().info( "Processing snapshots." );
 
-        for ( Iterator iter = versions.iterator(); iter.hasNext(); )
+        for ( String version : versions )
         {
-            String version = (String) iter.next();
             if ( VersionUtil.isSnapshot( version ) )
             {
                 String baseVersion = VersionUtil.getBaseVersion( version );
@@ -197,9 +215,9 @@ public class DefaultRepositoryBrowsing
             }
         }
 
-        for ( Iterator it = ( snapshots.entrySet() ).iterator(); it.hasNext(); )
+        for ( Entry<String, String> entry : snapshots.entrySet() )
         {
-            String baseVersion = (String) ( (Map.Entry) it.next() ).getValue();
+            String baseVersion = entry.getValue();
             if ( !versions.contains( baseVersion ) )
             {
                 versions.add( baseVersion );
@@ -227,14 +245,12 @@ public class DefaultRepositoryBrowsing
     {
         if ( VersionUtil.isGenericSnapshot( version ) )
         {
-            List versions = dao.query( new UniqueVersionConstraint( groupId, artifactId ) );
+            List<String> versions = dao.query( new UniqueVersionConstraint( groupId, artifactId ) );
             Collections.sort( versions );
             Collections.reverse( versions );
 
-            for ( Iterator iter = versions.iterator(); iter.hasNext(); )
+            for ( String uniqueVersion : versions )
             {
-                String uniqueVersion = (String) iter.next();
-
                 if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) )
                 {
                     getLogger().info( "Retrieving artifact with version " + uniqueVersion );
@@ -266,8 +282,8 @@ public class DefaultRepositoryBrowsing
 
             if ( model == null )
             {
-                throw new ObjectNotFoundException(
-                    "Unable to find project model for [" + groupId + ":" + artifactId + ":" + version + "]" );
+                throw new ObjectNotFoundException( "Unable to find project model for ["
+                    + Keys.toKey( groupId, artifactId, version ) + "]" );
             }
 
             return model;
index 27f14e0dac44a069fe207896d91c5783edcfe9bd..18b7bdba58cc5624a3a2ee0ce43ea6e253ec27dd 100644 (file)
@@ -20,7 +20,6 @@ package org.apache.maven.archiva.database.browsing;
  */
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
@@ -77,21 +76,19 @@ public class GroupIdFilter
      * @param groups the list of groupIds.
      * @return
      */
-    public static List filterGroups( List groups )
+    public static List<String> filterGroups( List<String> groups )
     {
         GroupTreeNode tree = buildGroupTree( groups );
         return collateGroups( tree );
     }
 
-    public static GroupTreeNode buildGroupTree( List groups )
+    public static GroupTreeNode buildGroupTree( List<String> groups )
     {
         GroupTreeNode rootNode = new GroupTreeNode();
 
         // build a tree structure
-        for ( Iterator i = groups.iterator(); i.hasNext(); )
+        for ( String groupId : groups )
         {
-            String groupId = (String) i.next();
-
             StringTokenizer tok = new StringTokenizer( groupId, GROUP_SEPARATOR );
 
             GroupTreeNode node = rootNode;
@@ -108,7 +105,7 @@ public class GroupIdFilter
                 }
                 else
                 {
-                    node = (GroupTreeNode) node.getChildren().get( part );
+                    node = node.getChildren().get( part );
                 }
             }
         }
@@ -116,16 +113,14 @@ public class GroupIdFilter
         return rootNode;
     }
 
-    private static List collateGroups( GroupTreeNode rootNode )
+    private static List<String> collateGroups( GroupTreeNode rootNode )
     {
-        List groups = new ArrayList();
-        for ( Iterator i = rootNode.getChildren().values().iterator(); i.hasNext(); )
+        List<String> groups = new ArrayList<String>();
+        for ( GroupTreeNode node : rootNode.getChildren().values() )
         {
-            GroupTreeNode node = (GroupTreeNode) i.next();
-
             while ( node.getChildren().size() == 1 )
             {
-                node = (GroupTreeNode) node.getChildren().values().iterator().next();
+                node = node.getChildren().values().iterator().next();
             }
 
             groups.add( node.getFullName() );
@@ -139,7 +134,7 @@ public class GroupIdFilter
 
         private final String fullName;
 
-        private final Map children = new TreeMap();
+        private final Map<String, GroupTreeNode> children = new TreeMap<String, GroupTreeNode>();
 
         GroupTreeNode()
         {
@@ -163,7 +158,7 @@ public class GroupIdFilter
             return fullName;
         }
 
-        public Map getChildren()
+        public Map<String, GroupTreeNode> getChildren()
         {
             return children;
         }
index d8efa48b1a86e5e87c5c3d854211f7c9ff9d6c1d..4cea469419251bdb4bd0053a0ebc1c78699f1530 100644 (file)
@@ -38,7 +38,7 @@ public interface RepositoryBrowsing
      * 
      * @return the root browsing results.
      */
-    public BrowsingResults getRoot();
+    public BrowsingResults getRoot( String principle, List<String> observableRepositoryIds );
 
     /**
      * Get the {@link BrowsingResults} for the selected groupId.
@@ -46,7 +46,7 @@ public interface RepositoryBrowsing
      * @param groupId the groupId to select.
      * @return the {@link BrowsingResults} for the specified groupId.
      */
-    public BrowsingResults selectGroupId( String groupId );
+    public BrowsingResults selectGroupId( String principle, List<String> observableRepositoryIds, String groupId );
 
     /**
      * Get the {@link BrowsingResults} for the selected groupId & artifactId.
@@ -55,7 +55,8 @@ public interface RepositoryBrowsing
      * @param artifactId the artifactId selected
      * @return the {@link BrowsingResults} for the specified groupId / artifactId combo.
      */
-    public BrowsingResults selectArtifactId( String groupId, String artifactId );
+    public BrowsingResults selectArtifactId( String principle, List<String> observableRepositoryIds, String groupId,
+                                             String artifactId );
 
     /**
      * Get the {@link ArchivaProjectModel} for the selected groupId / artifactId / version combo.
@@ -67,9 +68,10 @@ public interface RepositoryBrowsing
      * @throws ObjectNotFoundException if the artifact object or project object isn't found in the database.
      * @throws ArchivaDatabaseException if there is a fundamental database error.
      */
-    public ArchivaProjectModel selectVersion( String groupId, String artifactId, String version )
+    public ArchivaProjectModel selectVersion( String principle, List<String> observableRepositoryIds, String groupId,
+                                              String artifactId, String version )
         throws ObjectNotFoundException, ArchivaDatabaseException;
-    
+
     /**
      * Get the {@link List} of {@link ArchivaProjectModel} that are used by the provided
      * groupId, artifactId, and version specified.
@@ -80,6 +82,7 @@ public interface RepositoryBrowsing
      * @return the {@link List} of {@link ArchivaProjectModel} objects. (never null, but can be empty)
      * @throws ArchivaDatabaseException if there is a fundamental database error.
      */
-    public List getUsedBy( String groupId, String artifactId, String version )
+    public List<ArchivaProjectModel> getUsedBy( String principle, List<String> observableRepositoryIds, String groupId,
+                                                String artifactId, String version )
         throws ArchivaDatabaseException;
 }
diff --git a/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/SqlBuilder.java b/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/SqlBuilder.java
new file mode 100644 (file)
index 0000000..208475d
--- /dev/null
@@ -0,0 +1,80 @@
+package org.apache.maven.archiva.database.constraints;
+
+/*
+ * 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.
+ */
+
+import org.apache.commons.lang.StringUtils;
+
+import java.util.List;
+
+/**
+ * SqlBuilder - common sql building mechanisms. 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class SqlBuilder
+{
+    /**
+     * Append a sql specific where clause within <code>"()"</code> braces that selects the specific
+     * repository ids provided. 
+     * 
+     * NOTE: This does not append the "WHERE" statement itself.
+     * 
+     * @param sql the sql buffer to append to.
+     * @param fieldId the field id for the repository Id.
+     * @param selectedRepositoryIds the list of repository ids to provide.
+     */
+    public static void appendWhereSelectedRepositories( StringBuffer sql, String fieldId,
+                                                        List<String> selectedRepositoryIds )
+    {
+        if ( fieldId == null )
+        {
+            throw new NullPointerException( "Null field id is not allowed." );
+        }
+
+        if ( StringUtils.isBlank( fieldId ) )
+        {
+            throw new IllegalArgumentException( "Blank field id is not allowed." );
+        }
+
+        if ( selectedRepositoryIds == null )
+        {
+            throw new NullPointerException( "Selected repositories cannot be null." );
+        }
+
+        if ( selectedRepositoryIds.isEmpty() )
+        {
+            throw new IllegalArgumentException( "Selected repositories cannot be null." );
+        }
+
+        sql.append( " (" );
+        boolean multiple = false;
+        for ( String repo : selectedRepositoryIds )
+        {
+            if ( multiple )
+            {
+                sql.append( " || " );
+            }
+            sql.append( " " ).append( fieldId ).append( " == \"" ).append( repo ).append( "\"" );
+            multiple = true;
+        }
+        sql.append( " )" );
+    }
+}
index f5aa438267df95e435963af4fd33ecc41f5244af..47766b94e8692ccc80061109063bb3b76ec21f85 100644 (file)
@@ -22,6 +22,8 @@ package org.apache.maven.archiva.database.constraints;
 import org.apache.maven.archiva.database.Constraint;
 import org.apache.maven.archiva.model.ArchivaArtifactModel;
 
+import java.util.List;
+
 /**
  * Obtain a set of unique ArtifactIds for the specified groupId.
  *
@@ -32,7 +34,24 @@ public class UniqueArtifactIdConstraint
     extends AbstractSimpleConstraint
     implements Constraint
 {
-    private String sql;
+    private StringBuffer sql = new StringBuffer();
+
+    /**
+     * Obtain a set of unique ArtifactIds for the specified groupId.
+     * 
+     * @param groupId the groupId to search for artifactIds within.
+     */
+    public UniqueArtifactIdConstraint( List<String> selectedRepositoryIds, String groupId )
+    {
+        appendSelect( sql );
+        sql.append( " WHERE " );
+        SqlBuilder.appendWhereSelectedRepositories( sql, "repositoryId", selectedRepositoryIds );
+        sql.append( " && " );
+        appendWhereSelectedGroupId( sql );
+        appendGroupBy( sql );
+
+        super.params = new Object[] { groupId };
+    }
 
     /**
      * Obtain a set of unique ArtifactIds for the specified groupId.
@@ -41,13 +60,15 @@ public class UniqueArtifactIdConstraint
      */
     public UniqueArtifactIdConstraint( String groupId )
     {
-        sql = "SELECT artifactId FROM " + ArchivaArtifactModel.class.getName()
-            + " WHERE groupId == selectedGroupId PARAMETERS String selectedGroupId"
-            + " GROUP BY artifactId ORDER BY artifactId ASCENDING";
+        appendSelect( sql );
+        sql.append( " WHERE " );
+        appendWhereSelectedGroupId( sql );
+        appendGroupBy( sql );
 
         super.params = new Object[] { groupId };
     }
 
+    @SuppressWarnings("unchecked")
     public Class getResultClass()
     {
         return String.class;
@@ -55,6 +76,22 @@ public class UniqueArtifactIdConstraint
 
     public String getSelectSql()
     {
-        return sql;
+        return sql.toString();
     }
+
+    private void appendGroupBy( StringBuffer buf )
+    {
+        buf.append( " GROUP BY artifactId ORDER BY artifactId ASCENDING" );
+    }
+
+    private void appendSelect( StringBuffer buf )
+    {
+        buf.append( "SELECT artifactId FROM " ).append( ArchivaArtifactModel.class.getName() );
+    }
+
+    private void appendWhereSelectedGroupId( StringBuffer buf )
+    {
+        buf.append( " groupId == selectedGroupId PARAMETERS String selectedGroupId" );
+    }
+
 }
index f8a77a4877f64bc9029dc857ae069ca5e0c68796..06490c211c846e02cf15382121f4daf3607a087b 100644 (file)
@@ -22,6 +22,8 @@ package org.apache.maven.archiva.database.constraints;
 import org.apache.maven.archiva.database.Constraint;
 import org.apache.maven.archiva.model.ArchivaArtifactModel;
 
+import java.util.List;
+
 /**
  * UniqueGroupIdConstraint 
  *
@@ -32,24 +34,46 @@ public class UniqueGroupIdConstraint
     extends AbstractSimpleConstraint
     implements Constraint
 {
-    private String sql;
+    private StringBuffer sql = new StringBuffer();
 
     public UniqueGroupIdConstraint()
     {
         /* this assumes search for no groupId prefix */
-        sql = "SELECT groupId FROM " + ArchivaArtifactModel.class.getName()
-            + " GROUP BY groupId ORDER BY groupId ASCENDING";
+        appendSelect( sql );
+        appendGroupBy( sql );
+    }
+
+    public UniqueGroupIdConstraint( List<String> selectedRepositories )
+    {
+        appendSelect( sql );
+        sql.append( " WHERE " );
+        SqlBuilder.appendWhereSelectedRepositories( sql, "repositoryId", selectedRepositories );
+        appendGroupBy( sql );
+    }
+
+    public UniqueGroupIdConstraint( List<String> selectedRepositories, String groupIdPrefix )
+    {
+        appendSelect( sql );
+        sql.append( " WHERE " );
+        SqlBuilder.appendWhereSelectedRepositories( sql, "repositoryId", selectedRepositories );
+        sql.append( " && " );
+        appendWhereGroupIdStartsWith( sql );
+        appendGroupBy( sql );
+
+        super.params = new Object[] { groupIdPrefix };
     }
 
     public UniqueGroupIdConstraint( String groupIdPrefix )
     {
-        sql = "SELECT groupId FROM " + ArchivaArtifactModel.class.getName()
-            + " WHERE groupId.startsWith(groupIdPrefix) PARAMETERS String groupIdPrefix"
-            + " GROUP BY groupId ORDER BY groupId ASCENDING";
+        appendSelect( sql );
+        sql.append( " WHERE " );
+        appendWhereGroupIdStartsWith( sql );
+        appendGroupBy( sql );
 
         super.params = new Object[] { groupIdPrefix };
     }
 
+    @SuppressWarnings("unchecked")
     public Class getResultClass()
     {
         return String.class;
@@ -57,6 +81,21 @@ public class UniqueGroupIdConstraint
 
     public String getSelectSql()
     {
-        return sql;
+        return sql.toString();
+    }
+
+    private void appendGroupBy( StringBuffer buf )
+    {
+        buf.append( " GROUP BY groupId ORDER BY groupId ASCENDING" );
+    }
+
+    private void appendSelect( StringBuffer buf )
+    {
+        buf.append( "SELECT groupId FROM " ).append( ArchivaArtifactModel.class.getName() );
+    }
+
+    private void appendWhereGroupIdStartsWith( StringBuffer buf )
+    {
+        buf.append( " groupId.startsWith(groupIdPrefix) PARAMETERS String groupIdPrefix" );
     }
 }
index 6c7a4d73e735a8d97c8011fbd7b10c16ba68196f..c36e34f829688aded3cdaaf2f22007937064b3be 100644 (file)
@@ -23,6 +23,8 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.maven.archiva.database.Constraint;
 import org.apache.maven.archiva.model.ArchivaArtifactModel;
 
+import java.util.List;
+
 /**
  * Obtain the list of version's for specific GroupId and ArtifactId.
  *
@@ -33,7 +35,36 @@ public class UniqueVersionConstraint
     extends AbstractSimpleConstraint
     implements Constraint
 {
-    private String sql;
+    private StringBuffer sql = new StringBuffer();
+
+    /**
+     * Obtain the list of version's for specific GroupId and ArtifactId.
+     * 
+     * @param selectedRepositoryIds the selected repository ids.
+     * @param groupId the selected groupId.
+     * @param artifactId the selected artifactId.
+     */
+    public UniqueVersionConstraint( List<String> selectedRepositoryIds, String groupId, String artifactId )
+    {
+        if ( StringUtils.isBlank( groupId ) )
+        {
+            throw new IllegalArgumentException( "A blank groupId is not allowed." );
+        }
+
+        if ( StringUtils.isBlank( artifactId ) )
+        {
+            throw new IllegalArgumentException( "A blank artifactId is not allowed." );
+        }
+
+        appendSelect( sql );
+        sql.append( " WHERE " );
+        SqlBuilder.appendWhereSelectedRepositories( sql, "repositoryId", selectedRepositoryIds );
+        sql.append( " && " );
+        appendWhereSelectedGroupIdArtifactId( sql );
+        appendGroupBy( sql );
+
+        super.params = new Object[] { groupId, artifactId };
+    }
 
     /**
      * Obtain the list of version's for specific GroupId and ArtifactId.
@@ -53,14 +84,15 @@ public class UniqueVersionConstraint
             throw new IllegalArgumentException( "A blank artifactId is not allowed." );
         }
 
-        sql = "SELECT version FROM " + ArchivaArtifactModel.class.getName()
-            + " WHERE groupId == selectedGroupId && artifactId == selectedArtifactId"
-            + " PARAMETERS String selectedGroupId, String selectedArtifactId"
-            + " GROUP BY version ORDER BY version ASCENDING";
+        appendSelect( sql );
+        sql.append( " WHERE " );
+        appendWhereSelectedGroupIdArtifactId( sql );
+        appendGroupBy( sql );
 
         super.params = new Object[] { groupId, artifactId };
     }
 
+    @SuppressWarnings("unchecked")
     public Class getResultClass()
     {
         return String.class;
@@ -68,6 +100,22 @@ public class UniqueVersionConstraint
 
     public String getSelectSql()
     {
-        return sql;
+        return sql.toString();
+    }
+
+    private void appendGroupBy( StringBuffer buf )
+    {
+        buf.append( " GROUP BY version ORDER BY version ASCENDING" );
+    }
+
+    private void appendSelect( StringBuffer buf )
+    {
+        buf.append( "SELECT version FROM " ).append( ArchivaArtifactModel.class.getName() );
+    }
+
+    private void appendWhereSelectedGroupIdArtifactId( StringBuffer buf )
+    {
+        buf.append( " groupId == selectedGroupId && artifactId == selectedArtifactId" );
+        buf.append( " PARAMETERS String selectedGroupId, String selectedArtifactId" );
     }
 }
index 6da3a4120e793e7c52eae06a9a65069fc7aecfc2..f643bdfd2e53cc4d523f824dd09b917a0e012a14 100644 (file)
@@ -74,7 +74,7 @@ public class JdoProjectModelDAO
         return (ArchivaProjectModel) jdo.getObjectById( ArchivaProjectModel.class, key, null );
     }
 
-    public List queryProjectModels( Constraint constraint )
+    public List<ArchivaProjectModel> queryProjectModels( Constraint constraint )
         throws ObjectNotFoundException, ArchivaDatabaseException
     {
         return jdo.queryObjects( ArchivaProjectModel.class, constraint );
index c1c7ac280c52435f36b8de4f78cdd394ac5d81fe..8f2e6bf27d8834d1c7b6b91cbf5dae0ee353e88e 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.maven.archiva.database.ArchivaDAO;
 import org.apache.maven.archiva.database.ArtifactDAO;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
@@ -36,13 +37,24 @@ import java.util.List;
 public class RepositoryBrowsingTest
     extends AbstractArchivaDatabaseTestCase
 {
+    private static final List<String> GUEST_REPO_IDS;
+
+    private static final String USER_GUEST = "guest";
+    
+    static
+    {
+        GUEST_REPO_IDS = new ArrayList<String>();
+        GUEST_REPO_IDS.add( "central" );
+        GUEST_REPO_IDS.add( "snapshots" );
+    }
+    
     private ArtifactDAO artifactDao;
 
     public ArchivaArtifact createArtifact( String groupId, String artifactId, String version )
     {
         ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, "", "jar" );
         artifact.getModel().setLastModified( new Date() ); // mandatory field.
-        artifact.getModel().setRepositoryId( "testable_repo" );
+        artifact.getModel().setRepositoryId( "central" );
         return artifact;
     }
 
@@ -97,7 +109,7 @@ public class RepositoryBrowsingTest
         saveTestData();
 
         RepositoryBrowsing browser = lookupBrowser();
-        BrowsingResults results = browser.selectGroupId( "org.apache.maven.test" );
+        BrowsingResults results = browser.selectGroupId( USER_GUEST, GUEST_REPO_IDS, "org.apache.maven.test" );
         assertNotNull( "Browsing Results should not be null.", results );
 
         String expectedSubGroupIds[] = new String[] { "org.apache.maven.test.foo" };
@@ -110,7 +122,7 @@ public class RepositoryBrowsingTest
         saveTestData();
 
         RepositoryBrowsing browser = lookupBrowser();
-        BrowsingResults results = browser.getRoot();
+        BrowsingResults results = browser.getRoot( USER_GUEST, GUEST_REPO_IDS );
         assertNotNull( "Browsing Results should not be null.", results );
 
         String expectedRootGroupIds[] = new String[] { "commons-lang", "org" };
index 4de63506f4b21a5893754e91e08211b5bc61beb2..b32ea06cf1c5be2c815f2682cf885f53a1bb957a 100644 (file)
@@ -26,6 +26,7 @@ import org.apache.maven.archiva.database.ArtifactDAO;
 import org.apache.maven.archiva.database.SimpleConstraint;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.Iterator;
@@ -42,91 +43,268 @@ public class UniqueGroupIdConstraintTest
 {
     private ArtifactDAO artifactDao;
 
-    protected void setUp()
+    public void testConstraintGroupIdParamCommonsLang()
         throws Exception
     {
-        super.setUp();
+        setupArtifacts();
 
-        ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
-        artifactDao = dao.getArtifactDAO();
+        assertConstraint( new String[] { "commons-lang" }, new UniqueGroupIdConstraint( "commons-lang" ) );
     }
 
-    public ArchivaArtifact createArtifact( String groupId, String artifactId, String version )
+    public void testConstraintGroupIdParamNoRepos()
+        throws Exception
     {
-        ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, "", "jar" );
-        artifact.getModel().setLastModified( new Date() ); // mandatory field.
-        artifact.getModel().setRepositoryId( "testable_repo" );
-        return artifact;
+        try
+        {
+            List<String> selectedRepos = new ArrayList<String>();
+            new UniqueGroupIdConstraint( selectedRepos, "org" );
+            fail( "Should have thrown an IllegalArgumentException due to lack of specified repos." );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            // expected path.
+        }
     }
 
-    public void testConstraint()
+    public void testConstraintGroupIdParamNullRepos()
         throws Exception
     {
-        ArchivaArtifact artifact;
+        try
+        {
+            new UniqueGroupIdConstraint( (List<String>) null, "org" );
+            fail( "Should have thrown an NullPointerException due to lack of specified repos." );
+        }
+        catch ( NullPointerException e )
+        {
+            // expected path.
+        }
+    }
 
-        // Setup artifacts in fresh DB.
-        artifact = createArtifact( "commons-lang", "commons-lang", "2.0" );
-        artifactDao.saveArtifact( artifact );
+    public void testConstraintGroupIdParamOrg()
+        throws Exception
+    {
+        setupArtifacts();
 
-        artifact = createArtifact( "commons-lang", "commons-lang", "2.1" );
-        artifactDao.saveArtifact( artifact );
+        assertConstraint( new String[] {
+            "org.apache.maven.test",
+            "org.apache.maven.test.foo",
+            "org.apache.maven.shared",
+            "org.apache.archiva",
+            "org.codehaus.modello",
+            "org.codehaus.mojo" }, new UniqueGroupIdConstraint( "org" ) );
+    }
 
-        artifact = createArtifact( "org.apache.maven.test", "test-one", "1.2" );
-        artifactDao.saveArtifact( artifact );
+    public void testConstraintGroupIdParamOrgApache()
+        throws Exception
+    {
+        setupArtifacts();
 
-        artifact = createArtifact( "org.apache.maven.test.foo", "test-two", "1.0" );
-        artifactDao.saveArtifact( artifact );
+        assertConstraint( new String[] {
+            "org.apache.maven.test",
+            "org.apache.maven.test.foo",
+            "org.apache.maven.shared",
+            "org.apache.archiva" }, new UniqueGroupIdConstraint( "org.apache" ) );
+    }
 
-        artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.0" );
-        artifactDao.saveArtifact( artifact );
+    public void testConstraintGroupIdParamOrgApacheMaven()
+        throws Exception
+    {
+        setupArtifacts();
 
-        artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1" );
-        artifactDao.saveArtifact( artifact );
+        assertConstraint( new String[] {
+            "org.apache.maven.test",
+            "org.apache.maven.test.foo",
+            "org.apache.maven.shared" }, new UniqueGroupIdConstraint( "org.apache.maven" ) );
+    }
 
-        artifact = createArtifact( "org.codehaus.modello", "test-two", "3.0" );
-        artifactDao.saveArtifact( artifact );
+    public void testConstraintGroupIdParamOrgApacheSnapshotsOnly()
+        throws Exception
+    {
+        setupArtifacts();
+
+        List<String> observableRepositories = new ArrayList<String>();
+        observableRepositories.add( "snapshots" );
+
+        assertConstraint( new String[] { "org.apache.archiva" }, new UniqueGroupIdConstraint( observableRepositories,
+                                                                                              "org.apache" ) );
+    }
+
+    public void testConstraintGroupIdParamOrgSnapshotsOnly()
+        throws Exception
+    {
+        setupArtifacts();
+
+        List<String> observableRepositories = new ArrayList<String>();
+        observableRepositories.add( "snapshots" );
+
+        assertConstraint( new String[] { "org.apache.archiva", "org.codehaus.modello", "org.codehaus.mojo" },
+                          new UniqueGroupIdConstraint( observableRepositories, "org" ) );
+    }
+
+    public void testConstraintNoGroupIdParam()
+        throws Exception
+    {
+        setupArtifacts();
 
         assertConstraint( new String[] {
             "commons-lang",
             "org.apache.maven.test",
             "org.apache.maven.test.foo",
             "org.apache.maven.shared",
-            "org.codehaus.modello" }, new UniqueGroupIdConstraint() );
-        assertConstraint( new String[] { "commons-lang" }, new UniqueGroupIdConstraint( "commons-lang" ) );
-        assertConstraint( new String[] {
-            "org.apache.maven.test",
-            "org.apache.maven.test.foo",
-            "org.apache.maven.shared" }, new UniqueGroupIdConstraint( "org.apache.maven" ) );
+            "org.codehaus.modello",
+            "org.codehaus.mojo",
+            "org.apache.archiva" }, new UniqueGroupIdConstraint() );
+    }
+
+    public void testConstraintNoGroupIdParamCentralAndSnapshots()
+        throws Exception
+    {
+        setupArtifacts();
+
+        List<String> observableRepositories = new ArrayList<String>();
+        observableRepositories.add( "central" );
+        observableRepositories.add( "snapshots" );
+
         assertConstraint( new String[] {
+            "commons-lang",
             "org.apache.maven.test",
             "org.apache.maven.test.foo",
-            "org.apache.maven.shared" }, new UniqueGroupIdConstraint( "org.apache" ) );
+            "org.apache.maven.shared",
+            "org.codehaus.modello",
+            "org.codehaus.mojo",
+            "org.apache.archiva" }, new UniqueGroupIdConstraint( observableRepositories ) );
+    }
+
+    public void testConstraintNoGroupIdParamCentralOnly()
+        throws Exception
+    {
+        setupArtifacts();
+
+        List<String> observableRepositories = new ArrayList<String>();
+        observableRepositories.add( "central" );
+
         assertConstraint( new String[] {
+            "commons-lang",
             "org.apache.maven.test",
             "org.apache.maven.test.foo",
             "org.apache.maven.shared",
-            "org.codehaus.modello" }, new UniqueGroupIdConstraint( "org" ) );
+            "org.codehaus.modello" }, new UniqueGroupIdConstraint( observableRepositories ) );
+    }
+
+    public void testConstraintNoGroupIdParamNoRepos()
+        throws Exception
+    {
+        try
+        {
+            List<String> selectedRepos = new ArrayList<String>();
+            new UniqueGroupIdConstraint( selectedRepos );
+            fail( "Should have thrown an IllegalArgumentException due to lack of specified repos." );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            // expected path.
+        }
+    }
+
+    public void testConstraintNoGroupIdParamNullRepos()
+        throws Exception
+    {
+        try
+        {
+            new UniqueGroupIdConstraint( (List<String>) null );
+            fail( "Should have thrown an NullPointerException due to lack of specified repos." );
+        }
+        catch ( NullPointerException e )
+        {
+            // expected path.
+        }
+    }
+
+    public void testConstraintNoGroupIdParamSnapshotsOnly()
+        throws Exception
+    {
+        setupArtifacts();
+
+        List<String> observableRepositories = new ArrayList<String>();
+        observableRepositories.add( "snapshots" );
+
+        assertConstraint( new String[] { "org.codehaus.modello", "org.codehaus.mojo", "org.apache.archiva" },
+                          new UniqueGroupIdConstraint( observableRepositories ) );
     }
 
     private void assertConstraint( String[] expectedGroupIds, SimpleConstraint constraint )
         throws Exception
     {
         String prefix = "Unique Group IDs: ";
-        
-        List results = dao.query( constraint );
+
+        List<String> results = dao.query( constraint );
         assertNotNull( prefix + "Not Null", results );
         assertEquals( prefix + "Results.size", expectedGroupIds.length, results.size() );
 
-        List groupIdList = Arrays.asList( expectedGroupIds );
+        List<String> groupIdList = Arrays.asList( expectedGroupIds );
 
-        Iterator it = results.iterator();
+        Iterator<String> it = results.iterator();
         while ( it.hasNext() )
         {
             String actualGroupId = (String) it.next();
             assertTrue( prefix + "groupId result should not be blank.", StringUtils.isNotBlank( actualGroupId ) );
-            assertTrue( prefix + " groupId result <" + actualGroupId + "> exists in expected GroupIds.",
-                        groupIdList.contains( actualGroupId ) );
+            assertTrue( prefix + " groupId result <" + actualGroupId + "> exists in expected GroupIds.", groupIdList
+                .contains( actualGroupId ) );
         }
     }
 
+    private ArchivaArtifact createArtifact( String repoId, String groupId, String artifactId, String version )
+    {
+        ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, "", "jar" );
+        artifact.getModel().setLastModified( new Date() ); // mandatory field.
+        artifact.getModel().setRepositoryId( repoId );
+        return artifact;
+    }
+
+    private void setupArtifacts()
+        throws Exception
+    {
+        ArchivaArtifact artifact;
+
+        // Setup artifacts in fresh DB.
+        artifact = createArtifact( "central", "commons-lang", "commons-lang", "2.0" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "central", "commons-lang", "commons-lang", "2.1" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "central", "org.apache.maven.test", "test-one", "1.2" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "central", "org.apache.maven.test.foo", "test-two", "1.0" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "central", "org.apache.maven.shared", "test-two", "2.0" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "central", "org.apache.maven.shared", "test-two", "2.1" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "central", "org.codehaus.modello", "test-two", "3.0" );
+        artifactDao.saveArtifact( artifact );
+
+        // Snapshots repository artifacts
+        artifact = createArtifact( "snapshots", "org.codehaus.modello", "test-three", "1.0-SNAPSHOT" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "snapshots", "org.codehaus.mojo", "testable-maven-plugin", "2.1-SNAPSHOT" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "snapshots", "org.apache.archiva", "testable", "1.1-alpha-1-20070822.033400-43" );
+        artifactDao.saveArtifact( artifact );
+    }
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
+        artifactDao = dao.getArtifactDAO();
+    }
 }
index 176b7192b909a061b9c58ed82aa0a1bc02e4cb5e..c30a624f119b77e933de6b69099f25896259dbde 100644 (file)
@@ -26,9 +26,9 @@ import org.apache.maven.archiva.database.ArtifactDAO;
 import org.apache.maven.archiva.database.SimpleConstraint;
 import org.apache.maven.archiva.model.ArchivaArtifact;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -42,87 +42,152 @@ public class UniqueVersionConstraintTest
 {
     private ArtifactDAO artifactDao;
 
-    protected void setUp()
+    public void testConstraintGroupIdArtifactIdCommonsLang()
         throws Exception
     {
-        super.setUp();
+        setupArtifacts();
 
-        ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
-        artifactDao = dao.getArtifactDAO();
+        assertConstraint( new String[] { "2.0", "2.1" }, new UniqueVersionConstraint( "commons-lang", "commons-lang" ) );
+    }
+
+    public void testConstraintGroupIdArtifactIdInvalid()
+        throws Exception
+    {
+        setupArtifacts();
+
+        assertConstraint( new String[] {}, new UniqueVersionConstraint( "org.apache", "invalid" ) );
+        assertConstraint( new String[] {}, new UniqueVersionConstraint( "org.apache.test", "invalid" ) );
+        assertConstraint( new String[] {}, new UniqueVersionConstraint( "invalid", "test-two" ) );
+    }
+
+    public void testConstraintGroupIdArtifactIdMavenSharedTestTwo()
+        throws Exception
+    {
+        setupArtifacts();
+
+        assertConstraint( new String[] { "2.0", "2.1-SNAPSHOT", "2.1.1", "2.1-alpha-1" },
+                          new UniqueVersionConstraint( "org.apache.maven.shared", "test-two" ) );
+    }
+
+    public void testConstraintGroupIdArtifactIdMavenSharedTestTwoCentralOnly()
+        throws Exception
+    {
+        setupArtifacts();
+
+        List<String> observableRepositories = new ArrayList<String>();
+        observableRepositories.add( "central" );
+
+        assertConstraint( new String[] { "2.0", "2.1.1", "2.1-alpha-1" },
+                          new UniqueVersionConstraint( observableRepositories, "org.apache.maven.shared", "test-two" ) );
+    }
+
+    public void testConstraintGroupIdArtifactIdMavenSharedTestTwoSnapshotsOnly()
+        throws Exception
+    {
+        setupArtifacts();
+
+        List<String> observableRepositories = new ArrayList<String>();
+        observableRepositories.add( "snapshots" );
+
+        assertConstraint( new String[] { "2.1-SNAPSHOT" }, 
+                          new UniqueVersionConstraint( observableRepositories, "org.apache.maven.shared", "test-two" ) );
+    }
+
+    public void testConstraintGroupIdArtifactIdMavenTestOne()
+        throws Exception
+    {
+        setupArtifacts();
+
+        assertConstraint( new String[] { "1.2" }, new UniqueVersionConstraint( "org.apache.maven.test", "test-one" ) );
     }
 
-    public ArchivaArtifact createArtifact( String groupId, String artifactId, String version )
+    public void testConstraintGroupIdArtifactIdModelloLong()
+        throws Exception
+    {
+        setupArtifacts();
+
+        assertConstraint( new String[] { "3.0" }, new UniqueVersionConstraint( "org.codehaus.modello", "modellong" ) );
+    }
+
+    private void assertConstraint( String[] versions, SimpleConstraint constraint )
+    {
+        String prefix = "Unique Versions: ";
+
+        List<String> results = dao.query( constraint );
+        assertNotNull( prefix + "Not Null", results );
+        assertEquals( prefix + "Results.size", versions.length, results.size() );
+
+        List<String> expectedVersions = Arrays.asList( versions );
+
+        for ( String actualVersion : results )
+        {
+            assertTrue( prefix + "version result should not be blank.", StringUtils.isNotBlank( actualVersion ) );
+            assertTrue( prefix + "version result <" + actualVersion + "> exists in expected versions.",
+                        expectedVersions.contains( actualVersion ) );
+        }
+    }
+
+    private ArchivaArtifact createArtifact( String repoId, String groupId, String artifactId, String version )
     {
         ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, "", "jar" );
         artifact.getModel().setLastModified( new Date() ); // mandatory field.
-        artifact.getModel().setRepositoryId( "testable_repo" );
+        artifact.getModel().setRepositoryId( repoId );
         return artifact;
     }
 
-    public void testConstraint()
+    private void setupArtifacts()
         throws Exception
     {
         ArchivaArtifact artifact;
 
         // Setup artifacts in fresh DB.
-        artifact = createArtifact( "commons-lang", "commons-lang", "2.0" );
+        artifact = createArtifact( "central", "commons-lang", "commons-lang", "2.0" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "commons-lang", "commons-lang", "2.1" );
+        artifact = createArtifact( "central", "commons-lang", "commons-lang", "2.1" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "org.apache.maven.test", "test-one", "1.2" );
+        artifact = createArtifact( "central", "org.apache.maven.test", "test-one", "1.2" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "org.apache.maven.test.foo", "test-two", "1.0" );
+        artifact = createArtifact( "central", "org.apache.maven.test.foo", "test-two", "1.0" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.0" );
+        artifact = createArtifact( "central", "org.apache.maven.shared", "test-two", "2.0" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-SNAPSHOT" );
+        artifact = createArtifact( "central", "org.apache.maven.shared", "test-two", "2.1.1" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1.1" );
+        artifact = createArtifact( "central", "org.apache.maven.shared", "test-two", "2.1-alpha-1" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-alpha-1" );
+        artifact = createArtifact( "central", "org.apache.maven.shared", "test-bar", "2.1" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "org.apache.maven.shared", "test-bar", "2.1" );
+        artifact = createArtifact( "central", "org.codehaus.modello", "modellong", "3.0" );
         artifactDao.saveArtifact( artifact );
 
-        artifact = createArtifact( "org.codehaus.modello", "modellong", "3.0" );
+        // Snapshots repository artifacts
+        artifact = createArtifact( "snapshots", "org.apache.maven.shared", "test-two", "2.1-SNAPSHOT" );
         artifactDao.saveArtifact( artifact );
 
-        assertConstraint( new String[] {}, new UniqueVersionConstraint( "org.apache", "invalid" ) );
-        assertConstraint( new String[] {}, new UniqueVersionConstraint( "org.apache.test", "invalid" ) );
-        assertConstraint( new String[] {}, new UniqueVersionConstraint( "invalid", "test-two" ) );
+        artifact = createArtifact( "snapshots", "org.codehaus.modello", "test-three", "1.0-SNAPSHOT" );
+        artifactDao.saveArtifact( artifact );
 
-        assertConstraint( new String[] { "2.0", "2.1" }, new UniqueVersionConstraint( "commons-lang", "commons-lang" ) );
-        assertConstraint( new String[] { "1.2" }, new UniqueVersionConstraint( "org.apache.maven.test", "test-one" ) );
-        assertConstraint( new String[] { "2.0", "2.1-SNAPSHOT", "2.1.1", "2.1-alpha-1" },
-                          new UniqueVersionConstraint( "org.apache.maven.shared", "test-two" ) );
-        assertConstraint( new String[] { "3.0" }, new UniqueVersionConstraint( "org.codehaus.modello", "modellong" ) );
+        artifact = createArtifact( "snapshots", "org.codehaus.mojo", "testable-maven-plugin", "2.1-SNAPSHOT" );
+        artifactDao.saveArtifact( artifact );
+
+        artifact = createArtifact( "snapshots", "org.apache.archiva", "testable", "1.1-alpha-1-20070822.033400-43" );
+        artifactDao.saveArtifact( artifact );
     }
 
-    private void assertConstraint( String[] versions, SimpleConstraint constraint )
+    protected void setUp()
+        throws Exception
     {
-        String prefix = "Unique Versions: ";
-
-        List results = dao.query( constraint );
-        assertNotNull( prefix + "Not Null", results );
-        assertEquals( prefix + "Results.size", versions.length, results.size() );
-
-        List expectedVersions = Arrays.asList( versions );
+        super.setUp();
 
-        Iterator it = results.iterator();
-        while ( it.hasNext() )
-        {
-            String actualVersion = (String) it.next();
-            assertTrue( prefix + "version result should not be blank.", StringUtils.isNotBlank( actualVersion ) );
-            assertTrue( prefix + "version result <" + actualVersion + "> exists in expected versions.",
-                        expectedVersions.contains( actualVersion ) );
-        }
+        ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
+        artifactDao = dao.getArtifactDAO();
     }
 }
index 5837eee9f7ab7b337bd8088ffd3bd4da1ada7140..5ba0428be96388135606bb02f02affbbeb219b64 100644 (file)
   <artifactId>archiva-security</artifactId>
   <name>Archiva Web :: Security Configuration</name>
   <dependencies>
+    <dependency>
+      <groupId>org.apache.maven.archiva</groupId>
+      <artifactId>archiva-configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus.redback</groupId>
+      <artifactId>redback-system</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus.redback</groupId>
+      <artifactId>redback-rbac-model</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.codehaus.plexus.redback</groupId>
       <artifactId>redback-rbac-role-manager</artifactId>
     </dependency>
+    <!-- Test Scoped -->
     <dependency>
       <groupId>org.codehaus.plexus.redback</groupId>
-      <artifactId>redback-rbac-memory</artifactId>
+      <artifactId>redback-authorization-rbac</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.codehaus.plexus.redback</groupId>
-      <artifactId>redback-xwork-integration</artifactId>
+      <artifactId>redback-keys-memory</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.derby</groupId>
-      <artifactId>derby</artifactId>
+      <groupId>org.codehaus.plexus.redback</groupId>
+      <artifactId>redback-users-memory</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus.redback</groupId>
+      <artifactId>redback-rbac-memory</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/AccessDeniedException.java b/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/AccessDeniedException.java
new file mode 100644 (file)
index 0000000..2c3ea5e
--- /dev/null
@@ -0,0 +1,40 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+/**
+ * AccessDeniedException 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class AccessDeniedException
+    extends ArchivaSecurityException
+{
+    public AccessDeniedException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public AccessDeniedException( String message )
+    {
+        super( message );
+    }
+}
index 0be90a7b00036e59ce7345e260926ee768fd9563..78745ec3561f102a5eaa36c885399f15b3120506 100644 (file)
@@ -35,6 +35,10 @@ public class ArchivaRoleConstants
     public static final String REGISTERED_USER_ROLE = "Registered User";
 
     public static final String GUEST_ROLE = "Guest";
+    
+    // principals
+    
+    public static final String PRINCIPAL_GUEST = "guest";
 
     // dynamic role prefixes
     public static final String REPOSITORY_MANAGER_ROLE_PREFIX = "Repository Manager";
@@ -68,4 +72,15 @@ public class ArchivaRoleConstants
     public static final String TEMPLATE_REPOSITORY_MANAGER = "archiva-repository-manager";
     
     public static final String TEMPLATE_REPOSITORY_OBSERVER = "archiva-repository-observer";
+    
+    public static final String TEMPLATE_GLOBAL_REPOSITORY_OBSERVER = "archiva-global-repository-observer"; 
+    
+    public static final String TEMPLATE_SYSTEM_ADMIN = "archiva-system-administrator";
+    
+    public static final String TEMPLATE_GUEST = "archiva-guest";
+    
+    public static String toRepositoryObserverRoleName( String repoId )
+    {
+        return REPOSITORY_OBSERVER_ROLE_PREFIX + " - " + repoId;
+    }
 }
diff --git a/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaSecurityException.java b/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaSecurityException.java
new file mode 100644 (file)
index 0000000..47973fc
--- /dev/null
@@ -0,0 +1,42 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.archiva.common.ArchivaException;
+
+/**
+ * ArchivaSecurityException 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class ArchivaSecurityException
+    extends ArchivaException
+{
+    public ArchivaSecurityException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public ArchivaSecurityException( String message )
+    {
+        super( message );
+    }
+}
diff --git a/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaStandardRolesCheck.java b/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaStandardRolesCheck.java
new file mode 100644 (file)
index 0000000..434c2f6
--- /dev/null
@@ -0,0 +1,103 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.redback.rbac.RBACManager;
+import org.codehaus.plexus.redback.system.check.EnvironmentCheck;
+
+import java.util.List;
+
+/**
+ * ArchivaStandardRolesCheck tests for the existance of expected / standard roles and permissions. 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ * 
+ * @plexus.component role="org.codehaus.plexus.redback.system.check.EnvironmentCheck"
+ *                   role-hint="required-roles"
+ */
+public class ArchivaStandardRolesCheck
+    extends AbstractLogEnabled
+    implements EnvironmentCheck
+{
+    /**
+     * @plexus.requirement role-hint="cached"
+     */
+    private RBACManager rbacManager;
+
+    /**
+     * boolean detailing if this environment check has been executed
+     */
+    private boolean checked = false;
+
+    @SuppressWarnings("unchecked")
+    public void validateEnvironment( List violations )
+    {
+        if ( !checked )
+        {
+            String expectedRoles[] = new String[] {
+                ArchivaRoleConstants.SYSTEM_ADMINISTRATOR_ROLE,
+                ArchivaRoleConstants.GLOBAL_REPOSITORY_MANAGER_ROLE,
+                ArchivaRoleConstants.GLOBAL_REPOSITORY_OBSERVER_ROLE,
+                ArchivaRoleConstants.GUEST_ROLE,
+                ArchivaRoleConstants.REGISTERED_USER_ROLE,
+                ArchivaRoleConstants.USER_ADMINISTRATOR_ROLE };
+
+            getLogger().info( "Checking the existance of required roles." );
+
+            for ( String roleName : expectedRoles )
+            {
+                if ( !rbacManager.roleExists( roleName ) )
+                {
+                    violations.add( "Unable to validate the existances of the '" + roleName + "' role." );
+                }
+            }
+
+            String expectedOperations[] = new String[] {
+                ArchivaRoleConstants.OPERATION_MANAGE_USERS,
+                ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION,
+                ArchivaRoleConstants.OPERATION_REGENERATE_INDEX,
+                ArchivaRoleConstants.OPERATION_RUN_INDEXER,
+                ArchivaRoleConstants.OPERATION_ACCESS_REPORT,
+                ArchivaRoleConstants.OPERATION_ADD_REPOSITORY,
+                ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY,
+                ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
+                ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY,
+                ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
+                ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
+                "archiva-guest" };
+
+            getLogger().info( "Checking the existance of required operations." );
+
+            for ( String operation : expectedOperations )
+            {
+                if ( !rbacManager.operationExists( operation ) )
+                {
+                    violations.add( "Unable to validate the existances of the '" + operation + "' operation." );
+                }
+            }
+
+            checked = true;
+        }
+
+    }
+
+}
diff --git a/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaUser.java b/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaUser.java
new file mode 100644 (file)
index 0000000..bdf70da
--- /dev/null
@@ -0,0 +1,36 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+/**
+ * ArchivaUser- interface to access the active principal. 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface ArchivaUser
+{
+    /**
+     * Get the active principal from the security system.
+     * 
+     * @return the active principal. (if not authenticated, the guest principal is returned)
+     */
+    public String getActivePrincipal();
+}
diff --git a/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/DefaultUserRepositories.java b/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/DefaultUserRepositories.java
new file mode 100644 (file)
index 0000000..88b740b
--- /dev/null
@@ -0,0 +1,135 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.codehaus.plexus.redback.authentication.AuthenticationResult;
+import org.codehaus.plexus.redback.authorization.AuthorizationException;
+import org.codehaus.plexus.redback.rbac.RBACManager;
+import org.codehaus.plexus.redback.role.RoleManager;
+import org.codehaus.plexus.redback.role.RoleManagerException;
+import org.codehaus.plexus.redback.system.DefaultSecuritySession;
+import org.codehaus.plexus.redback.system.SecuritySession;
+import org.codehaus.plexus.redback.system.SecuritySystem;
+import org.codehaus.plexus.redback.users.User;
+import org.codehaus.plexus.redback.users.UserNotFoundException;
+
+/**
+ * DefaultUserRepositories 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ * 
+ * @plexus.component role="org.apache.maven.archiva.security.UserRepositories"
+ *                   role-hint="default"
+ */
+public class DefaultUserRepositories
+    implements UserRepositories
+{
+    /**
+     * @plexus.requirement
+     */
+    private SecuritySystem securitySystem;
+
+    /**
+     * @plexus.requirement role-hint="cached"
+     */
+    private RBACManager rbacManager;
+
+    /**
+     * @plexus.requirement role-hint="default"
+     */
+    private RoleManager roleManager;
+    
+    /**
+     * @plexus.requirement
+     */
+    private ArchivaConfiguration archivaConfiguration;
+    
+    public List<String> getObservableRepositoryIds( String principal )
+        throws PrincipalNotFoundException, AccessDeniedException, ArchivaSecurityException
+    {
+
+        try
+        {
+            User user = securitySystem.getUserManager().findUser( principal );
+
+            if ( user.isLocked() )
+            {
+                throw new AccessDeniedException( "User " + principal + "(" + user.getFullName() + ") is locked." );
+            }
+            
+            AuthenticationResult authn = new AuthenticationResult( true, principal, null );
+            SecuritySession securitySession = new DefaultSecuritySession( authn, user );
+            
+            List<String> repoIds = new ArrayList<String>();
+
+            List<ManagedRepositoryConfiguration> repos = archivaConfiguration.getConfiguration().getManagedRepositories();
+            
+            for ( ManagedRepositoryConfiguration repo : repos )
+            {
+                try
+                {
+                    String repoId = repo.getId();
+                    if ( securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS, repoId ) )
+                    {
+                        repoIds.add( repoId );
+                    }
+                }
+                catch ( AuthorizationException e )
+                {
+                    // swallow.
+                }
+            }
+            
+            return repoIds;
+        }
+        catch ( UserNotFoundException e )
+        {
+            throw new PrincipalNotFoundException( "Unable to find principal " + principal + "" );
+        }
+    }
+
+    public void createMissingRepositoryRoles( String repoId )
+        throws ArchivaSecurityException
+    {
+        try
+        {
+            if ( !roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId ) )
+            {
+                roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId );
+            }
+
+            if ( !roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId ) )
+            {
+                roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId );
+            }
+        }
+        catch ( RoleManagerException e )
+        {
+            throw new ArchivaSecurityException( "Unable to create roles for configured repositories: " + e.getMessage(),
+                                                e );
+        }
+    }
+}
diff --git a/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/PrincipalNotFoundException.java b/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/PrincipalNotFoundException.java
new file mode 100644 (file)
index 0000000..1962044
--- /dev/null
@@ -0,0 +1,40 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+/**
+ * PrincipalNotFoundException 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class PrincipalNotFoundException
+    extends ArchivaSecurityException
+{
+    public PrincipalNotFoundException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public PrincipalNotFoundException( String message )
+    {
+        super( message );
+    }
+}
diff --git a/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/SecurityStartup.java b/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/SecurityStartup.java
new file mode 100644 (file)
index 0000000..8a6c51c
--- /dev/null
@@ -0,0 +1,206 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.maven.archiva.common.ArchivaException;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.ConfigurationNames;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.redback.rbac.RBACManager;
+import org.codehaus.plexus.redback.rbac.RbacManagerException;
+import org.codehaus.plexus.redback.rbac.UserAssignment;
+import org.codehaus.plexus.redback.system.check.EnvironmentCheck;
+import org.codehaus.plexus.registry.Registry;
+import org.codehaus.plexus.registry.RegistryListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * SecurityStartup 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ * 
+ * @plexus.component role="org.apache.maven.archiva.security.SecurityStartup"
+ */
+public class SecurityStartup
+    extends AbstractLogEnabled
+    implements RegistryListener
+{
+    /**
+     * @plexus.requirement
+     */
+    private UserRepositories userRepos;
+
+    /**
+     * @plexus.requirement role-hint="cached"
+     */
+    private RBACManager rbacManager;
+
+    /**
+     * @plexus.requirement role="org.codehaus.plexus.redback.system.check.EnvironmentCheck"
+     */
+    private Map<String, EnvironmentCheck> checkers;
+
+    /**
+     * @plexus.requirement
+     */
+    private ArchivaConfiguration archivaConfiguration;
+
+    public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
+    {
+        if ( ConfigurationNames.isManagedRepositories( propertyName ) )
+        {
+            createMissingManagedRepositoryRoles( archivaConfiguration.getConfiguration().getManagedRepositories() );
+        }
+    }
+
+    public void assignRepositoryObserverToGuestUser( List<ManagedRepositoryConfiguration> repos )
+    {
+        for ( ManagedRepositoryConfiguration repoConfig : repos )
+        {
+            String repoId = repoConfig.getId();
+
+            // TODO: Use the Redback / UserConfiguration..getString( "redback.default.guest" ) to get the right name.
+            String principal = "guest";
+
+            try
+            {
+                UserAssignment ua;
+
+                if ( rbacManager.userAssignmentExists( principal ) )
+                {
+                    ua = rbacManager.getUserAssignment( principal );
+                }
+                else
+                {
+                    ua = rbacManager.createUserAssignment( principal );
+                }
+
+                ua.addRoleName( ArchivaRoleConstants.toRepositoryObserverRoleName( repoId ) );
+                rbacManager.saveUserAssignment( ua );
+            }
+            catch ( RbacManagerException e )
+            {
+                getLogger().warn(
+                                  "Unable to add role [" + ArchivaRoleConstants.toRepositoryObserverRoleName( repoId )
+                                      + "] to " + principal + " user.", e );
+            }
+        }
+    }
+
+    public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
+    {
+        /* do nothing */
+    }
+
+    public void createMissingManagedRepositoryRoles( List<ManagedRepositoryConfiguration> repos )
+    {
+        // NOTE: Remote Repositories do not have roles or security placed around them.
+
+        for ( ManagedRepositoryConfiguration repoConfig : repos )
+        {
+            // manage roles for repositories
+            try
+            {
+                userRepos.createMissingRepositoryRoles( repoConfig.getId() );
+            }
+            catch ( ArchivaSecurityException e )
+            {
+                getLogger().warn( e.getMessage(), e );
+            }
+        }
+    }
+
+    public void createMissingRepositoryRoles( List<String> repoIds )
+    {
+        for ( String repoId : repoIds )
+        {
+            // manage roles for repositories
+            try
+            {
+                userRepos.createMissingRepositoryRoles( repoId );
+            }
+            catch ( ArchivaSecurityException e )
+            {
+                getLogger().warn( e.getMessage(), e );
+            }
+        }
+    }
+
+    public void executeEnvironmentChecks()
+        throws ArchivaException
+    {
+        if ( ( checkers == null ) || CollectionUtils.isEmpty( checkers.values() ) )
+        {
+            throw new ArchivaException( "Unable to initialize the Redback Security Environment, "
+                + "no Environment Check components found." );
+        }
+
+        List<String> violations = new ArrayList<String>();
+
+        for ( Entry<String, EnvironmentCheck> entry : checkers.entrySet() )
+        {
+            EnvironmentCheck check = entry.getValue();
+            getLogger().info( "Running Environment Check: " + entry.getKey() );
+            check.validateEnvironment( violations );
+        }
+
+        if ( CollectionUtils.isNotEmpty( violations ) )
+        {
+            StringBuffer msg = new StringBuffer();
+            msg.append( "EnvironmentCheck Failure.\n" );
+            msg.append( "======================================================================\n" );
+            msg.append( " ENVIRONMENT FAILURE !! \n" );
+            msg.append( "\n" );
+
+            for ( String violation : violations )
+            {
+                msg.append( violation ).append( "\n" );
+            }
+
+            msg.append( "\n" );
+            msg.append( "======================================================================" );
+            getLogger().fatalError( msg.toString() );
+
+            throw new ArchivaException( "Unable to initialize Redback Security Environment, [" + violations.size()
+                + "] violation(s) encountered, See log for details." );
+        }
+    }
+
+    public void startup()
+        throws ArchivaException
+    {
+        executeEnvironmentChecks();
+
+        createMissingManagedRepositoryRoles( archivaConfiguration.getConfiguration().getManagedRepositories() );
+        archivaConfiguration.addChangeListener( this );
+
+        if ( archivaConfiguration.isDefaulted() )
+        {
+            assignRepositoryObserverToGuestUser( archivaConfiguration.getConfiguration().getManagedRepositories() );
+        }
+    }
+}
diff --git a/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/UserRepositories.java b/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/UserRepositories.java
new file mode 100644 (file)
index 0000000..c448a26
--- /dev/null
@@ -0,0 +1,52 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+import java.util.List;
+
+/**
+ * UserRepositories 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface UserRepositories
+{
+    /**
+     * Get the list of observable repository ids for the user specified.
+     * 
+     * @param principal the principle to obtain the observable repository ids from.
+     * @return the list of observable repository ids.
+     * @throws PrincipalNotFoundException
+     * @throws AccessDeniedException
+     * @throws ArchivaSecurityException
+     */
+    public List<String> getObservableRepositoryIds( String principal )
+        throws PrincipalNotFoundException, AccessDeniedException, ArchivaSecurityException;
+    
+    /**
+     * Create any missing repository roles for the provided repository id.
+     * 
+     * @param repoId the repository id to work off of.
+     * @throws ArchivaSecurityException if there was a problem creating the repository roles.
+     */
+    public void createMissingRepositoryRoles( String repoId )
+        throws ArchivaSecurityException;
+}
diff --git a/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/DefaultUserRepositoriesTest.java b/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/DefaultUserRepositoriesTest.java
new file mode 100644 (file)
index 0000000..d99aea2
--- /dev/null
@@ -0,0 +1,175 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.redback.rbac.RBACManager;
+import org.codehaus.plexus.redback.role.RoleManager;
+import org.codehaus.plexus.redback.system.SecuritySystem;
+import org.codehaus.plexus.redback.users.User;
+import org.codehaus.plexus.redback.users.UserManager;
+
+/**
+ * DefaultUserRepositoriesTest 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class DefaultUserRepositoriesTest
+    extends PlexusTestCase
+{
+    private static final String USER_GUEST = "guest";
+
+    private static final String USER_ADMIN = "admin";
+
+    private static final String USER_ALPACA = "alpaca";
+
+    private SecuritySystem securitySystem;
+
+    private RBACManager rbacManager;
+
+    private RoleManager roleManager;
+
+    private ArchivaConfiguration archivaConfiguration;
+
+    private UserRepositories userRepos;
+
+    public void testGetObservableRepositoryIds()
+        throws Exception
+    {
+        // create some users.
+        createUser( USER_ALPACA, "Al 'Archiva' Paca" );
+
+        assertEquals( "Expected users", 3, securitySystem.getUserManager().getUsers().size() );
+
+        // some unassigned repo observer roles.
+        setupRepository( "central" );
+        setupRepository( "corporate" );
+        setupRepository( "internal" );
+        setupRepository( "snapshots" );
+        setupRepository( "secret" );
+
+        // some assigned repo observer roles.
+        assignRepositoryObserverRole( USER_ALPACA, "corporate" );
+        assignRepositoryObserverRole( USER_ALPACA, "central" );
+        assignRepositoryObserverRole( USER_GUEST, "corporate" );
+        // the global repo observer role.
+        assignGlobalRepositoryObserverRole( USER_ADMIN );
+
+        assertRepoIds( new String[] { "central", "corporate" }, userRepos.getObservableRepositoryIds( USER_ALPACA ) );
+        assertRepoIds( new String[] { "coporate" }, userRepos.getObservableRepositoryIds( USER_GUEST ) );
+        assertRepoIds( new String[] { "central", "internal", "corporate", "snapshots", "secret" }, userRepos
+            .getObservableRepositoryIds( USER_ADMIN ) );
+    }
+
+    private void assertRepoIds( String[] expectedRepoIds, List<String> observableRepositoryIds )
+    {
+        assertNotNull( "Observable Repository Ids cannot be null.", observableRepositoryIds );
+
+        if ( expectedRepoIds.length != observableRepositoryIds.size() )
+        {
+            fail( "Size of Observable Repository Ids wrong, expected <" + expectedRepoIds.length + "> but got <"
+                + observableRepositoryIds.size() + "> instead. \nExpected: [" + StringUtils.join( expectedRepoIds, "," )
+                + "]\nActual: [" + StringUtils.join( observableRepositoryIds.iterator(), "," ) + "]" );
+        }
+    }
+
+    private void setupRepository( String repoId )
+        throws Exception
+    {
+        // Add repo to configuration.
+        ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration();
+        repoConfig.setId( repoId );
+        repoConfig.setName( "Testable repo <" + repoId + ">" );
+        repoConfig.setLocation( getTestPath( "target/test-repo/" + repoId ) );
+        archivaConfiguration.getConfiguration().addManagedRepository( repoConfig );
+
+        // Add repo roles to security.
+        userRepos.createMissingRepositoryRoles( repoId );
+    }
+
+    private void assignGlobalRepositoryObserverRole( String principal )
+        throws Exception
+    {
+        roleManager.assignRole( ArchivaRoleConstants.TEMPLATE_GLOBAL_REPOSITORY_OBSERVER, principal );
+    }
+
+    private void assignRepositoryObserverRole( String principal, String repoId )
+        throws Exception
+    {
+        roleManager.assignTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId, principal );
+    }
+
+    private User createUser( String principal, String fullname )
+    {
+        UserManager userManager = securitySystem.getUserManager();
+
+        User user = userManager.createUser( principal, fullname, principal + "@testable.archiva.apache.org" );
+        securitySystem.getPolicy().setEnabled( false );
+        userManager.addUser( user );
+        securitySystem.getPolicy().setEnabled( true );
+
+        return user;
+    }
+
+    @Override
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        File srcConfig = getTestFile( "src/test/resources/repository-archiva.xml" );
+        File destConfig = getTestFile( "target/test-conf/archiva.xml" );
+
+        destConfig.getParentFile().mkdirs();
+        destConfig.delete();
+
+        FileUtils.copyFile( srcConfig, destConfig );
+
+        securitySystem = (SecuritySystem) lookup( SecuritySystem.class, "testable" );
+        rbacManager = (RBACManager) lookup( RBACManager.class, "memory" );
+        roleManager = (RoleManager) lookup( RoleManager.class, "default" );
+        userRepos = (UserRepositories) lookup( UserRepositories.class, "default" );
+        archivaConfiguration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class );
+
+        // Some basic asserts.
+        assertNotNull( securitySystem );
+        assertNotNull( rbacManager );
+        assertNotNull( roleManager );
+        assertNotNull( userRepos );
+        assertNotNull( archivaConfiguration );
+
+        // Setup Admin User.
+        User adminUser = createUser( USER_ADMIN, "Admin User" );
+        roleManager.assignRole( ArchivaRoleConstants.TEMPLATE_SYSTEM_ADMIN, adminUser.getPrincipal().toString() );
+
+        // Setup Guest User.
+        User guestUser = createUser( USER_GUEST, "Guest User" );
+        roleManager.assignRole( ArchivaRoleConstants.TEMPLATE_GUEST, guestUser.getPrincipal().toString() );
+
+    }
+}
diff --git a/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/SecurityStartupTest.java b/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/SecurityStartupTest.java
new file mode 100644 (file)
index 0000000..f3924f9
--- /dev/null
@@ -0,0 +1,49 @@
+package org.apache.maven.archiva.security;
+
+/*
+ * 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.
+ */
+
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ * SecurityStartupTest 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class SecurityStartupTest
+    extends PlexusTestCase
+{
+    private SecurityStartup secStart;
+
+    @Override
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        secStart = (SecurityStartup) lookup( SecurityStartup.class );
+    }
+
+    public void testEnvironmentChecks()
+        throws Exception
+    {
+        secStart.executeEnvironmentChecks();
+    }
+}
diff --git a/archiva-web/archiva-security/src/test/resources/META-INF/redback/redback-core.xml b/archiva-web/archiva-security/src/test/resources/META-INF/redback/redback-core.xml
new file mode 100644 (file)
index 0000000..794d527
--- /dev/null
@@ -0,0 +1,195 @@
+<?xml version="1.0" ?>
+<redback-role-model>
+  <version>1.0.0</version>
+  <application>Redback XWork Integration Security Core</application>
+  <resources>
+    <resource>
+      <id>global</id>
+      <name>*</name>
+      <permanent>true</permanent>
+      <description>global resource implies full access for authorization</description>
+    </resource>
+    <resource>
+      <id>username</id>
+      <name>${username}</name>
+      <permanent>true</permanent>
+      <description>replaced with the username of the principal at authorization check time</description>
+    </resource>    
+  </resources>
+  <operations>
+    <operation>
+      <id>configuration-edit</id>
+      <name>configuration-edit</name>
+      <description>edit configuration</description>
+      <permanent>true</permanent>
+    </operation>
+    <operation>
+      <id>user-management-user-create</id>
+      <name>user-management-user-create</name>
+      <description>create user</description>
+      <permanent>true</permanent>
+    </operation>
+    <operation>
+      <id>user-management-user-edit</id>
+      <name>user-management-user-edit</name>
+      <description>edit user</description>
+      <permanent>true</permanent>
+    </operation>
+    <operation>
+      <id>user-management-user-role</id>
+      <name>user-management-user-role</name>
+      <description>user roles</description>
+      <permanent>true</permanent>
+    </operation>
+    <operation>
+      <id>user-management-user-delete</id>
+      <name>user-management-user-delete</name>
+      <description>delete user</description>
+      <permanent>true</permanent>
+    </operation>    
+    <operation>
+      <id>user-management-user-list</id>
+      <name>user-management-user-list</name>
+      <description>list users</description>
+      <permanent>true</permanent>
+    </operation>
+    <operation>
+      <id>user-management-role-grant</id>
+      <name>user-management-role-grant</name>
+      <description>grant role</description>
+      <permanent>true</permanent>
+    </operation>
+    <operation>
+      <id>user-management-role-drop</id>
+      <name>user-management-role-drop</name>
+      <description>drop role</description>
+      <permanent>true</permanent>
+    </operation>
+    <operation>
+      <id>user-management-rbac-admin</id>
+      <name>user-management-rbac-admin</name>
+      <description>administer rbac</description>
+      <permanent>true</permanent>
+    </operation>  
+    <operation>
+      <id>guest-access</id>
+      <name>guest-access</name>
+      <description>access guest</description>
+      <permanent>true</permanent>
+    </operation>        
+  </operations>
+  <roles>
+    <role>
+      <id>system-administrator</id>
+      <name>System Administrator</name>
+      <permanent>true</permanent>
+      <assignable>true</assignable>
+      <permissions>
+        <permission>
+          <id>edit-redback-configuration</id>
+          <name>Edit Redback Configuration</name>
+          <operation>configuration-edit</operation>
+          <resource>global</resource>
+          <permanent>true</permanent> 
+        </permission>
+        <permission>
+          <id>manage-rbac-setup</id>
+          <name>User RBAC Management</name>
+          <operation>user-management-rbac-admin</operation>
+          <resource>global</resource>
+          <permanent>true</permanent> 
+        </permission>             
+      </permissions>
+      <childRoles>
+        <childRole>user-administrator</childRole>
+      </childRoles> 
+    </role>
+    <role>
+      <id>user-administrator</id>
+      <name>User Administrator</name>
+      <permanent>true</permanent>
+      <assignable>true</assignable>
+      <permissions>
+        <permission>
+          <id>drop-roles-for-anyone</id>
+          <name>Drop Roles for Anyone</name>
+          <operation>user-management-role-drop</operation>
+          <resource>global</resource>
+          <permanent>true</permanent>
+        </permission>
+        <permission>
+          <id>grant-roles-for-anyone</id>
+          <name>Grant Roles for Anyone</name>
+          <operation>user-management-role-grant</operation>
+          <resource>global</resource>
+          <permanent>true</permanent>
+        </permission>
+        <permission>
+          <id>user-create</id>
+          <name>Create Users</name>
+          <operation>user-management-user-create</operation>
+          <resource>global</resource>
+          <permanent>true</permanent>
+        </permission> 
+        <permission>
+          <id>user-delete</id>
+          <name>Delete Users</name>
+          <operation>user-management-user-delete</operation>
+          <resource>global</resource>
+          <permanent>true</permanent>
+        </permission>                  
+        <permission>
+          <id>user-edit</id>
+          <name>Edit Users</name>
+          <operation>user-management-user-edit</operation>
+          <resource>global</resource>
+          <permanent>true</permanent>
+        </permission>
+        <permission>
+          <id>access-users-roles</id>
+          <name>Access Users Roles</name>
+          <operation>user-management-user-role</operation>
+          <resource>global</resource>
+          <permanent>true</permanent>
+        </permission>
+        <permission>
+          <id>access-user-list</id>
+          <name>Access User List</name>
+          <operation>user-management-user-list</operation>
+          <resource>global</resource>
+          <permanent>true</permanent>
+        </permission>
+      </permissions>
+    </role>
+    <role>
+      <id>registered-user</id>
+      <name>Registered User</name>
+      <permanent>true</permanent>
+      <assignable>true</assignable>
+      <permissions>
+        <permission>
+          <id>edit-user-by-username</id>
+          <name>Edit User Data by Username</name>
+          <operation>user-management-user-edit</operation>
+          <resource>username</resource>
+          <permanent>true</permanent>
+        </permission>
+      </permissions>
+    </role>    
+    <role>
+      <id>guest</id>
+      <name>Guest</name>
+      <permanent>true</permanent>
+      <assignable>true</assignable>
+      <permissions>
+        <permission>
+          <id>guest-permission</id>
+          <name>Guest Permission</name>
+          <operation>guest-access</operation>
+          <resource>global</resource>
+          <permanent>true</permanent>
+        </permission>
+      </permissions>
+    </role>
+  </roles>
+</redback-role-model>
\ No newline at end of file
diff --git a/archiva-web/archiva-security/src/test/resources/org/apache/maven/archiva/security/DefaultUserRepositoriesTest.xml b/archiva-web/archiva-security/src/test/resources/org/apache/maven/archiva/security/DefaultUserRepositoriesTest.xml
new file mode 100644 (file)
index 0000000..5de5fb2
--- /dev/null
@@ -0,0 +1,193 @@
+<?xml version="1.0" ?>
+<component-set>
+  <components>
+  
+    <component>
+      <role>org.apache.maven.archiva.security.UserRepositories</role>
+      <role-hint>default</role-hint>
+      <implementation>org.apache.maven.archiva.security.DefaultUserRepositories</implementation>
+      <description>DefaultUserRepositories</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.system.SecuritySystem</role>
+          <role-hint>testable</role-hint>
+          <field-name>securitySystem</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.RoleManager</role>
+          <role-hint>default</role-hint>
+          <field-name>roleManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
+          <field-name>archivaConfiguration</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.system.SecuritySystem</role>
+      <role-hint>testable</role-hint>
+      <implementation>org.codehaus.plexus.redback.system.DefaultSecuritySystem</implementation>
+      <description>DefaultSecuritySystem:</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.authentication.AuthenticationManager</role>
+          <field-name>authnManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.authorization.Authorizer</role>
+          <role-hint>rbac</role-hint>
+          <field-name>authorizer</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.users.UserManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>userManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.keys.KeyManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>keyManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.policy.UserSecurityPolicy</role>
+          <field-name>policy</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.authorization.Authorizer</role>
+      <role-hint>rbac</role-hint>
+      <implementation>org.codehaus.plexus.redback.authorization.rbac.RbacAuthorizer</implementation>
+      <description>RbacAuthorizer:</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>manager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.users.UserManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>userManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role>
+          <role-hint>default</role-hint>
+          <field-name>evaluator</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.configuration.UserConfiguration</role>
+          <role-hint>default</role-hint>
+          <field-name>config</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role>
+      <role-hint>default</role-hint>
+      <implementation>org.codehaus.plexus.redback.authorization.rbac.evaluator.DefaultPermissionEvaluator</implementation>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.users.UserManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>userManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.role.RoleManager</role>
+      <role-hint>default</role-hint>
+      <implementation>org.codehaus.plexus.redback.role.DefaultRoleManager</implementation>
+      <description>RoleProfileManager:</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.merger.RoleModelMerger</role>
+          <role-hint>default</role-hint>
+          <field-name>modelMerger</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.validator.RoleModelValidator</role>
+          <role-hint>default</role-hint>
+          <field-name>modelValidator</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
+          <role-hint>default</role-hint>
+          <field-name>modelProcessor</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
+          <role-hint>default</role-hint>
+          <field-name>templateProcessor</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
+      <role-hint>default</role-hint>
+      <implementation>org.codehaus.plexus.redback.role.processor.DefaultRoleModelProcessor</implementation>
+      <description>DefaultRoleModelProcessor: inserts the components of the model that can be populated into the rbac manager</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
+      <role-hint>default</role-hint>
+      <implementation>org.codehaus.plexus.redback.role.template.DefaultRoleTemplateProcessor</implementation>
+      <description>DefaultRoleTemplateProcessor: inserts the components of a template into the rbac manager</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
+      <implementation>org.apache.maven.archiva.configuration.DefaultArchivaConfiguration</implementation>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.registry.Registry</role>
+          <role-hint>configured</role-hint>
+        </requirement>
+      </requirements>
+    </component>
+    <component>
+      <role>org.codehaus.plexus.registry.Registry</role>
+      <role-hint>configured</role-hint>
+      <implementation>org.codehaus.plexus.registry.commons.CommonsConfigurationRegistry</implementation>
+      <configuration>
+        <properties>
+          <system/>
+          <xml fileName="${basedir}/target/test-conf/archiva.xml"
+               config-name="org.apache.maven.archiva.base" config-at="org.apache.maven.archiva"/>
+        </properties>
+      </configuration>
+    </component>
+    
+  </components>
+</component-set>
index 65ede8171f6e44d2e99681385fb409d3dfe4c56a..d45485407cdbadf7381f0aa83e098f3c9f903f77 100644 (file)
@@ -34,7 +34,7 @@
         </requirement>
       </requirements>
     </component>
-   <component>
+    <component>
       <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
       <role-hint>default</role-hint>
       <implementation>org.codehaus.plexus.redback.role.processor.DefaultRoleModelProcessor</implementation>
@@ -47,6 +47,7 @@
         </requirement>
       </requirements>
     </component>
+    
     <component>
       <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
       <role-hint>default</role-hint>
         </requirement>
       </requirements>
     </component>
+        <component>
+      <role>org.codehaus.plexus.redback.system.check.EnvironmentCheck</role>
+      <role-hint>required-roles</role-hint>
+      <implementation>org.apache.maven.archiva.security.ArchivaStandardRolesCheck</implementation>
+      <description>ArchivaStandardRolesCheck tests for the existance of expected / standard roles and permissions.</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+  
+    <component>
+      <role>org.apache.maven.archiva.security.SecurityStartup</role>
+      <implementation>org.apache.maven.archiva.security.SecurityStartup</implementation>
+      <description>SecurityStartup</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.RoleManager</role>
+          <role-hint>default</role-hint>
+          <field-name>roleManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.system.check.EnvironmentCheck</role>
+          <field-name>checkers</field-name>
+        </requirement>
+        <requirement>
+          <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
+          <field-name>archivaConfiguration</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
   </components>
 </component-set>
diff --git a/archiva-web/archiva-security/src/test/resources/org/apache/maven/archiva/security/SecurityStartupTest.xml b/archiva-web/archiva-security/src/test/resources/org/apache/maven/archiva/security/SecurityStartupTest.xml
new file mode 100644 (file)
index 0000000..a29933a
--- /dev/null
@@ -0,0 +1,210 @@
+<?xml version="1.0" ?>
+<component-set>
+  <components>
+  
+    <component>
+      <role>org.codehaus.plexus.redback.system.check.EnvironmentCheck</role>
+      <role-hint>required-roles</role-hint>
+      <implementation>org.apache.maven.archiva.security.ArchivaStandardRolesCheck</implementation>
+      <description>ArchivaStandardRolesCheck tests for the existance of expected / standard roles and permissions.</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+  
+    <component>
+      <role>org.apache.maven.archiva.security.SecurityStartup</role>
+      <implementation>org.apache.maven.archiva.security.SecurityStartup</implementation>
+      <description>SecurityStartup</description>
+      <requirements>
+        <requirement>
+          <role>org.apache.maven.archiva.security.UserRepositories</role>
+          <field-name>userRepos</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.system.check.EnvironmentCheck</role>
+          <field-name>checkers</field-name>
+        </requirement>
+        <requirement>
+          <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
+          <field-name>archivaConfiguration</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.apache.maven.archiva.security.UserRepositories</role>
+      <role-hint>default</role-hint>
+      <implementation>org.apache.maven.archiva.security.DefaultUserRepositories</implementation>
+      <description>DefaultUserRepositories</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.system.SecuritySystem</role>
+          <role-hint>testable</role-hint>
+          <field-name>securitySystem</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.RoleManager</role>
+          <role-hint>default</role-hint>
+          <field-name>roleManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
+      <role-hint>default</role-hint>
+      <implementation>org.codehaus.plexus.redback.role.template.DefaultRoleTemplateProcessor</implementation>
+      <description>DefaultRoleTemplateProcessor: inserts the components of a template into the rbac manager</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
+      <role-hint>default</role-hint>
+      <implementation>org.codehaus.plexus.redback.role.processor.DefaultRoleModelProcessor</implementation>
+      <description>DefaultRoleModelProcessor: inserts the components of the model that can be populated into the rbac manager</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.role.RoleManager</role>
+      <role-hint>default</role-hint>
+      <implementation>org.codehaus.plexus.redback.role.DefaultRoleManager</implementation>
+      <instantiation-strategy>singleton</instantiation-strategy>
+      <description>RoleProfileManager:</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.merger.RoleModelMerger</role>
+          <role-hint>default</role-hint>
+          <field-name>modelMerger</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.validator.RoleModelValidator</role>
+          <role-hint>default</role-hint>
+          <field-name>modelValidator</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
+          <role-hint>default</role-hint>
+          <field-name>modelProcessor</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
+          <role-hint>default</role-hint>
+          <field-name>templateProcessor</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>rbacManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.PlexusContainer</role>
+          <field-name>container</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.system.SecuritySystem</role>
+      <role-hint>testable</role-hint>
+      <implementation>org.codehaus.plexus.redback.system.DefaultSecuritySystem</implementation>
+      <description>DefaultSecuritySystem:</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.authentication.AuthenticationManager</role>
+          <field-name>authnManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.authorization.Authorizer</role>
+          <role-hint>rbac</role-hint>
+          <field-name>authorizer</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.users.UserManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>userManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.keys.KeyManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>keyManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.policy.UserSecurityPolicy</role>
+          <field-name>policy</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.authorization.Authorizer</role>
+      <role-hint>rbac</role-hint>
+      <implementation>org.codehaus.plexus.redback.authorization.rbac.RbacAuthorizer</implementation>
+      <description>RbacAuthorizer:</description>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>manager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.users.UserManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>userManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role>
+          <role-hint>default</role-hint>
+          <field-name>evaluator</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.redback.configuration.UserConfiguration</role>
+          <role-hint>default</role-hint>
+          <field-name>config</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role>
+      <role-hint>default</role-hint>
+      <implementation>org.codehaus.plexus.redback.authorization.rbac.evaluator.DefaultPermissionEvaluator</implementation>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.redback.users.UserManager</role>
+          <role-hint>memory</role-hint>
+          <field-name>userManager</field-name>
+        </requirement>
+      </requirements>
+    </component>
+    
+  </components>
+</component-set>
diff --git a/archiva-web/archiva-security/src/test/resources/repository-archiva.xml b/archiva-web/archiva-security/src/test/resources/repository-archiva.xml
new file mode 100644 (file)
index 0000000..f642851
--- /dev/null
@@ -0,0 +1,111 @@
+<?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.
+  -->
+
+<configuration>
+
+  <version>2</version>
+  
+  <repositoryScanning>
+    <fileTypes>
+      <fileType>
+        <id>artifacts</id>
+        <patterns>
+          <pattern>**/*.pom</pattern>
+          <pattern>**/*.jar</pattern>
+          <pattern>**/*.ear</pattern>
+          <pattern>**/*.war</pattern>
+          <pattern>**/*.car</pattern>
+          <pattern>**/*.sar</pattern>
+          <pattern>**/*.mar</pattern>
+          <pattern>**/*.rar</pattern>
+          <pattern>**/*.dtd</pattern>
+          <pattern>**/*.tld</pattern>
+          <pattern>**/*.tar.gz</pattern>
+          <pattern>**/*.tar.bz2</pattern>
+          <pattern>**/*.zip</pattern>
+        </patterns>
+      </fileType>
+      <fileType>
+        <id>indexable-content</id>
+        <patterns>
+          <pattern>**/*.txt</pattern>
+          <pattern>**/*.TXT</pattern>
+          <pattern>**/*.block</pattern>
+          <pattern>**/*.config</pattern>
+          <pattern>**/*.pom</pattern>
+          <pattern>**/*.xml</pattern>
+          <pattern>**/*.xsd</pattern>
+          <pattern>**/*.dtd</pattern>
+          <pattern>**/*.tld</pattern>
+        </patterns>
+      </fileType>
+      <fileType>
+        <id>auto-remove</id>
+        <patterns>
+          <pattern>**/*.bak</pattern>
+          <pattern>**/*~</pattern>
+          <pattern>**/*-</pattern>
+        </patterns>
+      </fileType>
+      <fileType>
+        <id>ignored</id>
+        <patterns>
+          <pattern>**/.htaccess</pattern>
+          <pattern>**/KEYS</pattern>
+          <pattern>**/*.rb</pattern>
+          <pattern>**/*.sh</pattern>
+          <pattern>**/.svn/**</pattern>
+          <pattern>**/.DAV/**</pattern>
+        </patterns>
+      </fileType>
+    </fileTypes>
+    <knownContentConsumers>
+      <knownContentConsumer>update-db-artifact</knownContentConsumer>
+      <knownContentConsumer>create-missing-checksums</knownContentConsumer>
+      <knownContentConsumer>update-db-repository-metadata</knownContentConsumer>
+      <knownContentConsumer>validate-checksum</knownContentConsumer>
+      <knownContentConsumer>validate-signature</knownContentConsumer>
+      <knownContentConsumer>index-content</knownContentConsumer>
+      <knownContentConsumer>auto-remove</knownContentConsumer>
+      <knownContentConsumer>auto-rename</knownContentConsumer>
+    </knownContentConsumers>
+    <invalidContentConsumers>
+      <invalidContentConsumer>update-db-bad-content</invalidContentConsumer>
+    </invalidContentConsumers>
+  </repositoryScanning>
+
+  <databaseScanning>
+    <cronExpression>0 0 * * ?</cronExpression>
+    <unprocessedConsumers>
+      <unprocessedConsumer>index-artifact</unprocessedConsumer>
+      <unprocessedConsumer>update-db-project</unprocessedConsumer>
+      <unprocessedConsumer>validate-repository-metadata</unprocessedConsumer>
+      <unprocessedConsumer>index-archive-toc</unprocessedConsumer>
+      <unprocessedConsumer>update-db-bytecode-stats</unprocessedConsumer>
+      <unprocessedConsumer>index-public-methods</unprocessedConsumer>
+    </unprocessedConsumers>
+    <cleanupConsumers>
+      <cleanupConsumer>not-present-remove-db-artifact</cleanupConsumer>
+      <cleanupConsumer>not-present-remove-db-project</cleanupConsumer>
+      <cleanupConsumer>not-present-remove-indexed</cleanupConsumer>
+    </cleanupConsumers>
+  </databaseScanning>
+
+</configuration>
index e76b40cad8bfbb8066c618cea3320324172174a1..2bc0422314906274cd69d5e0c0131d6e3dae998e 100644 (file)
@@ -19,11 +19,20 @@ package org.apache.maven.archiva.web.action;
  * under the License.
  */
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.maven.archiva.database.browsing.BrowsingResults;
 import org.apache.maven.archiva.database.browsing.RepositoryBrowsing;
+import org.apache.maven.archiva.security.AccessDeniedException;
+import org.apache.maven.archiva.security.ArchivaSecurityException;
+import org.apache.maven.archiva.security.ArchivaUser;
+import org.apache.maven.archiva.security.PrincipalNotFoundException;
+import org.apache.maven.archiva.security.UserRepositories;
 import org.codehaus.plexus.xwork.action.PlexusActionSupport;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Browse the repository.
  *
@@ -39,6 +48,16 @@ public class BrowseAction
      * @plexus.requirement role-hint="default"
      */
     private RepositoryBrowsing repoBrowsing;
+    
+    /**
+     * @plexus.requirement
+     */
+    private UserRepositories userRepositories;
+    
+    /**
+     * @plexus.requirement role-hint="xwork"
+     */
+    private ArchivaUser archivaUser;
 
     private BrowsingResults results;
 
@@ -48,7 +67,13 @@ public class BrowseAction
 
     public String browse()
     {
-        this.results = repoBrowsing.getRoot();
+        List<String> selectedRepos = getObservableRepos();
+        if ( CollectionUtils.isEmpty( selectedRepos ) )
+        {
+            return GlobalResults.ACCESS_TO_NO_REPOS;
+        }
+
+        this.results = repoBrowsing.getRoot( getPrincipal(), selectedRepos );
         return SUCCESS;
     }
 
@@ -61,7 +86,14 @@ public class BrowseAction
             return ERROR;
         }
 
-        this.results = repoBrowsing.selectGroupId( groupId );
+        List<String> selectedRepos = getObservableRepos();
+        if ( CollectionUtils.isEmpty( selectedRepos ) )
+        {
+            return GlobalResults.ACCESS_TO_NO_REPOS;
+        }
+
+        
+        this.results = repoBrowsing.selectGroupId( getPrincipal(), selectedRepos, groupId );
         return SUCCESS;
     }
 
@@ -81,9 +113,43 @@ public class BrowseAction
             return ERROR;
         }
 
-        this.results = repoBrowsing.selectArtifactId( groupId, artifactId );
+        List<String> selectedRepos = getObservableRepos();
+        if ( CollectionUtils.isEmpty( selectedRepos ) )
+        {
+            return GlobalResults.ACCESS_TO_NO_REPOS;
+        }
+
+        
+        this.results = repoBrowsing.selectArtifactId( getPrincipal(), selectedRepos, groupId, artifactId );
         return SUCCESS;
     }
+    
+    private String getPrincipal()
+    {
+        return archivaUser.getActivePrincipal();
+    }
+    
+    private List<String> getObservableRepos()
+    {
+        try
+        {
+            return userRepositories.getObservableRepositoryIds( getPrincipal() );
+        }
+        catch ( PrincipalNotFoundException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+        }
+        catch ( AccessDeniedException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+            // TODO: pass this onto the screen.
+        }
+        catch ( ArchivaSecurityException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+        }
+        return Collections.emptyList();
+    }
 
     public String getGroupId()
     {
diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/GlobalResults.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/GlobalResults.java
new file mode 100644 (file)
index 0000000..15b7ae5
--- /dev/null
@@ -0,0 +1,31 @@
+package org.apache.maven.archiva.web.action;
+
+/*
+ * 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.
+ */
+
+/**
+ * GlobalResults - constants for global result definitions. 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class GlobalResults
+{
+    public static final String ACCESS_TO_NO_REPOS = "access_to_no_repos";
+}
index 37ca5146f8c83ead7a5681af12283a3156d9ac40..2785f7414eca76165df58aac4aa69924f3f9164f 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.maven.archiva.web.action;
  * under the License.
  */
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.maven.archiva.database.ArchivaDAO;
 import org.apache.maven.archiva.database.Constraint;
@@ -28,9 +29,15 @@ import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
 import org.apache.maven.archiva.indexer.search.CrossRepositorySearch;
 import org.apache.maven.archiva.indexer.search.SearchResultLimits;
 import org.apache.maven.archiva.indexer.search.SearchResults;
+import org.apache.maven.archiva.security.AccessDeniedException;
+import org.apache.maven.archiva.security.ArchivaSecurityException;
+import org.apache.maven.archiva.security.ArchivaUser;
+import org.apache.maven.archiva.security.PrincipalNotFoundException;
+import org.apache.maven.archiva.security.UserRepositories;
 import org.codehaus.plexus.xwork.action.PlexusActionSupport;
 
 import java.net.MalformedURLException;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -60,6 +67,16 @@ public class SearchAction
      * @plexus.requirement role-hint="default"
      */
     private CrossRepositorySearch crossRepoSearch;
+    
+    /**
+     * @plexus.requirement
+     */
+    private UserRepositories userRepositories;
+    
+    /**
+     * @plexus.requirement role-hint="xwork"
+     */
+    private ArchivaUser archivaUser;
 
     private static final String RESULTS = "results";
 
@@ -79,8 +96,14 @@ public class SearchAction
         assert q != null && q.length() != 0;
 
         SearchResultLimits limits = new SearchResultLimits( 0 );
+        
+        List<String> selectedRepos = getObservableRepos();
+        if ( CollectionUtils.isEmpty( selectedRepos ) )
+        {
+            return GlobalResults.ACCESS_TO_NO_REPOS;
+        }
 
-        results = crossRepoSearch.searchForTerm( q, limits );
+        results = crossRepoSearch.searchForTerm( getPrincipal(), selectedRepos, q, limits );
 
         if ( results.isEmpty() )
         {
@@ -125,16 +148,42 @@ public class SearchAction
             // 1 hit? return it's information directly!            
             return ARTIFACT;
         }
-        else
-        {
-            return RESULTS;
-        }
+        
+        return RESULTS;
     }
 
+    @Override
     public String doInput()
     {
         return INPUT;
     }
+    
+    private String getPrincipal()
+    {
+        return archivaUser.getActivePrincipal();
+    }
+    
+    private List<String> getObservableRepos()
+    {
+        try
+        {
+            return userRepositories.getObservableRepositoryIds( getPrincipal() );
+        }
+        catch ( PrincipalNotFoundException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+        }
+        catch ( AccessDeniedException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+            // TODO: pass this onto the screen.
+        }
+        catch ( ArchivaSecurityException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+        }
+        return Collections.emptyList();
+    }
 
     public String getQ()
     {
index 2c750c72d2920856c9fdc5d70e79216198bb5b76..faaa8261d22213cb6548be0c694ca8d1df66397a 100644 (file)
@@ -26,8 +26,14 @@ import org.apache.maven.archiva.database.ArchivaDatabaseException;
 import org.apache.maven.archiva.database.ObjectNotFoundException;
 import org.apache.maven.archiva.database.browsing.RepositoryBrowsing;
 import org.apache.maven.archiva.model.ArchivaProjectModel;
+import org.apache.maven.archiva.security.AccessDeniedException;
+import org.apache.maven.archiva.security.ArchivaSecurityException;
+import org.apache.maven.archiva.security.ArchivaUser;
+import org.apache.maven.archiva.security.PrincipalNotFoundException;
+import org.apache.maven.archiva.security.UserRepositories;
 import org.codehaus.plexus.xwork.action.PlexusActionSupport;
 
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -46,6 +52,16 @@ public class ShowArtifactAction
      * @plexus.requirement role-hint="default"
      */
     private RepositoryBrowsing repoBrowsing;
+    
+    /**
+     * @plexus.requirement
+     */
+    private UserRepositories userRepositories;
+    
+    /**
+     * @plexus.requirement role-hint="xwork"
+     */
+    private ArchivaUser archivaUser;
 
     /* .\ Input Parameters \.________________________________________ */
 
@@ -86,7 +102,7 @@ public class ShowArtifactAction
     {
         try
         {
-            this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
+            this.model = repoBrowsing.selectVersion( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
         }
         catch ( ObjectNotFoundException oe )
         {
@@ -104,7 +120,7 @@ public class ShowArtifactAction
     public String dependencies()
         throws ObjectNotFoundException, ArchivaDatabaseException
     {
-        this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
+        this.model = repoBrowsing.selectVersion( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
 
         this.dependencies = model.getDependencies();
 
@@ -117,7 +133,7 @@ public class ShowArtifactAction
     public String mailingLists()
         throws ObjectNotFoundException, ArchivaDatabaseException
     {
-        this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
+        this.model = repoBrowsing.selectVersion( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
         this.mailingLists = model.getMailingLists();
 
         return SUCCESS;
@@ -142,9 +158,9 @@ public class ShowArtifactAction
     public String dependees()
         throws ObjectNotFoundException, ArchivaDatabaseException
     {
-        this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
+        this.model = repoBrowsing.selectVersion( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
 
-        this.dependees = repoBrowsing.getUsedBy( groupId, artifactId, version );
+        this.dependees = repoBrowsing.getUsedBy( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
 
         return SUCCESS;
     }
@@ -155,10 +171,37 @@ public class ShowArtifactAction
     public String dependencyTree()
         throws ObjectNotFoundException, ArchivaDatabaseException
     {
-        this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
+        this.model = repoBrowsing.selectVersion( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
 
         return SUCCESS;
     }
+    
+    private String getPrincipal()
+    {
+        return archivaUser.getActivePrincipal();
+    }
+    
+    private List<String> getObservableRepos()
+    {
+        try
+        {
+            return userRepositories.getObservableRepositoryIds( getPrincipal() );
+        }
+        catch ( PrincipalNotFoundException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+        }
+        catch ( AccessDeniedException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+            // TODO: pass this onto the screen.
+        }
+        catch ( ArchivaSecurityException e )
+        {
+            getLogger().warn( e.getMessage(), e );
+        }
+        return Collections.emptyList();
+    }
 
     public void validate()
     {
index 0153a7b23ba34dc81ee0043a51e9590fdbfad989..10283a90f7e1e5735cd7f935e55672628f360cde 100644 (file)
@@ -193,14 +193,13 @@ public class SecuritySynchronization
                     ua = rbacManager.createUserAssignment( principal );
                 }
 
-                ua.addRoleName( ArchivaRoleConstants.REPOSITORY_OBSERVER_ROLE_PREFIX + " - " + repoId );
+                ua.addRoleName( ArchivaRoleConstants.toRepositoryObserverRoleName( repoId ) );
                 rbacManager.saveUserAssignment( ua );
             }
             catch ( RbacManagerException e )
             {
-                getLogger().warn(
-                                  "Unable to add role [" + ArchivaRoleConstants.REPOSITORY_OBSERVER_ROLE_PREFIX + " - "
-                                      + repoId + "] to " + principal + " user.", e );
+                getLogger().warn( "Unable to add role [" + ArchivaRoleConstants.toRepositoryObserverRoleName( repoId )
+                                      + "] to " + principal + " user.", e );
             }
         }
     }
diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java
new file mode 100644 (file)
index 0000000..44223b8
--- /dev/null
@@ -0,0 +1,77 @@
+package org.apache.maven.archiva.web.util;
+
+/*
+ * 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.
+ */
+
+import com.opensymphony.xwork.ActionContext;
+
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.apache.maven.archiva.security.ArchivaUser;
+import org.codehaus.plexus.redback.system.SecuritySession;
+import org.codehaus.plexus.redback.users.User;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * ArchivaXworkUser 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ * 
+ * @plexus.component role="org.apache.maven.archiva.security.ArchivaUser"
+ *                   role-hint="xwork"
+ */
+public class ArchivaXworkUser
+    implements ArchivaUser
+{
+    private Map<String, Object> getContextSession()
+    {
+        ActionContext context = ActionContext.getContext();
+        Map<String, Object> sessionMap = context.getSession();
+        if ( sessionMap == null )
+        {
+            sessionMap = new HashMap<String, Object>();
+        }
+
+        return sessionMap;
+    }
+
+    private SecuritySession getSecuritySession()
+    {
+        return (SecuritySession) getContextSession().get( SecuritySession.ROLE );
+    }
+
+    public String getActivePrincipal()
+    {
+        SecuritySession securitySession = getSecuritySession();
+        if ( securitySession == null )
+        {
+            return ArchivaRoleConstants.PRINCIPAL_GUEST;
+        }
+
+        User user = securitySession.getUser();
+        if ( user == null )
+        {
+            return ArchivaRoleConstants.PRINCIPAL_GUEST;
+        }
+
+        return (String) user.getPrincipal();
+    }
+}
index d75ae3172256fd8f59ceda137d880fe0e95d1604..53c8596cdf5d544d2561ab7ade52b738354cccdc 100644 (file)
@@ -82,6 +82,7 @@
 
     <global-results>
       <!-- The following security-* result names arrive from the plexus-security package -->
+      
       <result name="security-login-success" type="redirect-action">index</result>
       <result name="security-login-cancel" type="redirect-action">index</result>
       <result name="security-login-locked" type="redirect-action">
       <!-- Generic Catchall for those action configurations that forget to
            include a result for 'error' -->
       <result name="error">/WEB-INF/jsp/generalError.jsp</result>
+      <result name="access_to_no_repos">/WEB-INF/jsp/accessToNoRepos.jsp</result>
     </global-results>
   </package>
 
diff --git a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/accessToNoRepos.jsp b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/accessToNoRepos.jsp
new file mode 100644 (file)
index 0000000..5ed0473
--- /dev/null
@@ -0,0 +1,46 @@
+<%--
+  ~ 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.
+  --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<html>
+<head>
+  <title>You have access to no repositories</title>
+  <ww:head/>
+</head>
+
+<body>
+
+<div id="contentArea">
+  
+   <div id="results">
+     You have access to no repositories.  
+     Ask your system administrator for access.  
+   </div>
+  
+</div>
+
+<div class="clear">
+  <hr/>
+</div>
+
+</body>
+
+</html>
diff --git a/pom.xml b/pom.xml
index 2fb881c95fb531322e413c5653f989d958dc8f67..39c90e752844cb285dd237af03363e4888cfa466 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <groupId>org.codehaus.plexus.redback</groupId>
         <artifactId>redback-rbac-memory</artifactId>
         <version>${redback.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.plexus.redback</groupId>
+        <artifactId>redback-users-memory</artifactId>
+        <version>${redback.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.plexus.redback</groupId>
+        <artifactId>redback-keys-memory</artifactId>
+        <version>${redback.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.plexus.redback</groupId>
+        <artifactId>redback-rbac-model</artifactId>
+        <version>${redback.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.plexus.redback</groupId>
+        <artifactId>redback-authorization-rbac</artifactId>
+        <version>${redback.version}</version>
       </dependency>
       <dependency>
         <groupId>org.codehaus.plexus.redback</groupId>
         <artifactId>redback-rbac-role-manager</artifactId>
         <version>${redback.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.codehaus.plexus.redback</groupId>
+        <artifactId>redback-system</artifactId>
+        <version>${redback.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.codehaus.plexus.redback</groupId>
         <artifactId>redback-taglib</artifactId>
   <properties>
     <maven.version>2.0.5</maven.version>
     <wagon.version>1.0-beta-2</wagon.version>
-    <redback.version>1.0-alpha-3</redback.version>
+    <redback.version>1.0-alpha-4</redback.version>
   </properties>
   <!-- for plexus webdav snapshot -->
   <repositories>
     <repository>
       <id>codehaus.snapshots</id>
       <url>http://snapshots.repository.codehaus.org/</url>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
     </repository>
   </repositories>
 </project>