Commit 6330dd0d authored by Taddeus Kroes's avatar Taddeus Kroes

Added some more handlers with built-in security support

parent 2770f070
...@@ -9,31 +9,108 @@ ...@@ -9,31 +9,108 @@
namespace webbasics; namespace webbasics;
require_once 'router.php'; require_once 'router.php';
require_once 'security.php';
abstract class BaseHandler implements RouteHandler { abstract class BaseHandler implements RouteHandler {
function handleRequest(array $data) { function handleRequest(array $data) {
list($method_name, $args) = $this->extractMethodAndArgs($data);
return call_user_func_array(array($this, $method_name), $args);
}
protected function extractMethodAndArgs(array $data) {
$request_type = strtolower($_SERVER['REQUEST_METHOD']); $request_type = strtolower($_SERVER['REQUEST_METHOD']);
// Try to use first match value as method name, e.g. getAction() if // Try to use first match value as method name, e.g. getAction() if
// first match value is "action" // first match value is "action" and request method is "GET"
if (count($data)) { if (count($data)) {
$method_name = $request_type . camelize($data[0], true); $method_name = $request_type . camelize($data[0], true);
if (method_exists($this, $method_name)) { if (method_exists($this, $method_name)) {
// getAction() or getAction($data)
array_shift($data); array_shift($data);
} else {
// get($data) or post($data)
$method_name = $request_type;
}
} else {
// get() or post()
$method_name = $request_type;
}
if (count($data)) $args = count($data) ? array($data) : array();
return $this->$method_name($data); return array($method_name, $args);
else
return $this->$method_name();
} }
}
// get($data) or post($data) abstract class AuthenticatedHandler extends BaseHandler {
return $this->$request_type($data); function handleRequest(array $data) {
// A user must be logged in
self::checkLogin();
// Base class will call the corresponding method
return parent::handleRequest();
} }
// get() or post() static function checkLogin() {
return $this->$request_type(); Authentication::getInstance()->requireLogin();
}
}
abstract class TokenizedHandler extends BaseHandler {
const TOKEN_NAME = 'auth_token';
function handleRequest(array $data) {
// Token must exist and have the right value
self::checkToken();
// Base class will call the corresponding method
return parent::handleRequest();
}
static function checkToken() {
if (!isset($_REQUEST[self::TOKEN_NAME]))
throw new AuthenticationError('token missing in request data');
Authentication::getInstance()->requireToken($_REQUEST[self::TOKEN_NAME]);
}
}
abstract class AuthorizedHandler extends BaseHandler {
function handleRequest(array $data) {
// A user must be logged in
AuthenticatedHandler::checkLogin();
// The user must have access to the called method
list($method_name, $args) = $this->extractMethodAndArgs($data);
$role = $this->determineRequiredRole($method_name, $args);
Authentication::getInstance()->requireUserRole($role);
// Base class will call the corresponding method
return parent::handleRequest();
}
abstract function getRequiredRole($method_name, array $args);
}
abstract class TokenizedAuthenticatedHandler extends TokenizedHandler {
function handleRequest(array $data) {
// A user must be logged in
AuthenticatedHandler::checkLogin();
// Parent class will check the token
return parent::handleRequest();
}
}
abstract class TokenizedAuthorizedHandler extends AuthorizedHandler {
function handleRequest(array $data) {
// Token must exist and have the right value
TokenizedHandler::checkToken();
// Parent class will verify that a user is logged in and has access to
// the called method
return parent::handleRequest($data);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment