Browse Source

add basic bitbucket support

Christoph 13 years ago
parent
commit
47a360591b
1 changed files with 69 additions and 14 deletions
  1. 69 14
      src/Packagist/WebBundle/Controller/ApiController.php

+ 69 - 14
src/Packagist/WebBundle/Controller/ApiController.php

@@ -87,24 +87,57 @@ class ApiController extends Controller
             return new Response(json_encode(array('status' => 'error', 'message' => 'Missing or invalid payload',)), 406);
         }
 
-        $username = $request->request->has('username') ?
-            $request->request->get('username') :
-            $request->query->get('username');
+        $response = $this->checkCredentials($request);
+        if ($response instanceof Response) {
+            return $response;
+        }
 
-        $apiToken = $request->request->has('apiToken') ?
-            $request->request->get('apiToken') :
-            $request->query->get('apiToken');
+        if (!preg_match('{(github.com/[\w.-]+/[\w.-]+?)(\.git)?$}', $payload['repository']['url'], $match)) {
+            return new Response(json_encode(array('status' => 'error', 'message' => 'Could not parse payload repository URL',)), 406);
+        }
 
-        $updater = $this->get('packagist.package_updater');
-        $em = $this->get('doctrine.orm.entity_manager');
-        $user = $this->get('packagist.user_repository')
-            ->findOneBy(array('username' => $username, 'apiToken' => $apiToken));
+        $payloadRepositoryChunk = $match[1];
 
-        if (!$user) {
-            return new Response(json_encode(array('status' => 'error', 'message' => 'Invalid credentials',)), 403);
+        $updated = false;
+        $config = Factory::createConfig();
+        $loader = new ValidatingArrayLoader(new ArrayLoader());
+        foreach ($user->getPackages() as $package) {
+            if (preg_match('{'.preg_quote($payloadRepositoryChunk).'(\.git)?$}', $package->getRepository())) {
+                set_time_limit(3600);
+                $updated = true;
+
+                $repository = new VcsRepository(array('url' => $package->getRepository()), new NullIO, $config);
+                $repository->setLoader($loader);
+                $package->setAutoUpdated(true);
+                $em->flush();
+                $updater->update($package, $repository);
+            }
         }
 
-        if (!preg_match('{(github.com/[\w.-]+/[\w.-]+?)(\.git)?$}', $payload['repository']['url'], $match)) {
+        if ($updated) {
+            return new Response('{"status": "success"}', 202);
+        }
+
+        return new Response(json_encode(array('status' => 'error', 'message' => 'Could not find a package that matches this request (does user maintain the package?)',)), 404);
+    }
+
+    /**
+     * @Route("/api/bitbucket", name="bitbucket_postreceive", defaults={"_format" = "json"})
+     * @Method({"POST"})
+     */
+    public function bitbucketPostReceive(Request $request)
+    {
+        $payload = json_decode($request->request->get('payload'), true);
+        if (!$payload || !isset($payload['repository']['url'])) {
+            return new Response(json_encode(array('status' => 'error', 'message' => 'Missing or invalid payload',)), 406);
+        }
+
+        $response = $this->checkCredentials($request);
+        if ($response instanceof Response) {
+            return $response;
+        }
+
+        if (!preg_match('{(bitbucket.org/[\w.-]+/[\w.-]+?)/?$}', $payload['repository']['url'], $match)) {
             return new Response(json_encode(array('status' => 'error', 'message' => 'Could not parse payload repository URL',)), 406);
         }
 
@@ -114,7 +147,7 @@ class ApiController extends Controller
         $config = Factory::createConfig();
         $loader = new ValidatingArrayLoader(new ArrayLoader());
         foreach ($user->getPackages() as $package) {
-            if (preg_match('{'.preg_quote($payloadRepositoryChunk).'(\.git)?$}', $package->getRepository())) {
+            if (preg_match('{'.preg_quote($payloadRepositoryChunk).'/?$}', $package->getRepository())) {
                 set_time_limit(3600);
                 $updated = true;
 
@@ -176,4 +209,26 @@ class ApiController extends Controller
 
         return new Response('{"status": "success"}', 201);
     }
+
+    protected function checkCredentials(Request $request)
+    {
+        $username = $request->request->has('username') ?
+            $request->request->get('username') :
+            $request->query->get('username');
+
+        $apiToken = $request->request->has('apiToken') ?
+            $request->request->get('apiToken') :
+            $request->query->get('apiToken');
+
+        $updater = $this->get('packagist.package_updater');
+        $em = $this->get('doctrine.orm.entity_manager');
+        $user = $this->get('packagist.user_repository')
+            ->findOneBy(array('username' => $username, 'apiToken' => $apiToken));
+
+        if (!$user) {
+            return new Response(json_encode(array('status' => 'error', 'message' => 'Invalid credentials',)), 403);
+        }
+
+        return null;
+    }
 }