Skip to content

Commit

Permalink
authentication logic start prep; cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
donwilson committed Nov 9, 2023
1 parent 72f8691 commit a62760d
Show file tree
Hide file tree
Showing 11 changed files with 354 additions and 2 deletions.
136 changes: 136 additions & 0 deletions src/Magnetar/Auth/AuthManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php
declare(strict_types=1);

namespace Magnetar\Auth;

use Exception;

use Magnetar\Application;
use Magnetar\Auth\AuthenticationAdapter;

/**
* Authentication manager
*
* @see AuthenticationAdapter
*/
class AuthManager {
/**
* Array of authentication adapter instances
* @var array<string, AuthenticationAdapter>
*/
protected array $connections = [];

/**
* Array of authentication adapter classes
* @var array
*/
protected array $adapters = [
//'oauth' => OAuth\AuthenticationAdapter::class,
'session' => Session\AuthenticationAdapter::class,
'cookie' => Cookie\AuthenticationAdapter::class,
//'api' => API\AuthenticationAdapter::class,
];

/**
* Constructor
*/
public function __construct(
/**
* The application instance
* @var Application
*/
protected Application $app
) {

}

/**
* Returns the active authentication adapter for the specified driver
* @param string|null $connection_name Connection name from the auth config file. If no connection name is specified, the default connection is used
* @return AuthenticationAdapter
*
* @throws Exception
*/
public function connection(string|null $connection_name=null): AuthenticationAdapter {
// interfaces with the app's configuration to create an authentication connection
if(null === $connection_name) {
$connection_name = $this->getDefaultConnectionName() ?? throw new Exception('No default authentication connection specified');
}

if(!isset($this->connections[ $connection_name ])) {
$this->makeConnection($connection_name);
}

return $this->connections[ $connection_name ];
}

/**
* Creates a new authentication connection
* @param string $connection_name Connection name
* @return void
*
* @throws Exception
*/
protected function makeConnection(string $connection_name): void {
if(null === ($adapter_name = $this->getAdapterNameFromConnectionName($connection_name))) {
throw new Exception('Authentication driver not specified for connection');
}

if(null === ($adapter_class = $this->adapters[ $adapter_name ] ?? null)) {
throw new Exception('Invalid authentication driver');
}

$this->connections[ $connection_name ] = new $adapter_class(
$connection_name,
$this->app['config']->get('auth.connections.'. $connection_name, [])
) ?? throw new Exception('Unable to start authentication driver');
}

/**
* Get the authentication adapter from the connection name. Returns null if the adapter cannot be determined from configuration
* @param string $connection_name Connection name from the auth config file
* @return string|null
*/
protected function getAdapterNameFromConnectionName(string $connection_name): string|null {
return $this->app['config']->get('auth.connections.'. $connection_name .'.adapter', null);
}

/**
* Returns the default authentication connection name
* @return string|null
*/
public function getDefaultConnectionName(): string|null {
return $this->app['config']->get('auth.default', null);
}

/**
* Returns an array of driver names that have been connected to
* @return array
*/
public function getConnected(): array {
return array_keys($this->connections);
}

/**
* Returns the authentication adapter for the specified driver
* @param string $connection_name
* @return AuthenticationAdapter
*
* @throws Exception
*/
public function adapter(string $connection_name): AuthenticationAdapter {
return $this->connections[ $connection_name ] ?? throw new Exception('Specified authentication driver is not connected');
}

/**
* Passes method calls to the default authentication adapter
* @param string $method
* @param array $args
* @return mixed
*
* @see AuthenticationAdapter
*/
public function __call(string $method, array $args): mixed {
return $this->connection()->$method(...$args);
}
}
30 changes: 30 additions & 0 deletions src/Magnetar/Auth/AuthServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);

namespace Magnetar\Auth;

use Magnetar\Helpers\ServiceProvider;
use Magnetar\Helpers\DeferrableServiceInterface;
use Magnetar\Auth\AuthManager;

/**
* Auth service provider
*/
class AuthServiceProvider extends ServiceProvider implements DeferrableServiceInterface {
/**
* {@inheritDoc}
*/
public function register(): void {
// register connection services
$this->app->singleton('auth', fn ($app) => new AuthManager($app));
}

/**
* {@inheritDoc}
*/
public function provides(): array {
return [
AuthManager::class,
];
}
}
109 changes: 109 additions & 0 deletions src/Magnetar/Auth/AuthenticationAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
declare(strict_types=1);

namespace Magnetar\Auth;

use Magnetar\Auth\Exceptions\AuthenticationAdapterException;

class AuthenticationAdapter {
/**
* Name of the adapter
*/
const ADAPTER_NAME = '';

/**
* Whether or not the adapter has been initialized. Prevents certain methods from being called after initialization
* @var bool
*/
protected bool $initialized = false;

/**
* Namespace path to class for model to use for authentication
* @var string|null
*/
protected string|null $model_class=null;

/**
* Constructor
*/
public function __construct(
protected string $connection_name,
protected array $connection_config = []
) {
$this->initialize();
}

/**
* Initialize the adapter
* @return void
*/
protected function initialize(): void {
if($this->initialized) {
return;
}

// set the initialized flag
$this->initialized = true;

// pull the configuration and check if it is valid
$this->validateRuntime();

// create the connection
$this->createConnection();

// run any post connection actions
$this->postConnection();
}

/**
* Validate runtime configuration
* @return void
*
* @throws RuntimeException
* @throws AuthenticationAdapterException
*/
protected function validateRuntime(): void {
// individual adapters are encouraged to override this method
}

/**
* Create the connection to the adapter using the configuration
* @return void
*
* @throws RuntimeException
* @throws AuthenticationAdapterException
*/
protected function createConnection(): void {
// individual adapters must override this method
throw new AuthenticationAdapterException('Authentication adapter needs to override the createConnection method.');
}

/**
* Post connection actions
* @return void
*/
protected function postConnection(): void {
// individual adapters may override this method
}

/**
* Get the adapter name
* @return string The name of the adapter
*/
public function getAdapterName(): string {
return self::ADAPTER_NAME;
}

/**
* Set the model class to use for authentication
* @param string $model_class
* @return void
*/
public function setModelClass(string $model_class): void {
if($this->initialized) {
throw new Exceptions\AlreadyInitializedException('Cannot set model class after initialization');
}

$this->model_class = $model_class;
}
}
13 changes: 13 additions & 0 deletions src/Magnetar/Auth/Cookie/AuthenticationAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace Magnetar\Auth\Cookie;

use Magnetar\Auth\AuthenticationAdapter as BaseAuthenticationAdapter;
use Magnetar\Auth\Exceptions\AuthenticationAdapterException;

class AuthenticationAdapter extends BaseAuthenticationAdapter {



}
13 changes: 13 additions & 0 deletions src/Magnetar/Auth/Exceptions/AlreadyInitializedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace Magnetar\Auth\Exceptions;

use Exception;

/**
* Exception thrown when certain methods are called after authentication adapter initialization
*/
class AlreadyInitializedException extends Exception {

}
13 changes: 13 additions & 0 deletions src/Magnetar/Auth/Exceptions/AuthenticationAdapterException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace Magnetar\Auth\Exceptions;

use Exception;

/**
* Exception thrown when an authentication adapter error occurs
*/
class AuthenticationAdapterException extends Exception {

}
13 changes: 13 additions & 0 deletions src/Magnetar/Auth/Session/AuthenticationAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace Magnetar\Auth\Session;

use Magnetar\Auth\AuthenticationAdapter as BaseAuthenticationAdapter;
use Magnetar\Auth\Exceptions\AuthenticationAdapterException;

class AuthenticationAdapter extends BaseAuthenticationAdapter {



}
2 changes: 1 addition & 1 deletion src/Magnetar/Database/ConnectionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ConnectionManager {
];

/**
* ConnectionManager constructor
* Constructor
*/
public function __construct(
/**
Expand Down
2 changes: 1 addition & 1 deletion src/Magnetar/Database/DatabaseServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function register(): void {
*/
public function provides(): array {
return [
ConnectionManager::class
ConnectionManager::class,
];
}
}
24 changes: 24 additions & 0 deletions src/Magnetar/Helpers/Facades/Auth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);

namespace Magnetar\Helpers\Facades;

use Magnetar\Helpers\Facades\Facade;

/**
* @method connection(?string $connection_name=null): Magnetar\Auth\AuthenticationAdapter
* @method getDefaultConnectionName(): ?string
* @method getConnected(): array
* @method adapter(string $connection_name): Magnetar\Auth\AuthenticationAdapter
*
* @see Magnetar\Auth\AuthManager
*/
class Auth extends Facade {
/**
* Get the named key that this facade represents
* @return string
*/
protected static function getFacadeKey(): string {
return 'auth';
}
}
1 change: 1 addition & 0 deletions src/Magnetar/Helpers/Facades/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* @method assignOverrideParameters(array $parameters): void
* @method parameter(string $name, mixed $default=null): mixed
* @method get(string $name, mixed $default=null): mixed
* @method isset(string $name): bool
* @method parameters(): array
* @method body(): string
* @method file(string $input_name): Magnetar\Http\UploadedFile|array|null
Expand Down

0 comments on commit a62760d

Please sign in to comment.