cybercog/youtrack-rest-php

Refactor authorizers

Closed this issue · 4 comments

Goals

  • Tell Authorizers what to do, and don't ask them.
  • Remove authenticate method from Authorizer contract (not it's responsibility).
  • Delegate authentication process to Authenticators.
  • Create factory for Authorizer building since this process is more complicated.

New API proposals will be described below.

Version 1

Token Authorization

use Cog\YouTrack\Rest;

$http = new \GuzzleHttp\Client([
    'base_uri' => 'https://example.com',
]);

$authorizer = new Rest\Authorizer\TokenAuthorizer('YOUTRACK_API_TOKEN');

$client = new Rest\Client\YouTrackClient($http, $authorizer);

Cookie Authorization

use Cog\YouTrack\Rest;

$http = new \GuzzleHttp\Client([
    'base_uri' => $apiBaseUri,
]);

$authenticator = new Rest\Authenticator\CookieAuthenticator(
    'YOUTRACK_USERNAME', 'YOUTRACK_PASSWORD'
);

$authorizer = new Rest\Authorizer\CookieAuthorizer($authenticator);

$client = new Rest\Client\YouTrackClient($http, $authorizer);

Container Binding

$this->app->bind(YouTrackClientContract::class, function () {
    $config = $this->app->make('config');

    $http = new Client([
        'base_uri' => $config->get('youtrack.base_uri'),
    ]);

    $options = $config->get('youtrack.authorizers.' . $config->get('youtrack.authorizer'));
    if ($options['driver'] == 'token') {
        $authorizer = new $options['driver']($options['token']);
    } elseif ($options['driver'] == 'cookie') {
        $authenticator = new \Cog\YouTrack\Rest\Authenticator\CookieAuthenticator(
            $options['username'],
            $options['password']
        );
        $authorizer = new $options['driver']($authenticator);
    } elseif (class_exists($options['driver']) {
        $authorizer = new $options['driver']($options);
    } else {
        $authorizer = new \Cog\YouTrack\Rest\Authorizer\NullAuthorizer();
    }

    return new YouTrackClient($http, $authorizer);
});

Version 2

Token Authorization

use Cog\YouTrack\Rest;

$http = new \GuzzleHttp\Client([
    'base_uri' => 'https://example.com',
]);

$authorizer = new Rest\Authorizer\TokenAuthorizer([
    'token' => 'YOUTRACK_API_TOKEN',
]);

$client = new Rest\Client\YouTrackClient($http, $authorizer);

Cookie Authorization

use Cog\YouTrack\Rest;

$http = new \GuzzleHttp\Client([
    'base_uri' => $apiBaseUri,
]);

$authenticator = new Rest\Authenticator\CookieAuthenticator([
    'username' => 'YOUTRACK_USERNAME',
    'password' => 'YOUTRACK_PASSWORD',
]);

$authorizer = new Rest\Authorizer\CookieAuthorizer($authenticator);

$client = new Rest\Client\YouTrackClient($http, $authorizer);

Container Binding

$this->app->bind(YouTrackClientContract::class, function () {
    $config = $this->app->make('config');

    $http = new Client([
        'base_uri' => $config->get('youtrack.base_uri'),
    ]);

    $authorizerName = $config->get('youtrack.authorizer');

    $options = $config->get('youtrack.authorizers.' . $authorizerName);
    if ($authorizerName == 'cookie') {
        $authenticator = new \Cog\YouTrack\Rest\Authenticator\CookieAuthenticator($options);
        $authorizer = new $options['driver']($authenticator);
    } else {
        $authorizer = new $options['driver']($options);
    }

    return new YouTrackClient($http, $authorizer);
});

Because now we can't instantiate authorizer without conditional checks there is not much benefit from passing options as array. But we definitely require factory for building Authorizers and have an ability to define own factories within application.

Version 1 was implemented.