<?php

namespace Colorium\Stateful;

abstract class Auth
{

    /** @var Provider */
    protected static $provider;

    /** @var string */
    protected static $root = '__AUTH__';


    /**
     * Load session provider
     *
     * @param Provider $provider
     * @return Provider
     */
    public static function provider(Provider $provider = null)
    {
        if($provider) {
            static::$provider = $provider;
        }
        elseif(!static::$provider) {
            static::$provider = new Provider\Native(static::$root);
        }

        return static::$provider;
    }


    /**
     * Get user rank
     *
     * @return int
     */
    public static function rank()
    {
        return static::provider()->get('rank', 0);
    }


    /**
     * Get user object
     *
     * @return object
     */
    public static function user()
    {
        return static::provider()->get('user');
    }


    /**
     * Log user in session
     *
     * @param int $rank
     * @param object $user
     */
    public static function login($rank = 1, $user = null)
    {
        static::provider()->set('rank', $rank);
        static::provider()->set('user', $user);
    }


    /**
     * Log user out of session
     */
    public static function logout()
    {
        static::provider()->drop('rank');
        static::provider()->drop('user');
    }

}
<?php

namespace Colorium\Stateful;

abstract class Auth
{

    /** @var provider */
    protected static $provider;

    /** @var \Closure */
    protected static $factory;

    /** @var object */
    protected static $user;

    /** @var string */
    protected static $root = '__AUTH__';


    /**
     * Load session provider
     *
     * @param provider $provider
     * @return provider
     */
    public static function provider(provider $provider = null)
    {
        if($provider) {
            static::$provider = $provider;
        }
        elseif(!static::$provider) {
            static::$provider = new provider\Native(static::$root);
        }

        return static::$provider;
    }


    /**
     * Set user factory
     *
     * @param \Closure $factory
     */
    public static function factory(\Closure $factory)
    {
        static::$factory = $factory;
    }


    /**
     * Get user rank
     *
     * @return int
     */
    public static function rank()
    {
        return static::provider()->get('rank', 0);
    }


    /**
     * Get user ref
     *
     * @return string
     */
    public static function ref()
    {
        return static::provider()->get('ref');
    }


    /**
     * Get user object
     *
     * @return object
     */
    public static function user()
    {
        if(!static::$user and static::$factory) {
            static::$user = call_user_func(static::$factory, static::ref());
        }

        return static::$user;
    }


    /**
     * Log user in session
     *
     * @param int $rank
     * @param string $ref
     */
    public static function login($rank = 1, $ref = null)
    {
        static::provider()->set('rank', $rank);
        static::provider()->set('ref', $ref);
    }


    /**
     * Log user out of session
     */
    public static function logout()
    {
        static::provider()->drop('rank');
        static::provider()->drop('ref');
    }

}
Add user factory to auth handler
Add user factory to auth handler
