]> source.dussan.org Git - archiva.git/commitdiff
[MRM-694]
authorMaria Odea B. Ching <oching@apache.org>
Thu, 22 May 2008 10:02:29 +0000 (10:02 +0000)
committerMaria Odea B. Ching <oching@apache.org>
Thu, 22 May 2008 10:02:29 +0000 (10:02 +0000)
-fix virtual repo authentication problem

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

archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java
archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java
archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletRepositoryGroupTest.java
archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/rss/SecuritySystemStub.java
archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java

index 861e087e47e4a59f7084e974ba5ae4886b6ff688..4e8c040b7f72c5f451b427f8fb9f2948160f3fa8 100644 (file)
@@ -29,8 +29,11 @@ import org.codehaus.plexus.redback.authorization.AuthorizationResult;
 import org.codehaus.plexus.redback.authorization.UnauthorizedException;
 import org.codehaus.plexus.redback.policy.AccountLockedException;
 import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+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;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,8 +66,8 @@ public class ArchivaServletAuthenticator
                                  boolean isWriteRequest )
         throws AuthorizationException, UnauthorizedException
     {
-        // also check for permission to proxy the resource when MRM-579 is implemented
-        
+        // TODO: also check for permission to proxy the resource when MRM-579 is implemented
+
         String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
 
         if ( isWriteRequest )
@@ -89,4 +92,31 @@ public class ArchivaServletAuthenticator
 
         return true;
     }
+
+    public boolean isAuthorizedToAccessVirtualRepository( String principal, String repoId )
+        throws UnauthorizedException
+    {
+        try
+        {
+            User user = securitySystem.getUserManager().findUser( principal );
+            if ( user.isLocked() )
+            {
+                throw new UnauthorizedException( "User account is locked." );
+            }
+
+            AuthenticationResult authn = new AuthenticationResult( true, principal, null );
+            SecuritySession securitySession = new DefaultSecuritySession( authn, user );
+
+            return securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
+                                                repoId );
+        }
+        catch ( UserNotFoundException e )
+        {
+            throw new UnauthorizedException( e.getMessage() );
+        }
+        catch ( AuthorizationException e )
+        {
+            throw new UnauthorizedException( e.getMessage() );
+        }
+    }
 }
index a96928887c5f17e2ecbf0d0275d0e77b683e5856..fb39b4bca2490db2cb7c0c42ea159ef515ce1dbe 100644 (file)
@@ -40,4 +40,7 @@ public interface ServletAuthenticator
 
     public boolean isAuthorized( HttpServletRequest request, SecuritySession securitySession, String repositoryId,
         boolean isWriteRequest ) throws AuthorizationException, UnauthorizedException;
+    
+    public boolean isAuthorizedToAccessVirtualRepository( String principal, String repoId )
+        throws UnauthorizedException;
 }
index ef80939c0fbbda03f2b25538c966614a3351814c..201ac934266bf43d023df76703e603875c1afdf7 100644 (file)
@@ -215,7 +215,7 @@ public class RepositoryServletRepositoryGroupTest
         WebResponse response = sc.getResponse( request );
                 
         assertNotNull( "Should have received a response", response );
-        assertResponseOK( response );
+        assertEquals( "Should have been an 401 response code.", HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
     }
         
     protected void assertResponseBadRequest( WebResponse response )
index 546f2560676f4f36995c1199625819ed6e0c6db5..96dc95e7b015e645c9290f766fdf7bd7f8a8cb34 100644 (file)
@@ -24,7 +24,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
 import org.codehaus.plexus.redback.authentication.AuthenticationDataSource;
 import org.codehaus.plexus.redback.authentication.AuthenticationException;
 import org.codehaus.plexus.redback.authentication.AuthenticationResult;
index 7e8c12958af447653c362ce1bc408a01bbada36e..3b4d0b27d5a135ede0af02f75b4567d4984bab15 100644 (file)
@@ -56,6 +56,7 @@ import org.codehaus.plexus.redback.authorization.UnauthorizedException;
 import org.codehaus.plexus.redback.policy.AccountLockedException;
 import org.codehaus.plexus.redback.policy.MustChangePasswordException;
 import org.codehaus.plexus.redback.system.SecuritySession;
+import org.codehaus.plexus.redback.system.SecuritySystemConstants;
 import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 import org.slf4j.Logger;
@@ -63,7 +64,9 @@ import org.slf4j.LoggerFactory;
 
 import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.io.*;
 
 /**
@@ -123,7 +126,7 @@ public class ArchivaDavResourceFactory
     public DavResource createResource( final DavResourceLocator locator, final DavServletRequest request,
                                        final DavServletResponse response )
         throws DavException
-    {        
+    {   
         checkLocatorIsInstanceOfRepositoryLocator( locator );
         ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator;
         
@@ -636,7 +639,7 @@ public class ArchivaDavResourceFactory
         {
             AuthenticationResult result = httpAuth.getAuthenticationResult( request, null );            
             SecuritySession securitySession = httpAuth.getSecuritySession();
-            
+                       
             return servletAuth.isAuthenticated( request, result ) &&
                 servletAuth.isAuthorized( request, securitySession, repositoryId,
                                           WebdavMethodUtil.isWriteMethod( request.getMethod() ) );
@@ -671,36 +674,63 @@ public class ArchivaDavResourceFactory
         LogicalResource logicalResource =
             new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
         
-        for( String repository : repositories )
+        // flow: 
+        // if the current user logged in has permission to any of the repositories, allow user to
+        // browse the repo group but displaying only the repositories which the user has permission to access.
+        // otherwise, prompt for authentication.
+        
+        // put the current session in the session map which will be passed to ArchivaXworkUser
+        Map<String, Object> sessionMap = new HashMap<String, Object>();
+        if( request.getSession().getAttribute( SecuritySystemConstants.SECURITY_SESSION_KEY ) != null )
         {
-            ManagedRepositoryContent managedRepository = null;
-
-            try
-            {
-                managedRepository = getManagedRepository( repository );
-            }
-            catch ( DavException de )
-            {
-                throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Invalid managed repository <" +
-                    repository + ">" );
-            }
-            
-            if( isAuthorized( request, repository ) )
-            {
-                if ( !locator.getResourcePath().startsWith( ArchivaVirtualDavResource.HIDDEN_PATH_PREFIX ) )
+            sessionMap.put( SecuritySystemConstants.SECURITY_SESSION_KEY, 
+                            request.getSession().getAttribute( SecuritySystemConstants.SECURITY_SESSION_KEY ) );
+        }
+        
+        String activePrincipal = ArchivaXworkUser.getActivePrincipal( sessionMap );        
+        boolean allow = isAllowedToContinue( request, repositories, activePrincipal );
+              
+        if( allow )
+        {            
+            for( String repository : repositories )
+            {    
+                // for prompted authentication
+                if( httpAuth.getSecuritySession() != null )
                 {
-                    if( managedRepository != null )
+                    try
                     {   
-                        File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
-                        if( resourceFile.exists() )
+                        if( isAuthorized( request, repository ) )                        
                         {
-                            mergedRepositoryContents.add( resourceFile );
-                        }                    
+                            getResource( locator, mergedRepositoryContents, logicalResource, repository );
+                        }
+                    }                    
+                    catch ( DavException e )
+                    {                        
+                        continue;
                     }
                 }
+                else
+                {
+                    // for the current user logged in 
+                    try
+                    {
+                        if( servletAuth.isAuthorizedToAccessVirtualRepository( activePrincipal, repository ) )
+                        {
+                            getResource( locator, mergedRepositoryContents, logicalResource, repository );
+                        }
+                    }
+                    catch ( UnauthorizedException e )                    
+                    {                        
+                        continue;
+                    }
+                }                
             }
-        }      
-                
+        }
+        else
+        {
+            throw new UnauthorizedDavException( locator.getRepositoryId(), "User not authorized." );
+        }
+        
         ArchivaVirtualDavResource resource =
             new ArchivaVirtualDavResource( mergedRepositoryContents, logicalResource.getPath(), mimeTypes, locator, this );
        
@@ -712,5 +742,88 @@ public class ArchivaDavResourceFactory
         
         return resource;
     }
+
+    private void getResource( ArchivaDavResourceLocator locator, List<File> mergedRepositoryContents,
+                              LogicalResource logicalResource, String repository )
+        throws DavException
+    {
+        ManagedRepositoryContent managedRepository = null;
+
+        try
+        {
+            managedRepository = getManagedRepository( repository );
+        }
+        catch ( DavException de )
+        {
+            throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Invalid managed repository <" +
+                repository + ">" );
+        }                            
+        
+        if ( !locator.getResourcePath().startsWith( ArchivaVirtualDavResource.HIDDEN_PATH_PREFIX ) )
+        {
+            if( managedRepository != null )
+            {   
+                File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
+                if( resourceFile.exists() )
+                {                    
+                    mergedRepositoryContents.add( resourceFile );
+                }                    
+            }
+        }
+    }
     
+    /**
+     * Check if the current user is authorized to access any of the repos
+     *  
+     * @param request
+     * @param repositories
+     * @param activePrincipal
+     * @return
+     */
+    private boolean isAllowedToContinue( DavServletRequest request, List<String> repositories, String activePrincipal )    
+    {
+        boolean allow = false;
+        
+              
+        // if securitySession != null, it means that the user was prompted for authentication
+        if( httpAuth.getSecuritySession() != null )
+        {
+            for( String repository : repositories )
+            {
+                try
+                {
+                    if( isAuthorized( request, repository ) )
+                    {
+                        allow = true;
+                        break;
+                    }
+                }
+                catch( DavException e )
+                {                    
+                    continue;
+                }
+            }  
+        }
+        else
+        {   
+            for( String repository : repositories )
+            {
+                try
+                {
+                    if( servletAuth.isAuthorizedToAccessVirtualRepository( activePrincipal, repository ) )
+                    {
+                        allow = true;
+                        break;
+                    }
+                }
+                catch ( UnauthorizedException e )
+                {                    
+                    continue;
+                }
+            }  
+        }
+        
+        return allow;
+    }
+        
 }