Last active
March 10, 2016 04:06
-
-
Save igorsantos07/2f0720c977e4b7478b36 to your computer and use it in GitHub Desktop.
Test case for Luracast/Restler#524
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Luracast\Restler\Restler; | |
use Luracast\Restler\Explorer; | |
require __DIR__ . '/../vendor/autoload.php'; | |
$r = new Restler(); | |
$r->addAPIClass('Home',''); | |
$r->addAPIClass('Explorer'); | |
$r->addAuthenticationClass('Session'); | |
$r->addAPIClass('Session'); | |
Explorer::$hideProtected = false; | |
$r->handle(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Luracast\Restler\iAuthenticate; | |
use Luracast\Restler\RestException; | |
class Session implements iAuthenticate { | |
/** | |
* Points the basic user level needed whenever authentication is used. | |
* Can be changed by API method using "@class Session {@requires manager}" | |
* @var int | |
*/ | |
public static $requires = 1; //was a constant | |
/** | |
* The level of the current authenticated user | |
* @var int | |
*/ | |
public static $currentLevel = 0; | |
const SESSION_NAME = 'token'; | |
protected static function _sessionStart() { | |
if (session_status() == PHP_SESSION_ACTIVE) { | |
return; | |
} | |
//protecting against badly-cleaned cookies | |
if (isset($_COOKIE[static::SESSION_NAME]) && !$_COOKIE[static::SESSION_NAME]) { | |
unset($_COOKIE[static::SESSION_NAME]); | |
} | |
session_name(static::SESSION_NAME); | |
session_set_cookie_params(0, '/', null, isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'], true); | |
if (isset($_SERVER['HTTP_AUTHORIZATION'])) { | |
if (stripos($_SERVER['HTTP_AUTHORIZATION'], 'Bearer ') === 0) { | |
$parts = explode(' ', $_SERVER['HTTP_AUTHORIZATION']); | |
if (isset($parts[1])) { | |
session_id($token = $parts[1]); | |
} | |
} | |
if (!isset($token)) { //if the header was sent but no token was found, the request was badly formed | |
throw new RestException(HTTP_BAD_REQUEST, 'Incomplete auth header'); | |
} | |
} | |
session_start(); | |
} | |
protected static function _gotSessionData() { | |
return isset($_COOKIE[static::SESSION_NAME]) || isset($_SERVER['HTTP_AUTHORIZATION']); | |
} | |
public function __getWWWAuthenticateString() { | |
return 'POST /session { email, password }'; | |
} | |
/** | |
* Access verification method. | |
* API access will be denied when this method returns false | |
* @return boolean true when api access is allowed false otherwise | |
* @throws 403 Forbidden User level is not enough | |
*/ | |
public function __isAllowed() { | |
if (!self::_gotSessionData()) { //sent no session token, so there's no reason to even open it | |
return false; | |
} | |
static::_sessionStart(); | |
if (!(isset($_SESSION['email']) && $_SESSION['email'])) { //not authenticated! | |
$this->delete(); | |
return false; | |
} else { //authenticated, who are you? | |
static::$currentLevel = $_SESSION['level']?: 0; | |
$allowed = [static::$requires, User::LEVELS[static::$requires], User::LVL_MANAGER]; | |
if (in_array(static::$currentLevel, $allowed)) { | |
return true; //nice badge you got there, go ahead | |
} else { | |
throw new RestException(HTTP_FORBIDDEN); //you're not allowed to be here, move on | |
} | |
} | |
} | |
/** | |
* Authenticates a user and issues a session cookie. | |
* If the client does not support cookies, the behaviour can be easily simulated by | |
* storing the cookie name and value (got from the Set-Cookie header) and sending | |
* it back with a "Cookie" header. | |
* @param string $email | |
* @param string $password | |
* @throws 401 Unauthorized | |
* @return array The auth token, also contained in the Set-Cookie header. | |
*/ | |
public function post($email, $password) { | |
User::$throwOnFind = false; //so we won't disclose what users are valid | |
/** @var User $user */ | |
$user = User::where('email', $email)->first(); | |
if ($user && User::$hasher->check($password, $user->password)) { | |
static::_sessionStart(); | |
session_regenerate_id(); | |
$result = ['token' => session_id()]; | |
foreach($user->attributesToArray() as $field => $value) { | |
$_SESSION[$field] = $result[$field] = $value; | |
} | |
return $result; | |
} else { | |
$this->delete(); | |
throw new RestException(HTTP_UNAUTHORIZED); | |
} | |
} | |
/** | |
* Destroys the user session. | |
* @status 204 | |
*/ | |
protected function delete() { | |
static::_sessionStart(); | |
setcookie(static::SESSION_NAME, null, null, '/'); | |
$_SESSION = []; | |
session_destroy(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment