Skip to content
This repository was archived by the owner on May 7, 2023. It is now read-only.

Commit d59b171

Browse files
committed
new basic auth alternative, session based, but backwards compatible
1 parent 86352a9 commit d59b171

File tree

21 files changed

+602
-94
lines changed

21 files changed

+602
-94
lines changed

lib/Foomo/BasicAuth.php

Lines changed: 71 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,21 @@ class BasicAuth {
3030

3131
private $authUserFile;
3232
private $passwordEncryption;
33+
private $authUserDomain;
3334
private $authenticated = false;
3435

3536
const DEFAULT_AUTH_DOMAIN = 'default';
3637

38+
public static function getCurrentUser()
39+
{
40+
if(isset($_SERVER["PHP_AUTH_USER"])) {
41+
return $_SERVER["PHP_AUTH_USER"];
42+
} else if(BasicAuth\HTML::isAvailable()) {
43+
return BasicAuth\HTML\Session::getUser();
44+
} else {
45+
return "";
46+
}
47+
}
3748
/**
3849
* construct your auth object
3950
*
@@ -45,10 +56,12 @@ public function __construct($authUserDomain = null, $passwordEncryption = 'crypt
4556
{
4657
$authUserFile = null;
4758
if (is_null($authUserDomain)) {
59+
$this->authUserDomain = self::DEFAULT_AUTH_DOMAIN;
4860
if (file_exists(self::getDefaultAuthFilename())) {
4961
$authUserFile = self::getDefaultAuthFilename();
5062
}
5163
} else {
64+
$this->authUserDomain = $authUserDomain;
5265
$authUserFile = self::getAuthFilename($authUserDomain);
5366
}
5467
if (!file_exists($authUserFile)) {
@@ -136,47 +149,11 @@ public function checkAuthentication()
136149
} else {
137150
$auth = false;
138151
if (isset($_SERVER["PHP_AUTH_USER"]) && $_SERVER["PHP_AUTH_PW"]) {
139-
$fp = fopen($this->authUserFile, 'r');
140-
while ($line = fgets($fp)) {
141-
$line = trim($line);
142-
$parts = explode(':', $line);
143-
if(count($parts)==2) {
144-
list($username, $password) = $parts;
145-
if ($username == $_SERVER['PHP_AUTH_USER']) {
146-
switch(true) {
147-
case strpos($password, '{SHA}') === 0:
148-
//trigger_error("sha " . $password . " " . $_SERVER["PHP_AUTH_PW"] . " " . base64_encode(sha1($_SERVER["PHP_AUTH_PW"], true)), E_USER_WARNING);
149-
// inline sha
150-
$this->passwordEncryption = "sha1";
151-
break;
152-
}
153-
switch ($this->passwordEncryption) {
154-
case 'crypt':
155-
// Get the salt from $password. It is always the first
156-
// two characters of a DES-encrypted string.
157-
$salt = substr($password, 0, 2);
158-
// Encrypt $PHP_AUTH_PW based on $salt
159-
$hashedPassword = crypt($_SERVER["PHP_AUTH_PW"], $salt);
160-
break;
161-
case 'sha1':
162-
$hashedPassword = "{SHA}" . base64_encode(sha1($_SERVER["PHP_AUTH_PW"], true));
163-
break;
164-
default:
165-
$hashedPassword = null;
166-
trigger_error("unsupported password hashing algorithm", E_USER_ERROR);
167-
}
168-
if ($password == $hashedPassword) {
169-
// A match is found, meaning the user is authenticated.
170-
// Stop the search.
171-
$auth = true;
172-
break;
173-
}
174-
}
175-
} else {
176-
trigger_error("fishy line in basic auth file", E_USER_WARNING);
177-
}
152+
$auth = $this->checkCredentials($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]);
153+
if(!$auth && BasicAuth\HTML::isAvailable()) {
154+
// token fallback
155+
$auth = in_array($this->authUserDomain, BasicAuth\Token::useToken($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]));
178156
}
179-
fclose($fp);
180157
}
181158
if (!$auth) {
182159
return false;
@@ -186,6 +163,55 @@ public function checkAuthentication()
186163
}
187164
}
188165
}
166+
private function checkCredentials($user, $password)
167+
{
168+
$auth = false;
169+
$fp = fopen($this->authUserFile, 'r');
170+
while ($line = fgets($fp)) {
171+
$line = trim($line);
172+
$parts = explode(':', $line);
173+
if(count($parts)==2) {
174+
list($fileUserName, $filePasswordHash) = $parts;
175+
if ($fileUserName == $user) {
176+
switch(true) {
177+
case strpos($filePasswordHash, '{SHA}') === 0:
178+
// inline sha
179+
$this->passwordEncryption = "sha1";
180+
break;
181+
}
182+
switch ($this->passwordEncryption) {
183+
case 'crypt':
184+
// Get the salt from $password. It is always the first
185+
// two characters of a DES-encrypted string.
186+
$salt = substr($filePasswordHash, 0, 2);
187+
$hashedPassword = crypt($password, $salt);
188+
break;
189+
case 'sha1':
190+
$hashedPassword = "{SHA}" . base64_encode(sha1($password, true));
191+
break;
192+
default:
193+
$hashedPassword = null;
194+
trigger_error("unsupported password hashing algorithm", E_USER_ERROR);
195+
}
196+
if ($filePasswordHash == $hashedPassword) {
197+
// A match is found, meaning the user is authenticated.
198+
// Stop the search.
199+
$auth = true;
200+
break;
201+
}
202+
}
203+
} else {
204+
trigger_error("fishy line in basic auth file", E_USER_WARNING);
205+
}
206+
}
207+
fclose($fp);
208+
return $auth;
209+
}
210+
public static function checkCredentialsForDomain($user, $password, $domain)
211+
{
212+
$inst = new self($domain);
213+
return $inst->checkCredentials($user, $password);
214+
}
189215
/**
190216
* check if you are authenticated use @see checkAuthentication instead
191217
*
@@ -197,8 +223,11 @@ public function getAuthenticated()
197223
return $this->checkAuthentication();
198224
}
199225

200-
public function logout()
226+
public static function logout()
201227
{
202-
228+
if(isset($_SERVER["PHP_AUTH_USER"])) {
229+
header('WWW-Authenticate: Basic realm="' . \Foomo\Frontend::BASIC_AUTH_REALM . '", true, 401');
230+
}
231+
BasicAuth\HTML::logout();
203232
}
204233
}

lib/Foomo/BasicAuth/Frontend/Controller.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Controller
3434
//---------------------------------------------------------------------------------------------
3535

3636
/**
37-
* @var Foomo\BasicAuth\Frontend\Model
37+
* @var Model
3838
*/
3939
public $model;
4040

lib/Foomo/BasicAuth/HTML.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the foomo Opensource Framework.
5+
*
6+
* The foomo Opensource Framework is free software: you can redistribute it
7+
* and/or modify it under the terms of the GNU Lesser General Public License as
8+
* published  by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* The foomo Opensource Framework is distributed in the hope that it will
12+
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License along with
17+
* the foomo Opensource Framework. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
namespace Foomo\BasicAuth;
21+
22+
/**
23+
* basic auth file CRUD
24+
*
25+
* @link www.foomo.org
26+
* @license www.gnu.org/licenses/lgpl.txt
27+
* @author jan <[email protected]>
28+
*/
29+
class HTML
30+
{
31+
public static function auth(array $domains, $authMVCClassOrObject = "Foomo\\BasicAuth\\HTML\\Frontend")
32+
{
33+
if(!self::isAvailable() || (!empty($_SERVER["PHP_AUTH_USER"]) && !empty($_SERVER["PHP_AUTH_PW"]))) {
34+
// basic auth fallback
35+
\Foomo\BasicAuth::auth("authenticate", $domains[0]);
36+
} else {
37+
if(!HTML\Session::userIsAuthenticatedForOneDomain($domains)) {
38+
if(is_string($authMVCClassOrObject)) {
39+
$authMVCClassOrObject = new $authMVCClassOrObject($domains);
40+
}
41+
echo \Foomo\MVC::run($authMVCClassOrObject, $_SERVER["REQUEST_URI"], true);
42+
exit;
43+
}
44+
}
45+
}
46+
public static function login($user, $password, $domains)
47+
{
48+
$authenticatedDomains = [];
49+
foreach($domains as $domain) {
50+
if(\Foomo\BasicAuth::checkCredentialsForDomain($user, $password, $domain)) {
51+
$authenticatedDomains[] = $domain;
52+
}
53+
}
54+
if(count($authenticatedDomains) > 0) {
55+
\Foomo\MVC::abort();
56+
\Foomo\BasicAuth\HTML\Session::setUser($user, $authenticatedDomains);
57+
header('Location: ' . $_SERVER["REQUEST_URI"]);
58+
exit;
59+
}
60+
}
61+
public static function isAvailable()
62+
{
63+
return \Foomo\Session::getEnabled();
64+
}
65+
public static function logout()
66+
{
67+
HTML\Session::reset();
68+
}
69+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/*
3+
* This file is part of the foomo Opensource Framework.
4+
*
5+
* The foomo Opensource Framework is free software: you can redistribute it
6+
* and/or modify it under the terms of the GNU Lesser General Public License as
7+
* published by the Free Software Foundation, either version 3 of the
8+
* License, or (at your option) any later version.
9+
*
10+
* The foomo Opensource Framework is distributed in the hope that it will
11+
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License along with
16+
* the foomo Opensource Framework. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
namespace Foomo\BasicAuth\HTML;
20+
21+
use Foomo\MVC\AbstractApp;
22+
23+
/**
24+
* @link www.foomo.org
25+
* @license www.gnu.org/licenses/lgpl.txt
26+
* @author jan
27+
*/
28+
29+
class Frontend extends AbstractApp
30+
{
31+
/**
32+
* @var Frontend\Model
33+
*/
34+
public $model;
35+
/**
36+
* @var Frontend\Controller
37+
*/
38+
public $controller;
39+
public function __construct($domains)
40+
{
41+
parent::__construct(__CLASS__);
42+
$this->model->domains = $domains;
43+
}
44+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the foomo Opensource Framework.
5+
*
6+
* The foomo Opensource Framework is free software: you can redistribute it
7+
* and/or modify it under the terms of the GNU Lesser General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* The foomo Opensource Framework is distributed in the hope that it will
12+
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License along with
17+
* the foomo Opensource Framework. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
namespace Foomo\BasicAuth\HTML\Frontend;
21+
use Foomo\MVC;
22+
23+
/**
24+
* @link www.foomo.org
25+
* @license www.gnu.org/licenses/lgpl.txt
26+
* @author jan
27+
*/
28+
29+
class Controller
30+
{
31+
/**
32+
* my model
33+
*
34+
* @var Model
35+
*/
36+
public $model;
37+
38+
public function actionDefault()
39+
{
40+
if(!empty($_POST["name"]) && !empty($_POST["password"])) {
41+
$user = $_POST["name"];
42+
$password = $_POST["password"];
43+
\Foomo\BasicAuth\HTML::login($user, $password, $this->model->domains);
44+
45+
}
46+
}
47+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the foomo Opensource Framework.
5+
*
6+
* The foomo Opensource Framework is free software: you can redistribute it
7+
* and/or modify it under the terms of the GNU Lesser General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* The foomo Opensource Framework is distributed in the hope that it will
12+
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License along with
17+
* the foomo Opensource Framework. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
namespace Foomo\BasicAuth\HTML\Frontend;
21+
22+
/**
23+
* @link www.foomo.org
24+
* @license www.gnu.org/licenses/lgpl.txt
25+
* @author jan
26+
*/
27+
28+
class Model
29+
{
30+
public $domains;
31+
}

0 commit comments

Comments
 (0)