eesyphp/src/Auth/Http.php

138 lines
3.8 KiB
PHP

<?php
namespace EesyPHP\Auth;
use EesyPHP\App;
use EesyPHP\Auth;
use EesyPHP\I18n;
use EesyPHP\Log;
use EesyPHP\Tpl;
use EesyPHP\Url;
use function EesyPHP\vardump;
class Http extends Method {
/**
* Method to retreive HTTP credentials
* @var string
*/
private static $method;
/**
* HTTP realm string (use to compute WWW-Authenticate HTTP header)
* @var string
*/
private static $realm;
/**
* Initialize
* @return boolean
*/
public static function init() {
self :: $method = App::get('auth.http.method', 'PHP_AUTH', 'string');
self :: $realm = App::get(
'auth.http.realm', _('Authentication required'), 'string');
return true;
}
/**
* Retreive HTTP authentication data
* @return array|false array('username' => '[login]', 'password' => '[password]') or false
*/
private static function get_auth_data() {
switch(self :: $method) {
case 'AUTHORIZATION':
Log :: debug("Auth HTTP: use AUTHORIZATION method");
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
$auth_data = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
if (is_array($auth_data) && count($auth_data) == 2) {
return array(
'username' => $auth_data[0],
'password' => $auth_data[1],
);
}
else
Log :: error("Fail to parse HTTP_AUTHORIZATION environnement variable.");
}
break;
case 'REMOTE_USER':
Log :: debug("Auth HTTP : use REMOTE_USER method");
if (isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])) {
return array(
'username' => $_SERVER['REMOTE_USER'],
'password' => false,
);
}
break;
case 'PHP_AUTH':
default:
Log :: debug("Auth HTTP : use PHP_AUTH method");
if (isset($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_USER'])) {
return array(
'username' => $_SERVER['PHP_AUTH_USER'],
'password' => $_SERVER['PHP_AUTH_PW'],
);
}
break;
}
Log :: trace("HTTP::get_auth_data(): no auth data found\n".vardump($_SERVER));
return false;
}
/**
* Log user
* @param bool $force Force user authentication
* @return \EesyPHP\Auth\User|null
*/
public static function login($force=false) {
$auth_data = self :: get_auth_data();
if (!$auth_data) {
if ($force) self :: force_login();
return null;
}
if (App :: get('auth.http.trust_without_password_challenge', false, 'bool'))
$user = Auth :: get_user($auth_data['username']);
else
$user = Auth :: authenticate($auth_data['username'], $auth_data['password']);
if (!$user && $force)
self :: force_login();
return $user;
}
/**
* Force HTTP user authentification
* @return void
*/
public static function force_login() {
header('HTTP/1.1 401 Authorization Required');
header(
sprintf('WWW-Authenticate: Basic realm="%s"', addslashes(self :: $realm))
);
if (Tpl::initialized()) {
Tpl :: display("must_login.tpl", I18n::_("Access denied"));
}
else {
printf("<h1>%s</h1>", I18n::_("Access denied"));
printf("<p>%s</p>", I18n::_("You must login to access this page."));
printf(
"<p><a href='%s'>%s</a></p>",
Url :: public_root_url(),
I18n::_("You must login to access this page.")
);
}
exit();
}
/**
* Logout
* @return void
*/
public static function logout() {
self :: force_login();
}
}