diff --git a/database/migrations/2019_01_17_174733_create_bitbucket2_config_table.php b/database/migrations/2019_01_17_174733_create_bitbucket2_config_table.php index 47cbd09..96bdd75 100644 --- a/database/migrations/2019_01_17_174733_create_bitbucket2_config_table.php +++ b/database/migrations/2019_01_17_174733_create_bitbucket2_config_table.php @@ -24,6 +24,21 @@ function (Blueprint $t) { $t->text('token')->nullable(); } ); + DB::table('service')->where('service.type', '=', 'bitbucket') + ->update(['service.type' => 'bitbucket2']); + $bitbucket_config_data = DB::table("bitbucket_config")->get(); + foreach($bitbucket_config_data as $bitbucket_record){ + if(!(DB::table('bitbucket2_config')->where('service_id', '=', $bitbucket_record->service_id)->get()->count() > 0)){ + DB::table('bitbucket2_config')->insert([ + 'service_id' => $bitbucket_record->service_id, + 'vendor' => $bitbucket_record->vendor, + 'username' => $bitbucket_record->username, + 'password' => $bitbucket_record->password, + 'token' => $bitbucket_record->token, + ]); + } + } + DB::table("bitbucket_config")->delete(); } /** @@ -33,6 +48,21 @@ function (Blueprint $t) { */ public function down() { + $bitbucket2_config_data = DB::table("bitbucket2_config")->get(); + foreach($bitbucket2_config_data as $bitbucket_record){ + if (!(DB::table('bitbucket_config')->where('service_id', '=', $bitbucket_record->service_id)->get()->count() > 0)) { + DB::table('bitbucket_config')->insert([ + 'service_id' => $bitbucket_record->service_id, + 'vendor' => $bitbucket_record->vendor, + 'username' => $bitbucket_record->username, + 'password' => $bitbucket_record->password, + 'token' => $bitbucket_record->token, + ]); + } + } + DB::table('service')->where('service.type', '=', 'bitbucket2') + ->update(['service.type' => 'bitbucket']); + DB::table("bitbucket2_config")->delete(); Schema::dropIfExists('bitbucket2_config'); } } diff --git a/database/migrations/2019_07_26_110740_rename_service_type_from_bitbucket2_to_bitbucket.php b/database/migrations/2019_07_26_110740_rename_service_type_from_bitbucket2_to_bitbucket.php new file mode 100644 index 0000000..be48965 --- /dev/null +++ b/database/migrations/2019_07_26_110740_rename_service_type_from_bitbucket2_to_bitbucket.php @@ -0,0 +1,31 @@ +where('service.type', '=', 'bitbucket2') + ->update(['service.type' => 'bitbucket']); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + DB::table('service')->where('service.type', '=', 'bitbucket') + ->update(['service.type' => 'bitbucket2']); + } +} diff --git a/database/migrations/2019_07_26_110748_move_data_from_bitbucket2_config_table_into_bitbucket_config_table.php b/database/migrations/2019_07_26_110748_move_data_from_bitbucket2_config_table_into_bitbucket_config_table.php new file mode 100644 index 0000000..2bd9183 --- /dev/null +++ b/database/migrations/2019_07_26_110748_move_data_from_bitbucket2_config_table_into_bitbucket_config_table.php @@ -0,0 +1,53 @@ +get(); + foreach($bitbucket2_config_data as $bitbucket_record){ + if (!(DB::table('bitbucket_config')->where('service_id', '=', $bitbucket_record->service_id)->get()->count() > 0)) { + DB::table('bitbucket_config')->insert([ + 'service_id' => $bitbucket_record->service_id, + 'vendor' => $bitbucket_record->vendor, + 'username' => $bitbucket_record->username, + 'password' => $bitbucket_record->password, + 'token' => $bitbucket_record->token, + ]); + } + } + DB::table("bitbucket2_config")->delete(); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $bitbucket_config_data = DB::table("bitbucket_config")->get(); + foreach($bitbucket_config_data as $bitbucket_record){ + if(!(DB::table('bitbucket2_config')->where('service_id', '=', $bitbucket_record->service_id)->get()->count() > 0)){ + DB::table('bitbucket2_config')->insert([ + 'service_id' => $bitbucket_record->service_id, + 'vendor' => $bitbucket_record->vendor, + 'username' => $bitbucket_record->username, + 'password' => $bitbucket_record->password, + 'token' => $bitbucket_record->token, + ]); + } + } + DB::table("bitbucket_config")->delete(); + } +} diff --git a/database/migrations/2019_07_26_113359_remove_bitbucket2_config_table.php b/database/migrations/2019_07_26_113359_remove_bitbucket2_config_table.php new file mode 100644 index 0000000..5860a85 --- /dev/null +++ b/database/migrations/2019_07_26_113359_remove_bitbucket2_config_table.php @@ -0,0 +1,38 @@ +integer('service_id')->unsigned()->primary(); + $t->foreign('service_id')->references('id')->on('service')->onDelete('cascade'); + $t->string('vendor'); + $t->string('username')->nullable(); + $t->text('password')->nullable(); + $t->text('token')->nullable(); + } + ); + } +} diff --git a/src/Components/Bitbucket2Client.php b/src/Components/Bitbucket2Client.php deleted file mode 100644 index aa41f4d..0000000 --- a/src/Components/Bitbucket2Client.php +++ /dev/null @@ -1,244 +0,0 @@ -get($this->buildSrcPath($ref, $path), $params); - } -} - -class Bitbucket2Client implements GitClientInterface -{ - /** @var \Bitbucket\Client */ - protected $client; - - /** @var String */ - protected $username; - - /** - * BitbucketClient constructor. - * - * @param $config - * - * @throws \DreamFactory\Core\Exceptions\InternalServerErrorException - */ - public function __construct($config) - { - $this->validateConfig($config); - $this->username = $config['vendor']; - $username = array_get($config, 'username'); - $password = array_get($config, 'password'); - $token = array_get($config, 'token'); - $auth = null; - - if (!empty($username) && !empty($token)) { - $auth = new OauthAuthenticator(); - } elseif (!empty($username) && !empty($password)) { - $auth = new PasswordAuthenticator(); - } - $client = new Client(); - if (empty($auth)) { - $this->client = $client; - } else { - $this->client = $auth->with($client)->authenticate($config); - } - } - - /** - * @param $config - * - * @throws \DreamFactory\Core\Exceptions\InternalServerErrorException - */ - protected function validateConfig($config) - { - if (empty(array_get($config, 'vendor'))) { - throw new InternalServerErrorException('No account/organization name provided for Bitbucket client.'); - } - } - - /** - * @param int $page - * @param int $perPage - * - * @return array - * @throws \DreamFactory\Core\Exceptions\RestException - */ - public function repoAll($page = 1, $perPage = 50) - { - $repo = $this->client->repositories(); - - $pager = new ResultPager($this->client); - return $pager->fetchAll($repo->users($this->username), "list"); - } - - /** - * @param string $repo - * @param null $path - * @param null $ref - * - * @return array - * @throws \DreamFactory\Core\Exceptions\RestException - */ - public function repoList($repo, $path = null, $ref = null) - { - $src = $this->client->repositories()->users($this->username)->src($repo); - $pager = new ResultPager($this->client); - $params = [ - 'fields' => 'values.commit.hash,values.commit.date,values.commit.revision,values.path,values.name,values.type,values.node,values.size' - ]; - $list = $pager->fetchAll($src, "list", [$params]); - - return $this->cleanSrcList($list); - } - - /** - * @param string $repo - * @param string $path - * @param null $ref - * - * @return array - * @throws \DreamFactory\Core\Exceptions\RestException - */ - public function repoGetFileInfo($repo, $path, $ref = null) - { - $src = new CustomSrc($this->client->getHttpClient(), $this->username, $repo); - - $result = $src->listPath($ref, $path, ['format' => 'meta']); - if ('commit_directory' === $result['type']) { - $pager = new ResultPager($this->client); - $params = [ - 'fields' => 'values.commit.hash,values.commit.date,values.path,values.name,values.type,values.node,values.size' - ]; - $result = $pager->fetchAll($src, "listPath", [$ref, $path, $params]); - $result = $this->cleanSrcList($result); - } else { - $file_content = $src->download($ref, $path); - $result = $this->cleanSrcData($result, $file_content); - } - - return $result; - } - - /** - * @param string $repo - * @param string $path - * @param null $ref - * - * @return mixed|string - * @throws \DreamFactory\Core\Exceptions\RestException - */ - public function repoGetFileContent($repo, $path, $ref = null) - { - $src = new CustomSrc($this->client->getHttpClient(), $this->username, $repo); - - $result = $src->listPath($ref, $path, ['format' => 'meta']); - - if ('commit_directory' === $result['type']) { - $pager = new ResultPager($this->client); - $params = ['fields' => 'values.path,values.name']; - $result = $pager->fetchAll($src, "listPath", [$ref, $path, $params]); - return $this->cleanDirectoryContent($result); - } else { - return (string)$src->download($ref, $path); - } - - } - - /** - * @param $list - * - * @return array - */ - protected function cleanDirectoryContent($list) - { - $names = []; - foreach ($list as $obj) { - $chuckedName = explode('/', $obj['path']); - $name = array_pop($chuckedName); - $names[] = $name; - } - return implode("\n", $names); - } - - /** - * @param $list - * - * @return array - */ - protected function cleanSrcList($list) - { - $dirs = array(); - $files = array(); - - foreach ($list as $obj) { - if ("commit_directory" === $obj['type']) { - $dirs[] = $obj; - } elseif ("commit_file" === $obj['type']) { - $files[] = $obj; - } - } - - foreach ($dirs as $key => $dir) { - $chunked_path = explode('/', $dir['path']); - $dirs[$key] = [ - 'name' => array_pop($chunked_path), - 'path' => implode("/", $chunked_path) . '/', - 'type' => 'dir', - 'node' => $dir['commit']['hash'] - ]; - } - - foreach ($files as $key => $file) { - $name = array_get($file, 'path'); - $date = new \DateTime($file['commit']['date']); - $date->setTimeZone(new \DateTimeZone('UTC')); - $files[$key] = [ - 'size' => $file['size'], - 'path' => $file['path'], - 'timestamp' => date_format($date, 'Y-m-d\TH:i:s\Z'), - 'utctimestamp' => $date->format('Y-m-d H:i:sP'), - 'revision' => $file['commit']['hash'], - 'name' => $name, - 'type' => 'file', - 'node' => $file['commit']['hash'] - ]; - } - - return array_merge($dirs, $files); - } - - /** - * @param $data - * @param $content - * - * @return array - */ - protected function cleanSrcData($data, $content) - { - - $content = base64_encode($content); - $size = array_get($data, 'size'); - $path = array_get($data, 'path'); - $data = [ - 'node' => $data['commit']['hash'], - 'path' => $path, - 'content' => $content, - 'encoding' => 'base64', - 'size' => $size, - ]; - - return $data; - } -} \ No newline at end of file diff --git a/src/Components/BitbucketClient.php b/src/Components/BitbucketClient.php index ee128b6..fdf250a 100644 --- a/src/Components/BitbucketClient.php +++ b/src/Components/BitbucketClient.php @@ -8,8 +8,17 @@ use GrahamCampbell\Bitbucket\Authenticators\PasswordAuthenticator; use GrahamCampbell\Bitbucket\Authenticators\OauthAuthenticator; use Bitbucket\Client; +use Bitbucket\Api\Repositories\Users\Src; use Bitbucket\ResultPager; +class CustomSrc extends Src +{ + public function listPath($ref, $path, $params = []) + { + return $this->get($this->buildSrcPath($ref, $path), $params); + } +} + class BitbucketClient implements GitClientInterface { /** @var \Bitbucket\Client */ @@ -73,7 +82,6 @@ public function repoAll($page = 1, $perPage = 50) $repo = $this->client->repositories(); $pager = new ResultPager($this->client); - return $pager->fetchAll($repo->users($this->username), "list"); } @@ -87,11 +95,12 @@ public function repoAll($page = 1, $perPage = 50) */ public function repoList($repo, $path = null, $ref = null) { - - $src = new BitbucketRepositorySrc($this->client->getHttpClient(), $this->username, $repo); + $src = $this->client->repositories()->users($this->username)->src($repo); $pager = new ResultPager($this->client); - - $list = $pager->fetchAll($src, "listPath", [$ref]); + $params = [ + 'fields' => 'values.commit.hash,values.commit.date,values.commit.revision,values.path,values.name,values.type,values.node,values.size' + ]; + $list = $pager->fetchAll($src, "list", [$params]); return $this->cleanSrcList($list); } @@ -106,12 +115,22 @@ public function repoList($repo, $path = null, $ref = null) */ public function repoGetFileInfo($repo, $path, $ref = null) { - $src = new BitbucketRepositorySrc($this->client->getHttpClient(), $this->username, $repo); - $pager = new ResultPager($this->client); + $src = new CustomSrc($this->client->getHttpClient(), $this->username, $repo); - $result = $pager->fetchAll($src, "listPath", [$ref, $path]); + $result = $src->listPath($ref, $path, ['format' => 'meta']); + if ('commit_directory' === $result['type']) { + $pager = new ResultPager($this->client); + $params = [ + 'fields' => 'values.commit.hash,values.commit.date,values.path,values.name,values.type,values.node,values.size' + ]; + $result = $pager->fetchAll($src, "listPath", [$ref, $path, $params]); + $result = $this->cleanSrcList($result); + } else { + $file_content = $src->download($ref, $path); + $result = $this->cleanSrcData($result, $file_content); + } - return $this->cleanSrcData($result); + return $result; } /** @@ -124,26 +143,35 @@ public function repoGetFileInfo($repo, $path, $ref = null) */ public function repoGetFileContent($repo, $path, $ref = null) { - $src = new BitbucketRepositorySrc($this->client->getHttpClient(), $this->username, $repo); + $src = new CustomSrc($this->client->getHttpClient(), $this->username, $repo); + + $result = $src->listPath($ref, $path, ['format' => 'meta']); + + if ('commit_directory' === $result['type']) { + $pager = new ResultPager($this->client); + $params = ['fields' => 'values.path,values.name']; + $result = $pager->fetchAll($src, "listPath", [$ref, $path, $params]); + return $this->cleanDirectoryContent($result); + } else { + return (string)$src->download($ref, $path); + } - return (string)$src->raw($ref, $path)->getBody(); } /** - * @param \Buzz\Message\Response $response + * @param $list * - * @return \Buzz\Message\Response - * @throws \DreamFactory\Core\Exceptions\RestException + * @return array */ - protected function checkResponse(Response $response) + protected function cleanDirectoryContent($list) { - $statusCode = $response->getStatusCode(); - - if ($statusCode >= 300) { - throw new RestException($statusCode, $response->getContent()); + $names = []; + foreach ($list as $obj) { + $chuckedName = explode('/', $obj['path']); + $name = array_pop($chuckedName); + $names[] = $name; } - - return $response; + return implode("\n", $names); } /** @@ -153,25 +181,41 @@ protected function checkResponse(Response $response) */ protected function cleanSrcList($list) { - $dirs = array_get($list, 'directories'); - $files = array_get($list, 'files'); - $path = array_get($list, 'path'); - $node = array_get($list, 'node'); + $dirs = array(); + $files = array(); + + foreach ($list as $obj) { + if ("commit_directory" === $obj['type']) { + $dirs[] = $obj; + } elseif ("commit_file" === $obj['type']) { + $files[] = $obj; + } + } foreach ($dirs as $key => $dir) { + $chunked_path = explode('/', $dir['path']); $dirs[$key] = [ - 'name' => $dir, - 'path' => $path, + 'name' => array_pop($chunked_path), + 'path' => implode("/", $chunked_path) . '/', 'type' => 'dir', - 'node' => $node + 'node' => $dir['commit']['hash'] ]; } foreach ($files as $key => $file) { $name = array_get($file, 'path'); - $files[$key]['name'] = $name; - $files[$key]['type'] = 'file'; - $files[$key]['node'] = $node; + $date = new \DateTime($file['commit']['date']); + $date->setTimeZone(new \DateTimeZone('UTC')); + $files[$key] = [ + 'size' => $file['size'], + 'path' => $file['path'], + 'timestamp' => date_format($date, 'Y-m-d\TH:i:s\Z'), + 'utctimestamp' => $date->format('Y-m-d H:i:sP'), + 'revision' => $file['commit']['hash'], + 'name' => $name, + 'type' => 'file', + 'node' => $file['commit']['hash'] + ]; } return array_merge($dirs, $files); @@ -179,23 +223,23 @@ protected function cleanSrcList($list) /** * @param $data + * @param $content * * @return array */ - protected function cleanSrcData($data) + protected function cleanSrcData($data, $content) { - if (isset($data['data'])) { - $content = base64_encode($data['data']); - $size = array_get($data, 'size'); - unset($data['size']); - unset($data['data']); // Keeping response consistent with other SCM services using key 'content' instead of 'data' - $data['content'] = $content; - $data['encoding'] = 'base64'; - $data['size'] = $size; - - return $data; - } elseif (isset($data['files']) || isset($data['directories'])) { - return $this->cleanSrcList($data); - } + $content = base64_encode($content); + $size = array_get($data, 'size'); + $path = array_get($data, 'path'); + $data = [ + 'node' => $data['commit']['hash'], + 'path' => $path, + 'content' => $content, + 'encoding' => 'base64', + 'size' => $size, + ]; + + return $data; } } \ No newline at end of file diff --git a/src/Components/BitbucketRepositorySrc.php b/src/Components/BitbucketRepositorySrc.php deleted file mode 100644 index 6cbe711..0000000 --- a/src/Components/BitbucketRepositorySrc.php +++ /dev/null @@ -1,95 +0,0 @@ -client = $client; - } - - /** - * @param array $params - * @param string $ref - * @param string $path - * - * @throws \Http\Client\Exception - * - * @return array - */ - public function listPath($ref, $path = "/", array $params = []) - { - return ["values" => $this->get($this->buildSrcPath($ref, $path), $params)]; - } - - /** - * Build the raw path from the given parts. - * - * @param string[] $parts - * - * @throws \Bitbucket\Exception\InvalidArgumentException - * - * @return string - */ - protected function buildRawPath(string ...$parts) - { - return static::buildPath('repositories', $this->username, $this->repo, 'raw', ...$parts); - } - - /** - * @param string $ref - * @param string $path - * @param array $params - * - * @throws \Http\Client\Exception - * - * @return \Psr\Http\Message\ResponseInterface - */ - public function raw($ref, $path = "/", array $params = []) - { - return $this->pureGet($this->buildRawPath($ref, $path), $params); - } - - /** - * {@inheritDoc} - */ - public function pureGet(string $path, array $params = [], array $headers = []) - { - if ($this->perPage !== null && !isset($params['pagelen'])) { - $params['pagelen'] = $this->perPage; - } - - if ($params) { - $path .= '?' . http_build_query($params); - } - - return $this->client->get(self::computePath($path), $headers); - } - - /** - * {@inheritDoc} - */ - public static function computePath(string $path) - { - return sprintf('/1.0/%s', $path); - } -} \ No newline at end of file diff --git a/src/Models/Bitbucket2Config.php b/src/Models/Bitbucket2Config.php deleted file mode 100644 index 4c4cc78..0000000 --- a/src/Models/Bitbucket2Config.php +++ /dev/null @@ -1,60 +0,0 @@ - 'integer', - ]; - - /** @var array */ - protected $encrypted = ['token', 'password']; - - /** @var array */ - protected $protected = ['token', 'password']; - - /** - * {@inheritdoc} - */ - protected static function prepareConfigSchemaField(array &$schema) - { - parent::prepareConfigSchemaField($schema); - - switch ($schema['name']) { - case 'vendor': - $schema['label'] = 'Account/Organization'; - $schema['description'] = 'Bitbucket Account/Organization/Username for accessing a repository.'; - break; - case 'username': - $schema['label'] = 'Username'; - $schema['description'] = 'Your Bitbucket username goes here.'; - break; - case 'password': - $schema['type'] = 'password'; - $schema['label'] = 'Password'; - $schema['description'] = 'Your Bitbucket password goes here.'; - break; - case 'token': - $schema['label'] = 'Bitbucket Token'; - $schema['description'] = 'You can use a Bitbucket token here to access your account.' . - ' If you use token then there is no need to enter the Password above.'; - break; - } - } -} \ No newline at end of file diff --git a/src/Resources/Bitbucket2Repo.php b/src/Resources/Bitbucket2Repo.php deleted file mode 100644 index c39817f..0000000 --- a/src/Resources/Bitbucket2Repo.php +++ /dev/null @@ -1,22 +0,0 @@ - 'object', - 'properties' => [ - 'uuid' => ['type' => 'string'], - 'name' => ['type' => 'string'], - 'description' => ['type' => 'string'], - ] - ]; - } -} \ No newline at end of file diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 326aa93..182d8e8 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -4,10 +4,8 @@ use DreamFactory\Core\Enums\ServiceTypeGroups; use DreamFactory\Core\Git\Models\BitbucketConfig; -use DreamFactory\Core\Git\Models\Bitbucket2Config; use DreamFactory\Core\Git\Models\GitHubConfig; use DreamFactory\Core\Git\Services\Bitbucket; -use DreamFactory\Core\Git\Services\Bitbucket2; use DreamFactory\Core\Git\Services\GitHub; use DreamFactory\Core\Git\Services\GitLab; use DreamFactory\Core\Git\Models\GitLabConfig; @@ -48,7 +46,7 @@ public function register() new ServiceType([ 'name' => 'bitbucket', 'label' => 'Bitbucket Service', - 'description' => 'A client service for Bitbucket', + 'description' => 'A client service for Bitbucket API 2.0', 'group' => ServiceTypeGroups::SCM, 'config_handler' => BitbucketConfig::class, 'factory' => function ($config){ @@ -56,18 +54,6 @@ public function register() }, ]) ); - $df->addType( - new ServiceType([ - 'name' => 'bitbucket2', - 'label' => 'Bitbucket2 Service', - 'description' => 'A client service for Bitbucket API 2.0', - 'group' => ServiceTypeGroups::SCM, - 'config_handler' => Bitbucket2Config::class, - 'factory' => function ($config){ - return new Bitbucket2($config); - }, - ]) - ); }); } diff --git a/src/Services/Bitbucket2.php b/src/Services/Bitbucket2.php deleted file mode 100644 index b351ccf..0000000 --- a/src/Services/Bitbucket2.php +++ /dev/null @@ -1,25 +0,0 @@ - [ - 'name' => Bitbucket2Repo::RESOURCE_NAME, - 'class_name' => Bitbucket2Repo::class, - 'label' => 'Repository' - ] - ]; - - /** @inheritdoc */ - protected function setClient($config) - { - /** @var BitbucketClient client */ - $this->client = new Bitbucket2Client($config); - } -} \ No newline at end of file