Browse Source

Allow hooks APIs to work with URLs that have a different format in packagist than the default on github/bitbucket

Jordi Boggiano 12 years ago
parent
commit
47cb359b58

+ 9 - 7
src/Packagist/WebBundle/Controller/ApiController.php

@@ -82,7 +82,7 @@ class ApiController extends Controller
      */
     public function githubPostReceive(Request $request)
     {
-        return $this->receivePost($request, '{(^|//)(?P<url>github\.com/[\w.-]+/[\w.-]+?)(\.git)?$}', '(\.git)?$');
+        return $this->receivePost($request, '{^(?:https?://|git://|git@)?(?P<domain>github\.com)[:/](?P<repo>[\w.-]+/[\w.-]+?)(?:\.git)?$}');
     }
 
     /**
@@ -91,7 +91,7 @@ class ApiController extends Controller
      */
     public function bitbucketPostReceive(Request $request)
     {
-        return $this->receivePost($request, '{(^|//)(?P<url>bitbucket\.org/[\w.-]+/[\w.-]+?)/?$}', '/?$');
+        return $this->receivePost($request, '{^(?:https?://)?(?P<domain>bitbucket\.org)/(?P<repo>[\w.-]+/[\w.-]+?)/?$}');
     }
 
     /**
@@ -138,7 +138,7 @@ class ApiController extends Controller
         return new Response('{"status": "success"}', 201);
     }
 
-    protected function receivePost(Request $request, $urlRegex, $optionalRepositorySuffix)
+    protected function receivePost(Request $request, $urlRegex)
     {
         $payload = json_decode($request->request->get('payload'), true);
         if (!$payload || !isset($payload['repository']['url'])) {
@@ -146,12 +146,10 @@ class ApiController extends Controller
         }
 
         // try to parse the URL first to avoid the DB lookup on malformed requests
-        if (!preg_match($urlRegex, $payload['repository']['url'], $match)) {
+        if (!preg_match($urlRegex, $payload['repository']['url'], $requestedRepo)) {
             return new Response(json_encode(array('status' => 'error', 'message' => 'Could not parse payload repository URL',)), 406);
         }
 
-        $payloadRepositoryChunk = $match['url'];
-
         $username = $request->request->has('username') ?
             $request->request->get('username') :
             $request->query->get('username');
@@ -173,8 +171,12 @@ class ApiController extends Controller
         $updater = $this->get('packagist.package_updater');
         $em = $this->get('doctrine.orm.entity_manager');
 
+$candidate = array();
         foreach ($user->getPackages() as $package) {
-            if (preg_match('{'.preg_quote($payloadRepositoryChunk).$optionalRepositorySuffix.'}', $package->getRepository())) {
+            if (preg_match($urlRegex, $package->getRepository(), $candidate)
+                && $candidate['domain'] === $requestedRepo['domain']
+                && $candidate['repo'] === $requestedRepo['repo']
+            ) {
                 set_time_limit(3600);
                 $updated = true;
 

+ 19 - 8
src/Packagist/WebBundle/Tests/Controller/ApiControllerTest.php

@@ -28,12 +28,15 @@ class ApiControllerTest extends WebTestCase
         $this->assertEquals(403, $client->getResponse()->getStatusCode(), 'POST method should return 403 "Forbidden" if invalid username and API Token are sent');
     }
 
-    public function testGithubApi()
+    /**
+     * @dataProvider githubApiProvider
+     */
+    public function testGithubApi($url)
     {
         $client = self::createClient();
 
         $package = new Package;
-        $package->setRepository('http://github.com/composer/composer.git');
+        $package->setRepository($url);
 
         $user = new User;
         $user->addPackages($package);
@@ -56,6 +59,16 @@ class ApiControllerTest extends WebTestCase
         $this->assertEquals(202, $client->getResponse()->getStatusCode());
     }
 
+    public function githubApiProvider()
+    {
+        return array(
+            array('https://github.com/composer/composer.git'),
+            array('http://github.com/composer/composer.git'),
+            array('http://github.com/composer/composer'),
+            array('git@github.com:composer/composer.git'),
+        );
+    }
+
     /**
      * @depends      testGithubFailsCorrectly
      * @dataProvider urlProvider
@@ -82,23 +95,21 @@ class ApiControllerTest extends WebTestCase
             // valid github URLs
             array('github', 'github.com/user/repo', true),
             array('github', 'github.com/user/repo.git', true),
-            array('github', '//github.com/user/repo', true),
             array('github', 'http://github.com/user/repo', true),
             array('github', 'https://github.com/user/repo', true),
             array('github', 'https://github.com/user/repo.git', true),
             array('github', 'git://github.com/user/repo', true),
+            array('github', 'git@github.com:user/repo.git', true),
+            array('github', 'git@github.com:user/repo', true),
 
             // valid bitbucket URLs
             array('bitbucket', 'bitbucket.org/user/repo', true),
-            array('bitbucket', '//bitbucket.org/user/repo', true),
             array('bitbucket', 'http://bitbucket.org/user/repo', true),
             array('bitbucket', 'https://bitbucket.org/user/repo', true),
 
-            // protocol is ignored, so these are okay, too
-            array('github', 'php://github.com/user/repository', true),
-            array('github', 'javascript://github.com/user/repository', true),
-
             // invalid URLs
+            array('github', 'php://github.com/user/repository', false),
+            array('github', 'javascript://github.com/user/repository', false),
             array('github', 'http://', false),
             array('github', 'http://thisisnotgithub.com/user/repository', false),
             array('github', 'http://thisisnotbitbucket.org/user/repository', false),