Skip to content

Commit

Permalink
Add Custom User Provider (#9)
Browse files Browse the repository at this point in the history
- Adds a new CoilpackUserProvider callback to Laravel's Authentication Provider.
- Respects the Member model (default Coilpack Member model or one added in the config)
- Uses EE's native authentication functions to create the session

---------

Co-authored-by: Stephen Galbraith <[email protected]>
  • Loading branch information
bryannielsen and nerdgency authored Mar 13, 2024
1 parent 5faebd6 commit 99ede38
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Ability to pass a 'tagdata' parameter to the ExpressionEngine Template library
- Support for the Member fieldtype introduced in ExpressionEngine 7.4
- A custom user provider to enable the `coilpack` guard to be used for logging in ExpressionEngine members through Laravel's authentication manager.

### Fixed

Expand Down
89 changes: 89 additions & 0 deletions src/Auth/CoilpackUserProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

namespace Expressionengine\Coilpack\Auth;

use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Auth\Authenticatable;

class CoilpackUserProvider extends EloquentUserProvider
{
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
$key = array_key_exists('username', $credentials) ? 'username' : 'email';
$value = $credentials[$key];

return $this->newModelQuery()
->where('username', $value)
->when(strpos($value, '@'), function ($query) use ($value) {
$query->orWhere('email', $value);
})
->first();
}

/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
ee()->load->library('auth');

$result = false;

if (array_key_exists('username', $credentials)) {
$result = ee()->auth->authenticate_username($credentials['username'], $credentials['password']);
} elseif (array_key_exists('email', $credentials)) {
$result = ee()->auth->authenticate_email($credentials['email'], $credentials['password']);
}

if (! $result) {
return false;
}

$result->start_session();

return $result !== false;
}

/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
if (! ee()->remember->exists()) {
return null;
}

$model = $this->createModel();

return $this->newModelQuery($model)->where(
$model->getAuthIdentifierName(),
ee()->remember->data('member_id')
)->first();
}

/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
ee()->remember->exists() ? ee()->remember->refresh() : ee()->remember->create();
}
}
12 changes: 12 additions & 0 deletions src/Auth/SessionGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ public function user()
return $this->user;
}


/**
* Remove the user data from the session and cookies.
*
* @return void
*/
protected function clearUserDataFromStorage()
{
$this->session->remove($this->getName());
ee()->session->destroy();
}

/**
* Get a unique identifier for the auth session value.
*
Expand Down
18 changes: 14 additions & 4 deletions src/Bootstrap/ConfigureAuthProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,27 @@ public function bootstrap(Application $app)
$session->start(); // This is usually handled in middleware
$provider = $app->make('auth')->createUserProvider($config['provider'] ?? null);

return new \Expressionengine\Coilpack\Auth\SessionGuard($name, $provider, $session);
$guard = new \Expressionengine\Coilpack\Auth\SessionGuard($name, $provider, $session);
$guard->setCookieJar($app['cookie']);

return $guard;
});

app('auth')->provider('coilpack', function ($app, array $config) {
return new \Expressionengine\Coilpack\Auth\CoilpackUserProvider(
$app['hash'],
$config['model']
);
});

// Configure our 'coilpack' guard which uses the 'members' provider below
app('config')->set('auth.guards.coilpack', [
'driver' => 'exp_sessions',
'provider' => 'members',
'provider' => 'coilpack',
]);

app('config')->set('auth.providers.members', [
'driver' => 'eloquent',
app('config')->set('auth.providers.coilpack', [
'driver' => 'coilpack',
'model' => $this->getMemberModel(),
]);

Expand Down
1 change: 1 addition & 0 deletions src/CoilpackServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Expressionengine\Coilpack;

use Expressionengine\Coilpack\Auth\CoilpackUserProvider;
use Expressionengine\Coilpack\Api\Graph\Support\FieldtypeRegistrar;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Event;
Expand Down
6 changes: 4 additions & 2 deletions src/Models/Member/Member.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
use Expressionengine\Coilpack\Models\FieldContent;
use Expressionengine\Coilpack\Models\Permission\Permission;
use Expressionengine\Coilpack\Models\Role;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Foundation\Auth\Access\Authorizable;

/**
Expand All @@ -18,9 +20,9 @@
* provided by the Member module. This is a single user of
* the website.
*/
class Member extends Model implements AuthorizableContract
class Member extends Model implements AuthorizableContract, AuthenticatableContract
{
use Authorizable;
use Authorizable, Authenticatable;

protected $primaryKey = 'member_id';

Expand Down

0 comments on commit 99ede38

Please sign in to comment.