Skip to content

Commit

Permalink
DP-460 Upgrade to PHP 8.1 / Laravel 9
Browse files Browse the repository at this point in the history
- Migrate Bitbucket, GitLab, GitHub clients
- Fix pagination
- Disallow password authorization support for GitHub client
- Get rid of global helper functions
  • Loading branch information
daniilly committed Feb 28, 2023
1 parent c9bff5f commit 710dc03
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 72 deletions.
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"dreamfactory/df-core": "~0.25",
"graham-campbell/github": "^7.5|^8.2",
"graham-campbell/gitlab": "^1.7.0|^2.2",
"graham-campbell/bitbucket": "^4.2|^5.2",
"php-http/guzzle6-adapter": "^1.1"
"dreamfactory/df-core": "~1.0",
"graham-campbell/github": "^10.3.1",
"graham-campbell/gitlab": "^5.4.1",
"graham-campbell/bitbucket": "^8.1",
"php-http/guzzle7-adapter": "^1.0.0"
},
"autoload": {
"psr-4": {
Expand Down
56 changes: 33 additions & 23 deletions src/Components/BitbucketClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@

namespace DreamFactory\Core\Git\Components;

use DreamFactory\Core\Exceptions\RestException;
use DreamFactory\Core\Git\Contracts\ClientInterface as GitClientInterface;
use DreamFactory\Core\Exceptions\InternalServerErrorException;
use GrahamCampbell\Bitbucket\Authenticators\PasswordAuthenticator;
use GrahamCampbell\Bitbucket\Authenticators\OauthAuthenticator;
use Bitbucket\Client;
use Bitbucket\Api\Repositories\Users\Src;
use Bitbucket\ResultPager;

use Bitbucket\Api\Repositories\Workspaces;
use Bitbucket\Api\Repositories\Workspaces\Src;
use GrahamCampbell\Bitbucket\Auth\AuthenticatorFactory;
use Illuminate\Support\Arr;

/*
Method 'listPath' is similar to 'show' method from library,
but it gives us full control over $params variable,
so we do not establish ['format' => 'meta'] into it
*/
class CustomSrc extends Src
{
public function listPath($ref, $path, $params = [])
{
return $this->get($this->buildSrcPath($ref, $path), $params);
return $this->get($this->buildSrcUri($ref, $path), $params);
}
}

Expand All @@ -27,6 +32,9 @@ class BitbucketClient implements GitClientInterface
/** @var String */
protected $username;

/** @var Bitbucket\Api\Repositories\AbstractRepositoriesApi */
protected $workspace;

/**
* BitbucketClient constructor.
*
Expand All @@ -38,18 +46,21 @@ 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');
$username = Arr::get($config, 'username');
$password = Arr::get($config, 'password');
$token = Arr::get($config, 'token');

$authFactory = new AuthenticatorFactory();
$auth = null;

if (!empty($username) && !empty($token)) {
$auth = new OauthAuthenticator();
$auth = $authFactory->make('oauth');
} elseif (!empty($username) && !empty($password)) {
$auth = new PasswordAuthenticator();
$auth = $authFactory->make('password');
}

$client = new Client();
$this->workspace = new Workspaces($client, $username);

if (empty($auth)) {
$this->client = $client;
Expand All @@ -65,7 +76,7 @@ public function __construct($config)
*/
protected function validateConfig($config)
{
if (empty(array_get($config, 'vendor'))) {
if (empty(Arr::get($config, 'vendor'))) {
throw new InternalServerErrorException('No account/organization name provided for Bitbucket client.');
}
}
Expand All @@ -79,10 +90,9 @@ protected function validateConfig($config)
*/
public function repoAll($page = 1, $perPage = 50)
{
$repo = $this->client->repositories();

$pager = new ResultPager($this->client);
return $pager->fetchAll($repo->users($this->username), "list");
$repositories = $pager->fetchAll($this->workspace, "list");
return array_chunk($repositories, $perPage)[$page - 1];
}

/**
Expand All @@ -95,7 +105,7 @@ public function repoAll($page = 1, $perPage = 50)
*/
public function repoList($repo, $path = null, $ref = null)
{
$src = $this->client->repositories()->users($this->username)->src($repo);
$src = $this->workspace->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'
Expand All @@ -115,9 +125,9 @@ public function repoList($repo, $path = null, $ref = null)
*/
public function repoGetFileInfo($repo, $path, $ref = null)
{
$src = new CustomSrc($this->client->getHttpClient(), $this->username, $repo);
$src = new CustomSrc($this->client, $this->username, $repo);

$result = $src->listPath($ref, $path, ['format' => 'meta']);
$result = $src->show($ref, $path);
if ('commit_directory' === $result['type']) {
$pager = new ResultPager($this->client);
$params = [
Expand All @@ -143,9 +153,9 @@ public function repoGetFileInfo($repo, $path, $ref = null)
*/
public function repoGetFileContent($repo, $path, $ref = null)
{
$src = new CustomSrc($this->client->getHttpClient(), $this->username, $repo);
$src = new CustomSrc($this->client, $this->username, $repo);

$result = $src->listPath($ref, $path, ['format' => 'meta']);
$result = $src->show($ref, $path);

if ('commit_directory' === $result['type']) {
$pager = new ResultPager($this->client);
Expand Down Expand Up @@ -203,7 +213,7 @@ protected function cleanSrcList($list)
}

foreach ($files as $key => $file) {
$name = array_get($file, 'path');
$name = Arr::get($file, 'path');
$date = new \DateTime($file['commit']['date']);
$date->setTimeZone(new \DateTimeZone('UTC'));
$files[$key] = [
Expand All @@ -230,8 +240,8 @@ protected function cleanSrcList($list)
protected function cleanSrcData($data, $content)
{
$content = base64_encode($content);
$size = array_get($data, 'size');
$path = array_get($data, 'path');
$size = Arr::get($data, 'size');
$path = Arr::get($data, 'path');
$data = [
'node' => $data['commit']['hash'],
'path' => $path,
Expand Down
38 changes: 27 additions & 11 deletions src/Components/GitHubClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,26 @@
namespace DreamFactory\Core\Git\Components;

use Github\Client;
use Github\Api\User;
use DreamFactory\Core\Exceptions\InternalServerErrorException;
use DreamFactory\Core\Git\Contracts\ClientInterface;
use GrahamCampbell\GitHub\Authenticators\TokenAuthenticator;
use GrahamCampbell\GitHub\Authenticators\PasswordAuthenticator;
use GrahamCampbell\GitHub\Auth\AuthenticatorFactory;
use Illuminate\Support\Arr;

class GitHubUser extends User
{
public function repositories($username, $type = 'owner', $sort = 'full_name', $direction = 'asc', $visibility = 'all', $affiliation = 'owner,collaborator,organization_member', $extra = [])
{
$headers = array_merge([
'type' => $type,
'sort' => $sort,
'direction' => $direction,
'visibility' => $visibility,
'affiliation' => $affiliation
], $extra);
return $this->get('/users/'.rawurlencode($username).'/repos', $headers);
}
}

class GitHubClient implements ClientInterface
{
Expand All @@ -27,15 +43,15 @@ 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');
$username = Arr::get($config, 'username');
$password = Arr::get($config, 'password');
$token = Arr::get($config, 'token');

$authFactory = new AuthenticatorFactory();
$auth = null;

if (!empty($username) && !empty($token)) {
$auth = new TokenAuthenticator();
} elseif (!empty($username) && !empty($password)) {
$auth = new PasswordAuthenticator();
$auth = $authFactory->make('token');
}

if (empty($auth)) {
Expand All @@ -52,7 +68,7 @@ public function __construct($config)
*/
protected function validateConfig($config)
{
if (empty(array_get($config, 'vendor'))) {
if (empty(Arr::get($config, 'vendor'))) {
throw new InternalServerErrorException('No account/organization name provided for GitHub client.');
}
}
Expand All @@ -75,12 +91,12 @@ public function repoList($repo, $path = null, $ref = null)
/** {@inheritdoc} */
public function repoGetFileInfo($repo, $path, $ref = null)
{
return $this->repoList($repo, $path, $ref);
return $this->repoList($repo, rtrim($path, '/'), $ref);
}

/** {@inheritdoc} */
public function repoGetFileContent($repo, $path, $ref = null)
{
return $this->client->repo()->contents()->download($this->username, $repo, $path, $ref);
return $this->client->repo()->contents()->download($this->username, $repo, rtrim($path, '/'), $ref);
}
}
19 changes: 0 additions & 19 deletions src/Components/GitHubUser.php

This file was deleted.

22 changes: 12 additions & 10 deletions src/Components/GitLabClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

use DreamFactory\Core\Exceptions\InternalServerErrorException;
use DreamFactory\Core\Git\Contracts\ClientInterface;
use GrahamCampbell\GitLab\Authenticators\GitLabAuthenticator;
use GrahamCampbell\GitLab\Auth\AuthenticatorFactory;
use Gitlab\Client;
use Gitlab\Api\Users;
use Illuminate\Support\Arr;

class CustomUsers extends Users
{
Expand Down Expand Up @@ -43,14 +44,16 @@ public function __construct($config)
{
$this->validateConfig($config);
$client = new Client();
$auth = new GitLabAuthenticator('http_token');

$authFactory = new AuthenticatorFactory();
$auth = $authFactory->make('token');

$this->client = $auth->with($client)->authenticate($config);
$this->client->setUrl(array_get($config, 'base_url'));
$this->client->setUrl(Arr::get($config, 'base_url'));

$namespace = array_get($config, 'namespace');
$namespace = Arr::get($config, 'namespace');
if (empty($namespace)) {
$userInfo = $this->client->api('users')->me();
$userInfo = $this->client->users()->me();
if (empty($userInfo) || !isset($userInfo['username'])) {
throw new InternalServerErrorException('No authenticated user found for GitLab client. Please check GitLab service configuration.');
}
Expand All @@ -76,18 +79,18 @@ protected function getProjectId($name)
*/
protected function validateConfig($config)
{
if (empty(array_get($config, 'base_url'))) {
if (empty(Arr::get($config, 'base_url'))) {
throw new InternalServerErrorException('No base url provided for GitLab client.');
}
if (empty(array_get($config, 'token'))) {
if (empty(Arr::get($config, 'token'))) {
throw new InternalServerErrorException('No token provided for GitLab client.');
}
}

/** {@inheritdoc} */
public function repoAll($page = 1, $perPage = 50)
{
$username = $this->client->api('users')->me()['username'];
$username = $this->client->users()->me()['username'];
$params = ['page' => (int)$page, 'per_page' => (int)$perPage];

if ($username !== $this->namespace) {
Expand All @@ -111,9 +114,8 @@ public function repoGetFileInfo($repo, $path = null, $ref = null)
{
$result = $this->repoList($repo, $path, $ref);
if (0 === count($result)) {
$result = $this->client->repositories()->getFile($this->getProjectId($repo), $path, $ref);
$result = $this->client->repositoryFiles()->getFile($this->getProjectId($repo), $path, $ref);
$result['path'] = $result['file_path'];

}

return $result;
Expand Down
5 changes: 4 additions & 1 deletion src/Models/GitHubConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class GitHubConfig extends BaseServiceConfigModel
/** @var array */
protected $protected = ['token', 'password'];

/** @var array */
protected $rules = ['token' => 'required'];

/**
* {@inheritdoc}
*/
Expand All @@ -48,7 +51,7 @@ protected static function prepareConfigSchemaField(array &$schema)
case 'password':
$schema['type'] = 'password';
$schema['label'] = 'Password';
$schema['description'] = 'Your GitHub password goes here.';
$schema['description'] = 'WARNING Password authentication is not supported. Please use a personal access token.';
break;
case 'token':
$schema['label'] = 'GitHub Token';
Expand Down
6 changes: 4 additions & 2 deletions src/Resources/BaseResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use DreamFactory\Core\Enums\ApiOptions;
use DreamFactory\Core\Utility\ResourcesWrapper;
use Github\Exception\RuntimeException;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class BaseResource extends BaseRestResource
{
Expand Down Expand Up @@ -37,7 +39,7 @@ protected function handleGET()
$perPage = $this->request->getParameter('per_page', 50);

$resourceArray = $this->resourceArray;
$repo = array_get($resourceArray, 0);
$repo = Arr::get($resourceArray, 0);

try {
if (empty($repo)) {
Expand Down Expand Up @@ -74,7 +76,7 @@ protected function handleGET()
protected function getApiDocPaths()
{
$service = $this->getServiceName();
$capitalized = camelize($service);
$capitalized = Str::camel($service);
$resourceName = strtolower($this->name);
$path = '/' . $resourceName;

Expand Down
3 changes: 2 additions & 1 deletion src/Services/BaseService.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use DreamFactory\Core\Exceptions\InternalServerErrorException;
use DreamFactory\Core\Services\BaseRestService;
use DreamFactory\Core\Utility\Session;
use Illuminate\Support\Arr;

abstract class BaseService extends BaseRestService
{
Expand All @@ -15,7 +16,7 @@ public function __construct(array $settings)
{
parent::__construct($settings);

$config = array_get($settings, 'config');
$config = Arr::get($settings, 'config');
Session::replaceLookups($config, true);

if (empty($config)) {
Expand Down

0 comments on commit 710dc03

Please sign in to comment.