Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use App;
use Config;
use Laravel\Passport\Passport;
use LukeTowers\Passport\Classes\Authenticate;
use System\Classes\PluginBase;
use Illuminate\Foundation\AliasLoader;

Expand All @@ -11,6 +12,10 @@
*/
class Plugin extends PluginBase
{
public $middlewareAliases = [
'auth' => Authenticate::class
];

/**
* Returns information about this plugin.
*
Expand All @@ -27,11 +32,29 @@ public function pluginDetails()
];
}

public function registerSettings()
{
return [
'settings' => [
'label' => 'Passport Settings',
'description' => 'Manage passport based settings.',
'category' => 'Passport',
'icon' => 'icon-cog',
'class' => 'LukeTowers\Passport\Models\Settings',
'order' => 500,
'keywords' => 'user auth passport'
]
];
}

/**
* Runs right before the request route
*/
public function boot()
{
// Boot middleware aliases
$this->aliasMiddleware();

// Disable the Laravel migrations from Passport, handled via plugin updates
Passport::ignoreMigrations();

Expand Down Expand Up @@ -81,4 +104,18 @@ public function bootPackages()
}
}
}

/**
* Registers provided middleware aliases with the router
*/
protected function aliasMiddleware()
{
$router = $this->app['router'];

$method = method_exists($router, 'aliasMiddleware') ? 'aliasMiddleware' : 'middleware';

foreach ($this->middlewareAliases as $alias => $middleware) {
$router->$method($alias, $middleware);
}
}
}
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
WORK-IN-PROGRESS Laravel Passport integration for OctoberCMS

# Installation
Add the plugin to your application and then run `php artisan october:up` to run the plugin's migrations. Following https://laravel.com/docs/5.5/passport#installation would have you run `php artisan passport:install`. Read https://laravel.com/docs/5.5/passport for more information on using Passport.
Add the plugin to your application and then run `php artisan october:up` to run the plugin's migrations.
Following https://laravel.com/docs/6.x/passport#installation would have you run `php artisan passport:install`.
Read https://laravel.com/docs/6.x/passport for more information on using Passport.

**NOTE:** The default backend user model is extended to work with Passport via the `LukeTowers\Passport\Models\BackendUser` model, use that instead of `Backend\Models\User` when working with Passport.
**NOTE:**

The default backend user model is extended to work with Passport via the `LukeTowers\Passport\Models\BackendUser` model, use that instead of `Backend\Models\User` when working with Passport.

To use a different use model simply update the class path via settings. Noting that the given class must use `HasApiTokens` as per Passport documentation.
74 changes: 74 additions & 0 deletions classes/Authenticate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace LukeTowers\Passport\Classes;

use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;

/**
* Class Authenticate
* This class is heavily based off Illuminate\Auth\Middleware\Authenticate however replaces
* error causing Factory implementations with the 'Auth' reference in Octobers IOC
* @package LukeTowers\Passport\Classes
*/
class Authenticate
{
/**
* The authentication factory instance.
*/
protected $auth;

/**
* Create a new middleware instance.
*
* @return void
*/
public function __construct()
{
$this->auth = app()['auth'];
}

/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @param string[] ...$guards
* @return mixed
*
*/
public function handle($request, Closure $next, ...$guards)
{
try {
$this->authenticate($guards);
} catch (AuthenticationException $e) {
return response()->json(['error' => 'Unauthenticated!'], 401);
}

return $next($request);
}

/**
* Determine if the user is logged in to any of the given guards.
*
* @param array $guards
* @return void
*
* @throws AuthenticationException
*/
protected function authenticate(array $guards)
{
if (empty($guards)) {
return $this->auth->authenticate();
}

foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
return $this->auth->shouldUse($guard);
}
}

throw new AuthenticationException('Unauthenticated.', $guards);
}
}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
],
"require": {
"composer/installers": "~1.0",
"laravel/passport": "~4.0"
"laravel/passport": "~8.5",
"lcobucci/jwt": "3.3.3"
}
}
2 changes: 1 addition & 1 deletion config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => \LukeTowers\Passport\Models\BackendUser::class,
'model' => \LukeTowers\Passport\Models\Settings::get('user_class', 'LukeTowers\Passport\Models\BackendUser'),
],

// 'users' => [
Expand Down
30 changes: 2 additions & 28 deletions models/BackendUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,12 @@

use Backend\Models\User as BackendUserModel;

// Authenticates the user for logging in and manages the remember token
// Initial compatibility with Illumninate.Auth
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;

// Initial compatibility with Laravel.Passport
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;

// Manages the user's access to the application using Laravel's concept
// of 'Gates' & 'Policies'. See https://laravel.com/docs/5.5/authorization
// A parallel could in theory be constructed to use October's permission
// system
// use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
// use Illuminate\Foundation\Auth\Access\Authorizable;

// Triggers sending a password reset notification for the user
// use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
// use Illuminate\Auth\Passwords\CanResetPassword;

class BackendUser extends BackendUserModel implements AuthenticatableContract
class BackendUser extends BackendUserModel
{
use Authenticatable,
HasApiTokens,
use HasApiTokens,
Notifiable;

/**
* The column name of the "remember me" token.
*
* @var string
*/
protected $rememberTokenName = 'persist_code';


}
16 changes: 16 additions & 0 deletions models/Settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace LukeTowers\Passport\Models;

use Model;

class Settings extends Model
{
public $implement = ['System.Behaviors.SettingsModel'];

// A unique code
public $settingsCode = 'luketowers_passport_settings';

// Reference to field configuration
public $settingsFields = 'fields.yaml';
}
7 changes: 7 additions & 0 deletions models/settings/fields.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fields:
user_class:
label: "User Model Class"
span: auto
required: 1
type: text
comment: "i.e. Backend\\Models\\User. Default: LukeTowers\\Passport\\Models\\BackendUser"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@b8ne if you're still interested in getting this merged in as a Winter plugin, then it would probably be better to handle this configuration in a config file rather than a DB based settings item. If not, just let me know and I'll make the necessary tweaks and transfer it over to the winter namespace.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It actually is in a config file, see line 77 of config/config.php. I just use the config, but thought other people may find the GUI way easier. If we scrap the settings and just use the config, then the entire models/Settings.php implementation can also be removd.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested it with v1.1 (ie Laravel 6)?

Just updated dependencies and tested on Laravel 6.