diff --git a/.github/workflows/actions.yaml b/.github/workflows/actions.yaml new file mode 100644 index 0000000..4ceccc7 --- /dev/null +++ b/.github/workflows/actions.yaml @@ -0,0 +1,48 @@ +name: PHP Pipeline + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + lint: + name: PHP Lint + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: PHP Lint + run: php -l src/ + + phpstan: + name: PHPStan + runs-on: ubuntu-latest + needs: lint + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-scripts --no-progress --no-suggest + + - name: Run PHPStan + run: composer verify-code + + cs-fixer: + name: PHP CS Fixer + runs-on: ubuntu-latest + needs: phpstan + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-scripts --no-progress --no-suggest + + - name: Run PHP CS Fixer + run: vendor/bin/php-cs-fixer fix --dry-run --diff src diff --git a/.gitignore b/.gitignore index f196cdb..7d5d911 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ vendor/* .php_cs-fixer.cache .phpstan.cache/ -var/ \ No newline at end of file +var/ +composer.lock +.php-cs-fixer.cache +phpstan.neon diff --git a/README.md b/README.md index 78ed134..85e64f0 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ $fileContent = $client->download([ // Delete a file from a bucket. Returns true or false. $fileDelete = $client->deleteFileFromArray([ 'FileId' => $file->getId() - + // Can also identify the file via bucket and path: // 'BucketName' => 'my-special-bucket', // 'FileName' => 'path/to/file' @@ -84,7 +84,7 @@ $fileList = $client->listFilesFromArray([ 'BucketId' => '4d2dbbe08e1e983c5e6f0d12' ]); -// Create a new access key +// Create a new access key. $capabilities = new Capabilities() $key = $client->createKey($accountId, $name, new Capabilities( [Capabilities::DELETE_BUCKETS, @@ -93,7 +93,14 @@ $key = $client->createKey($accountId, $name, new Capabilities( )); $keyId = $key->getKeyId(); -$applicationKetId = $key->getApplicationKey(); +$applicationKeyId = $key->getApplicationKey(); + +// Delete an existing access key. +try { + $client->deleteKey($keyId); +} catch (RequestException $e) { + // $e->getCode() +} ``` ## Installation diff --git a/src/Client.php b/src/Client.php index 3dbc70f..fa06b60 100644 --- a/src/Client.php +++ b/src/Client.php @@ -2,6 +2,7 @@ namespace obregonco\B2; +use GuzzleHttp\Exception\RequestException; use Illuminate\Cache\CacheManager; use Illuminate\Container\Container; use Illuminate\Filesystem\Filesystem; @@ -354,7 +355,7 @@ public function listFilesFromArray(array $options): array // B2 returns, at most, 1000 files per "page". Loop through the pages and compile an array of File objects. while (true) { - $response = $this->request('POST', '/b2_list_file_names', [ + $response = $this->request('POST', '/b2_list_file_versions', [ 'json' => [ 'bucketId' => $options['BucketId'], 'prefix' => $prefix, @@ -405,7 +406,7 @@ public function listFiles( if (!empty($delimiter)) { $params['delimiter'] = $delimiter; } - $response = $this->request('POST', '/b2_list_file_names', [ + $response = $this->request('POST', '/b2_list_file_versions', [ 'json' => $params, ]); @@ -859,6 +860,47 @@ public function createKey(string $name, Capabilities $capabilities, string $buck ); } + /** + * Deletes the key having the provided $id from Backblaze. + * + * @throws RequestException + * @throws \InvalidArgumentException + */ + public function deleteKey(string $id): void + { + if (empty($id)) { + throw new \InvalidArgumentException('The key ID is empty.'); + } + + $json = [ + 'applicationKeyId' => $id, + ]; + + $this->request('POST', '/b2_delete_key', [ + 'json' => $json, + true + ]); + } + + /** + * @throws \RuntimeException + */ + public function retrieveKeys(): array + { + $json = [ + 'accountId' => $this->accountId, + 'maxKeyCount' => 10000 + ]; + + /** @var array */ + $response = $this->request('POST', '/b2_list_keys', [ + "json" => $json, + true + ]); + + return $response['keys']; + } + /** * Authorize the B2 account in order to get an auth token and API/download URLs. */ diff --git a/src/File.php b/src/File.php index abe7c07..2aa359e 100644 --- a/src/File.php +++ b/src/File.php @@ -109,7 +109,7 @@ public function getUploadTimestamp() /** * @return array */ - public function jsonSerialize():mixed + public function jsonSerialize(): mixed { return $this->asArray(); } diff --git a/src/Http/Client.php b/src/Http/Client.php index a17ea3c..23b49d5 100644 --- a/src/Http/Client.php +++ b/src/Http/Client.php @@ -9,6 +9,8 @@ /** * Client wrapper around Guzzle. */ +// FIXME: Class obregonco\B2\Http\Client extends @final class GuzzleHttp\Client. +// @phpstan-ignore-next-line class Client extends GuzzleClient { public $retryLimit = 10; @@ -21,6 +23,9 @@ class Client extends GuzzleClient * * @return mixed|string */ + // FIXME: PHPDoc tag @return with type mixed is not subtype of native type Psr\Http\Message\ResponseInterface. + // FIXME: Default value of the parameter #2 $uri (string) of method obregonco\B2\Http\Client::request() is incompatible with type null. + // @phpstan-ignore-next-line public function request(string $method, $uri = '', array $options = []): ResponseInterface { $response = parent::request($method, $uri, $options);