-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new bindings to register access for the S3-compatible gateway and to construct a linksharing URL. The RegisterAccess happy flow isn't currently run in CI because there is no auth service in storj-sim. Solves #37
- Loading branch information
Showing
16 changed files
with
368 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
namespace Storj\Uplink\Edge; | ||
|
||
use FFI; | ||
use Storj\Uplink\Internal\Scope; | ||
use Storj\Uplink\Internal\Util; | ||
|
||
/** | ||
* Parameters when connecting to edge services | ||
*/ | ||
class Config | ||
{ | ||
/** | ||
* DRPC server e.g. auth.storjshare.io:7777. | ||
* Currently mandatory to set this manually. | ||
*/ | ||
private string $authServiceAddress = ""; | ||
|
||
/** | ||
* Root certificate(s) or chain(s) against which Uplink checks the auth service. | ||
* In PEM format. | ||
* Intended to test against a self-hosted auth service or to improve security. | ||
*/ | ||
private string $certificatePem = ""; | ||
|
||
public function withAuthServiceAddress(string $authServiceAddress): self | ||
{ | ||
$self = clone $this; | ||
$self->authServiceAddress = $authServiceAddress; | ||
return $self; | ||
} | ||
|
||
public function withCertificatePem(string $certificatePem): self | ||
{ | ||
$self = clone $this; | ||
$self->certificatePem = $certificatePem; | ||
return $self; | ||
} | ||
|
||
public function getAuthServiceAddress(): string | ||
{ | ||
return $this->authServiceAddress; | ||
} | ||
|
||
public function getCertificatePem(): string | ||
{ | ||
return $this->certificatePem; | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
public function toCStruct(FFI $ffi, Scope $scope): FFI\CData | ||
{ | ||
$cAuthServiceAddress = Util::createCString($this->authServiceAddress, $scope); | ||
$cCertificatePem = Util::createCString($this->certificatePem, $scope); | ||
|
||
$cConfig = $ffi->new('EdgeConfig'); | ||
$cConfig->auth_service_address = $cAuthServiceAddress; | ||
$cConfig->certificate_pem = $cCertificatePem; | ||
|
||
return $cConfig; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
namespace Storj\Uplink\Edge; | ||
|
||
/** | ||
* Gateway credentials in S3 format | ||
*/ | ||
class Credentials | ||
{ | ||
/** | ||
* Is also used in the linksharing url path | ||
*/ | ||
private string $accessKeyId; | ||
|
||
private string $secretKey; | ||
|
||
/** | ||
* Base HTTP(S) URL to the gateway | ||
*/ | ||
private string $endpoint; | ||
|
||
public function __construct( | ||
string $accessKeyId, | ||
string $secretKey, | ||
string $endpoint | ||
) { | ||
$this->accessKeyId = $accessKeyId; | ||
$this->secretKey = $secretKey; | ||
$this->endpoint = $endpoint; | ||
} | ||
|
||
public function getAccessKeyId(): string | ||
{ | ||
return $this->accessKeyId; | ||
} | ||
|
||
public function getSecretKey(): string | ||
{ | ||
return $this->secretKey; | ||
} | ||
|
||
public function getEndpoint(): string | ||
{ | ||
return $this->endpoint; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
|
||
namespace Storj\Uplink\Edge; | ||
|
||
use FFI; | ||
use Storj\Uplink\Access; | ||
use Storj\Uplink\Exception\Edge\DialFailed; | ||
use Storj\Uplink\Exception\Edge\RegisterAccessFailed; | ||
use Storj\Uplink\Internal\Scope; | ||
use Storj\Uplink\Internal\Util; | ||
|
||
class Edge | ||
{ | ||
/** | ||
* With libuplink.so and header files loaded | ||
*/ | ||
private FFI $ffi; | ||
|
||
public function __construct(FFI $ffi) | ||
{ | ||
$this->ffi = $ffi; | ||
} | ||
|
||
/** | ||
* @throws \Storj\Uplink\Exception\UplinkException | ||
*/ | ||
public function registerAccess( | ||
Config $config, | ||
Access $access, | ||
bool $isPublic = false | ||
): Credentials | ||
{ | ||
$scope = new Scope(); | ||
|
||
$cOptions = $this->ffi->new('EdgeRegisterAccessOptions'); | ||
$cOptions->is_public = $isPublic; | ||
|
||
$cCredentialsResult = $this->ffi->edge_register_access( | ||
$config->toCStruct($this->ffi, $scope), | ||
$access->getNativeAccess(), | ||
FFI::addr($cOptions), | ||
); | ||
|
||
$scope->onExit( | ||
fn() => $this->ffi->edge_free_credentials_result($cCredentialsResult) | ||
); | ||
|
||
Util::throwIfErrorResult($cCredentialsResult); | ||
|
||
$cCredentials = $cCredentialsResult->credentials; | ||
|
||
return new Credentials( | ||
FFI::string($cCredentials->access_key_id), | ||
FFI::string($cCredentials->secret_key), | ||
FFI::string($cCredentials->endpoint), | ||
); | ||
} | ||
|
||
/** | ||
* JoinShareURL creates a linksharing URL from parts. | ||
* The existence or accessibility of the target is not checked, it might not exist or be inaccessible. | ||
* | ||
* @param string $baseUrl Linksharing service, e.g. https://link.storjshare.io | ||
* @param string $accessKeyId Can be obtained by calling RegisterAccess. It must be associated with public visibility. | ||
* @param string $bucket Optional, leave it blank to share the entire project. | ||
* @param string $key Optional, if empty shares the entire bucket. It can also be a prefix, in which case it must end with a "/". | ||
* @param bool $raw Whether to get a direct link to the data instead of a landing page | ||
* | ||
* @return string example https://link.storjshare.io/s/l5pucy3dmvzxgs3fpfewix27l5pq/mybucket/myprefix/myobject | ||
* | ||
* @throws DialFailed in case of network errors | ||
* @throws RegisterAccessFailed in case of server errors | ||
*/ | ||
public function joinShareUrl( | ||
string $baseUrl, | ||
string $accessKeyId, | ||
string $bucket = "", | ||
string $key = "", | ||
bool $raw = false | ||
): string | ||
{ | ||
$cOptions = $this->ffi->new('EdgeShareURLOptions'); | ||
$cOptions->raw = $raw; | ||
|
||
$scope = new Scope(); | ||
$cStringResult = $this->ffi->edge_join_share_url( | ||
$baseUrl, | ||
$accessKeyId, | ||
$bucket, | ||
$key, | ||
FFI::addr($cOptions) | ||
); | ||
|
||
$scope->onExit( | ||
fn() => $this->ffi->uplink_free_string_result($cStringResult) | ||
); | ||
|
||
Util::throwIfErrorResult($cStringResult); | ||
|
||
return FFI::string($cStringResult->string); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace Storj\Uplink\Exception\Edge; | ||
|
||
|
||
class DialFailed extends EdgeException | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
namespace Storj\Uplink\Exception\Edge; | ||
|
||
use Storj\Uplink\Exception\UplinkException; | ||
|
||
abstract class EdgeException extends UplinkException | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
namespace Storj\Uplink\Exception\Edge; | ||
|
||
use Storj\Uplink\Exception\UplinkException; | ||
|
||
class RegisterAccessFailed extends EdgeException | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
namespace Storj\Uplink\Test\Edge; | ||
|
||
use DateInterval; | ||
use DateTimeImmutable; | ||
use PHPUnit\Framework\TestCase; | ||
use Storj\Uplink\Edge\Config; | ||
use Storj\Uplink\Edge\Edge; | ||
use Storj\Uplink\Exception\Edge\DialFailed; | ||
use Storj\Uplink\Permission; | ||
use Storj\Uplink\Test\Util; | ||
|
||
class RegisterAccessTest extends TestCase | ||
{ | ||
public function testRegisterAccessHappyFlow(): void | ||
{ | ||
$authService = getenv('AUTH_SERVICE_ADDRESS'); | ||
if (!$authService) { | ||
$this->markTestSkipped('No auth service address set'); | ||
} | ||
|
||
$edgeConfig = (new Config())->withAuthServiceAddress($authService); | ||
$edge = Util::uplink()->edgeServices(); | ||
|
||
// set expiry so we don't pollute the Auth service prod datebase when running tests against prod | ||
$tomorrow = (new DateTimeImmutable())->add(new DateInterval('P1D')); | ||
$access = Util::access()->share( | ||
Permission::readOnlyPermission() | ||
->notAfter($tomorrow) | ||
); | ||
|
||
$credentials = $edge->registerAccess($edgeConfig, $access); | ||
|
||
// just to check it isn't empty or garbage | ||
self::assertMatchesRegularExpression('~\w{10,200}~', $credentials->getAccessKeyId()); | ||
self::assertMatchesRegularExpression('~\w{10,200}~', $credentials->getSecretKey()); | ||
self::assertMatchesRegularExpression('~https://[\w.]{10,200}~', $credentials->getEndpoint()); | ||
} | ||
|
||
public function testRegisterAccessInvalidAddress(): void | ||
{ | ||
// No DRPC auth service is running at this address. | ||
$edgeConfig = (new Config())->withAuthServiceAddress('storj.io:33463'); | ||
$uplink = Util::uplink(); | ||
$edge = $uplink->edgeServices(); | ||
|
||
$this->expectException(DialFailed::class); | ||
$edge->registerAccess($edgeConfig, Util::access()); | ||
} | ||
} |
Oops, something went wrong.