🏡 index : ~doyle/koselig.git

author Jordan Doyle <jordan@doyle.wf> 2016-10-06 14:58:50.0 +00:00:00
committer Jordan Doyle <jordan@doyle.wf> 2016-10-06 14:58:50.0 +00:00:00
commit
8a8f0e505dc9d40261c8e500fc0e7564a0beda50 [patch]
tree
b01a943dcb581c0fa09b44e6813a1111fa318244
parent
f64550412d76553f3e363734ea347abb1707eb25
download
8a8f0e505dc9d40261c8e500fc0e7564a0beda50.tar.gz

Multisite & laravel -> wordpress authentication integration



Diff

 config/wordpress.php                       |   7 +-
 src/Guards/WordpressGuard.php              | 205 ++++++++++++++++++++++++++++++-
 src/Models/User.php                        |  16 +-
 src/Providers/WordpressServiceProvider.php |  38 ++++++-
 src/Routing/Route.php                      |  40 ++++++-
 src/Routing/Routing.php                    |   1 +-
 src/Support/Wordpress.php                  |   4 +-
 7 files changed, 309 insertions(+), 2 deletions(-)

diff --git a/config/wordpress.php b/config/wordpress.php
index d9f41bc..e88ee69 100644
--- a/config/wordpress.php
+++ b/config/wordpress.php
@@ -9,4 +9,11 @@ return [
    'secure_auth_salt' => env('SECURE_AUTH_SALT'),
    'logged_in_salt' => env('LOGGED_IN_SALT'),
    'nonce_salt' => env('NONCE_SALT'),
    'wp_allow_multisite' => env('WP_ALLOW_MULTISITE'),
    'multisite' => env('MULTISITE'),
    'subdomain_install' => env('SUBDOMAIN_INSTALL'),
    'domain_current_site' => env('DOMAIN_CURRENT_SITE'),
    'path_current_site' => env('PATH_CURRENT_SITE'),
    'site_id_current_site' => env('SITE_ID_CURRENT_SITE'),
    'blog_id_current_site' => env('BLOG_ID_CURRENT_SITE'),
];
diff --git a/src/Guards/WordpressGuard.php b/src/Guards/WordpressGuard.php
new file mode 100644
index 0000000..410fde7
--- /dev/null
+++ b/src/Guards/WordpressGuard.php
@@ -0,0 +1,205 @@
<?php
namespace Koselig\Guards;

use Illuminate\Auth\GuardHelpers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Support\Facades\Request;
use Koselig\Models\User;
use Koselig\Support\Action;
use WP_Error;

/**
 * Wordpress user guard, provides a bridge between Laravel's authentication
 * and Wordpress.
 *
 * @author Jordan Doyle <jordan@doyle.wf>
 */
class WordpressGuard implements StatefulGuard
{
    use GuardHelpers;

    /**
     * Get the last user we attempted to login as.
     *
     * @var User
     */
    private $lastAttempted = null;

    /**
     * Determine if the current user is authenticated.
     *
     * @return bool
     */
    public function check()
    {
        return is_user_logged_in();
    }

    /**
     * Get the currently authenticated user.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function user()
    {
        // If we've already retrieved the user for the current request we can just
        // return it back immediately. We do not want to fetch the user data on
        // every call to this method because that would be tremendously slow.
        if (!is_null($this->user)) {
            return $this->user;
        }

        return $this->user = ($this->check() ? User::find(get_current_user_id()) : null);
    }

    /**
     * Validate a user's credentials.
     *
     * @param  array $credentials
     * @return bool
     */
    public function validate(array $credentials = [])
    {
        $user = wp_authenticate($credentials['username'], $credentials['password']);

        $this->lastAttempted = User::find($user->ID);

        return !($user instanceof WP_Error);
    }

    /**
     * Attempt to authenticate a user using the given credentials.
     *
     * @param  array $credentials
     * @param  bool $remember
     * @param  bool $login
     * @return bool
     */
    public function attempt(array $credentials = [], $remember = false, $login = true)
    {
        $validate = $this->validate($credentials);

        if (!$login) {
            return $validate;
        }

        $user = $this->lastAttempted;

        // check if we should use a secure cookie
        wp_set_auth_cookie($user->ID, $credentials['remember'], Request::secure());
        Action::trigger('wp_login', $user->user_login, $user);

        $this->setUser($user);

        return true;
    }

    /**
     * Log a user into the application without sessions or cookies.
     *
     * @param  array $credentials
     * @return bool
     */
    public function once(array $credentials = [])
    {
        if ($this->validate($credentials)) {
            $this->setUser($this->lastAttempted);
            return true;
        }

        return false;
    }

    /**
     * Log a user into the application.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable $user
     * @param  bool $remember
     * @return void
     */
    public function login(Authenticatable $user, $remember = false)
    {
        wp_set_auth_cookie($user->ID, $remember);
        Action::trigger('wp_login', $user->user_login, get_userdata($user->ID));
        wp_set_current_user($user->ID);

        $this->user = $user;
    }

    /**
     * Log the given user ID into the application.
     *
     * @param  mixed $id
     * @param  bool $remember
     * @return \Illuminate\Contracts\Auth\Authenticatable|bool
     */
    public function loginUsingId($id, $remember = false)
    {
        $user = User::find($id);

        if (!$user) {
            return false;
        }

        wp_set_auth_cookie($user->ID, $remember);
        Action::trigger('wp_login', $user->user_login, get_userdata($user->ID));
        wp_set_current_user($user->ID);

        return $this->user = $user;
    }

    /**
     * Log the given user ID into the application without sessions or cookies.
     *
     * @param  mixed $id
     * @return bool
     */
    public function onceUsingId($id)
    {
        $user = User::find($id);

        if (!$user) {
            return false;
        }

        wp_set_current_user($id);

        return $this->user = $user;
    }

    /**
     * Determine if the user was authenticated via "remember me" cookie.
     *
     * @return bool
     */
    public function viaRemember()
    {
        return Request::hasCookie(Request::secure() ? SECURE_AUTH_COOKIE : AUTH_COOKIE);
    }

    /**
     * Log the user out of the application.
     *
     * @return void
     */
    public function logout()
    {
        wp_logout();
        $this->user = null;
    }

    /**
     * Set the current user.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable $user
     * @return $this
     */
    public function setUser(Authenticatable $user)
    {
        wp_set_current_user($user->ID);
        $this->user = $user;

        return $this;
    }
}
diff --git a/src/Models/User.php b/src/Models/User.php
index 80a82f5..98ed007 100644
--- a/src/Models/User.php
+++ b/src/Models/User.php
@@ -1,6 +1,8 @@
<?php
namespace Koselig\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

@@ -9,8 +11,10 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
 *
 * @author Jordan Doyle <jordan@doyle.wf>
 */
class User extends Model
class User extends Model implements AuthenticatableContract
{
    use Authenticatable;

    public $table = DB_PREFIX . 'users';
    public $primaryKey = 'ID';

@@ -23,4 +27,14 @@ class User extends Model
    {
        return $this->hasMany(self::class, 'post_author');
    }

    /**
     * Get the password for the user.
     *
     * @return string
     */
    public function getAuthPassword()
    {
        return $this->user_pass;
    }
}
diff --git a/src/Providers/WordpressServiceProvider.php b/src/Providers/WordpressServiceProvider.php
index 9aff474..183b476 100644
--- a/src/Providers/WordpressServiceProvider.php
+++ b/src/Providers/WordpressServiceProvider.php
@@ -2,8 +2,10 @@
namespace Koselig\Providers;

use Illuminate\Contracts\Routing\UrlGenerator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
use Koselig\Guards\WordpressGuard;
use Koselig\Support\Action;

/**
@@ -39,6 +41,18 @@ class WordpressServiceProvider extends ServiceProvider
    }

    /**
     * Register the Wordpress authentication services.
     *
     * @return void
     */
    public function boot()
    {
        Auth::extend('wordpress', function ($app, $name, array $config) {
            return new WordpressGuard(Auth::createUserProvider($config['provider']));
        });
    }

    /**
     * Set up the configuration values that wp-config.php
     * does. Use all the values out of .env instead.
     *
@@ -57,6 +71,7 @@ class WordpressServiceProvider extends ServiceProvider
        $this->setDatabaseConstants($table_prefix);
        $this->setAuthenticationConstants();
        $this->setLocationConstants();
        $this->setMultisiteConstants();

        if ($this->app->runningInConsole()) {
            // allow wordpress to run, even when running from console (ie. artisan compiling)
@@ -118,6 +133,29 @@ class WordpressServiceProvider extends ServiceProvider
    }

    /**
     * Set up constants that will allow the user to use a multisite install of Wordpress.
     */
    private function setMultisiteConstants()
    {
        $multisite = $this->app->make('config')->get('wordpress.wp_allow_multisite');

        if ($multisite) {
            define('WP_ALLOW_MULTISITE', $multisite);

            $enabled = $this->app->make('config')->get('wordpress.multisite');

            if ($enabled) {
                define('MULTISITE', $enabled);
                define('SUBDOMAIN_INSTALL', $this->app->make('config')->get('wordpress.subdomain_install'));
                define('DOMAIN_CURRENT_SITE', $this->app->make('config')->get('wordpress.domain_current_site'));
                define('PATH_CURRENT_SITE', $this->app->make('config')->get('wordpress.path_current_site'));
                define('SITE_ID_CURRENT_SITE', $this->app->make('config')->get('wordpress.site_id_current_site'));
                define('BLOG_ID_CURRENT_SITE', $this->app->make('config')->get('wordpress.blog_id_current_site'));
            }
        }
    }

    /**
     * Wordpress core hooks needed for the main functionality of
     * Koselig.
     *
diff --git a/src/Routing/Route.php b/src/Routing/Route.php
new file mode 100644
index 0000000..cd50c6e
--- /dev/null
+++ b/src/Routing/Route.php
@@ -0,0 +1,40 @@
<?php
namespace Koselig\Routing;

use Illuminate\Http\Request;
use Illuminate\Routing\Route as LaravelRoute;
use Illuminate\Support\Facades\Input;
use Symfony\Component\Routing\Route as SymfonyRoute;

/**
 * Extend the base Laravel routing functionality to add multisite support
 * to Route::get, Route::post, etc methods.
 *
 * @author Jordan Doyle <jordan@doyle.wf>
 */
class Route extends LaravelRoute
{
    /**
     * Determine if the route matches given request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  bool $includingMethod
     * @return bool
     */
    public function matches(Request $request, $includingMethod = true)
    {
        $this->compileRoute();

        foreach ($this->getValidators() as $validator) {
            if (!$includingMethod && $validator instanceof MethodValidator) {
                continue;
            }

            if (!$validator->matches($this, $request)) {
                return false;
            }
        }

        return true;
    }
}
diff --git a/src/Routing/Routing.php b/src/Routing/Routing.php
index 1ff2d70..0f39c77 100644
--- a/src/Routing/Routing.php
+++ b/src/Routing/Routing.php
@@ -3,6 +3,7 @@ namespace Koselig\Routing;

use Illuminate\Container\Container;
use Illuminate\Support\Facades\Route;
use Koselig\Routing\Route as KoseligRoute;

class Routing
{
diff --git a/src/Support/Wordpress.php b/src/Support/Wordpress.php
index 5ab59b0..8b18435 100644
--- a/src/Support/Wordpress.php
+++ b/src/Support/Wordpress.php
@@ -94,7 +94,9 @@ class Wordpress
    }

    /**
     * Get the current logged in user.
     * Get the current logged in user. Generally, you shouldn't be using this
     * function and should instead be using Auth::user() from Laravel to get
     * the current logged in Wordpress user.
     *
     * @return \WP_User
     */