Browse Source

Allow SVN to connect with credentials provided with the auth.json file

Benjamin Grandfond 10 years ago
parent
commit
a21b0f82db

+ 1 - 1
src/Composer/Downloader/SvnDownloader.php

@@ -84,7 +84,7 @@ class SvnDownloader extends VcsDownloader
      */
     protected function execute($baseUrl, $command, $url, $cwd = null, $path = null)
     {
-        $util = new SvnUtil($baseUrl, $this->io);
+        $util = new SvnUtil($baseUrl, $this->io, $this->config);
         try {
             return $util->execute($command, $url, $cwd, $path, $this->io->isVerbose());
         } catch (\RuntimeException $e) {

+ 1 - 1
src/Composer/Repository/Vcs/SvnDriver.php

@@ -306,7 +306,7 @@ class SvnDriver extends VcsDriver
     protected function execute($command, $url)
     {
         if (null === $this->util) {
-            $this->util = new SvnUtil($this->baseUrl, $this->io, $this->process);
+            $this->util = new SvnUtil($this->baseUrl, $this->io, $this->config, $this->process);
         }
 
         try {

+ 65 - 17
src/Composer/Util/Svn.php

@@ -12,6 +12,7 @@
 
 namespace Composer\Util;
 
+use Composer\Config;
 use Composer\IO\IOInterface;
 
 /**
@@ -57,15 +58,21 @@ class Svn
      */
     protected $qtyAuthTries = 0;
 
+    /**
+     * @var \Composer\Config
+     */
+    protected $config;
+
     /**
      * @param string                   $url
      * @param \Composer\IO\IOInterface $io
      * @param ProcessExecutor          $process
      */
-    public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
+    public function __construct($url, IOInterface $io, Config $config, ProcessExecutor $process = null)
     {
         $this->url = $url;
         $this->io  = $io;
+        $this->config = $config;
         $this->process = $process ?: new ProcessExecutor;
     }
 
@@ -123,16 +130,12 @@ class Svn
             throw new \RuntimeException($output);
         }
 
-        // no auth supported for non interactive calls
-        if (!$this->io->isInteractive()) {
-            throw new \RuntimeException(
-                'can not ask for authentication in non interactive mode ('.$output.')'
-            );
+        if (!$this->hasAuth()) {
+            $this->doAuthDance();
         }
 
         // try to authenticate if maximum quantity of tries not reached
-        if ($this->qtyAuthTries++ < self::MAX_QTY_AUTH_TRIES || !$this->hasAuth()) {
-            $this->doAuthDance();
+        if ($this->qtyAuthTries++ < self::MAX_QTY_AUTH_TRIES) {
 
             // restart the process
             return $this->execute($command, $url, $cwd, $path, $verbose);
@@ -147,9 +150,17 @@ class Svn
      * Repositories requests credentials, let's put them in.
      *
      * @return \Composer\Util\Svn
+     * @throws \RuntimeException
      */
     protected function doAuthDance()
     {
+        // cannot ask for credentials in non interactive mode
+        if (!$this->io->isInteractive()) {
+            throw new \RuntimeException(
+                'can not ask for authentication in non interactive mode'
+            );
+        }
+
         $this->io->write("The Subversion server ({$this->url}) requested credentials:");
 
         $this->hasAuth = true;
@@ -248,17 +259,11 @@ class Svn
             return $this->hasAuth;
         }
 
-        $uri = parse_url($this->url);
-        if (empty($uri['user'])) {
-            return $this->hasAuth = false;
-        }
-
-        $this->credentials['username'] = $uri['user'];
-        if (!empty($uri['pass'])) {
-            $this->credentials['password'] = $uri['pass'];
+        if (false === $this->createAuthFromConfig()) {
+            $this->createAuthFromUrl();
         }
 
-        return $this->hasAuth = true;
+        return $this->hasAuth;
     }
 
     /**
@@ -270,4 +275,47 @@ class Svn
     {
         return $this->cacheCredentials ? '' : '--no-auth-cache ';
     }
+
+    /**
+     * Create the auth params from the configuration file.
+     *
+     * @return bool
+     */
+    protected function createAuthFromConfig()
+    {
+        if (!$this->config->has('http-basic')) {
+            return $this->hasAuth = false;
+        }
+
+        $authConfig = $this->config->get('http-basic');
+
+        if (array_key_exists($this->url, $authConfig)) {
+            $this->credentials['username'] = $authConfig[$this->url]['username'];
+            $this->credentials['password'] = $authConfig[$this->url]['password'];
+
+            return $this->hasAuth = true;
+        }
+
+        return $this->hasAuth = false;
+    }
+
+    /**
+     * Create the auth params from the url
+     *
+     * @return bool
+     */
+    protected function createAuthFromUrl()
+    {
+        $uri = parse_url($this->url);
+        if (empty($uri['user'])) {
+            return $this->hasAuth = false;
+        }
+
+        $this->credentials['username'] = $uri['user'];
+        if (!empty($uri['pass'])) {
+            $this->credentials['password'] = $uri['pass'];
+        }
+
+        return $this->hasAuth = true;
+    }
 }

+ 0 - 3
tests/Composer/Test/Repository/Vcs/SvnDriverTest.php

@@ -23,9 +23,6 @@ class SvnDriverTest extends \PHPUnit_Framework_TestCase
     public function testWrongCredentialsInUrl()
     {
         $console = $this->getMock('Composer\IO\IOInterface');
-        $console->expects($this->exactly(6))
-            ->method('isInteractive')
-            ->will($this->returnValue(true));
 
         $output  = "svn: OPTIONS of 'http://corp.svn.local/repo':";
         $output .= " authorization failed: Could not authenticate to server:";

+ 23 - 2
tests/Composer/Test/Util/SvnTest.php

@@ -1,6 +1,7 @@
 <?php
 namespace Composer\Test\Util;
 
+use Composer\Config;
 use Composer\IO\NullIO;
 use Composer\Util\Svn;
 
@@ -16,7 +17,7 @@ class SvnTest extends \PHPUnit_Framework_TestCase
      */
     public function testCredentials($url, $expect)
     {
-        $svn = new Svn($url, new NullIO);
+        $svn = new Svn($url, new NullIO, new Config());
         $reflMethod = new \ReflectionMethod('Composer\\Util\\Svn', 'getCredentialString');
         $reflMethod->setAccessible(true);
 
@@ -41,7 +42,7 @@ class SvnTest extends \PHPUnit_Framework_TestCase
     {
         $url = 'http://svn.example.org';
 
-        $svn = new Svn($url, new NullIO());
+        $svn = new Svn($url, new NullIO(), new Config());
         $reflMethod = new \ReflectionMethod('Composer\\Util\\Svn', 'getCommand');
         $reflMethod->setAccessible(true);
 
@@ -51,6 +52,26 @@ class SvnTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    public function testCredentialsFromConfig()
+    {
+        $url = 'http://svn.apache.org';
+
+        $config = new Config();
+        $config->merge(array(
+            'config' => array(
+                'http-basic' => array(
+                    $url => array('username' => 'foo', 'password' => 'bar')
+                )
+            )
+        ));
+
+        $svn = new Svn($url, new NullIO, $config);
+        $reflMethod = new \ReflectionMethod('Composer\\Util\\Svn', 'getCredentialString');
+        $reflMethod->setAccessible(true);
+
+        $this->assertEquals($this->getCmd(" --username 'foo' --password 'bar' "), $reflMethod->invoke($svn));
+    }
+
     private function getCmd($cmd)
     {
         if (defined('PHP_WINDOWS_VERSION_BUILD')) {