Vaskovsky Web Application  3.17.0306
BasicAuthentication.php
1 <?php
2 // Copyright © 2017 Alexey Vaskovsky.
3 //
4 // This file is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 3.0 of the License, or (at your option) any later version.
8 //
9 // This file is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this file. If not, see
16 // <http://www.gnu.org/licenses/>
18 /**
19  * Performs basic HTTP authentication.
20  *
21  * @author Alexey Vaskovsky
22  */
24 {
25  /**
26  * Creates a new instance.
27  *
28  * @param string $realm
29  * is a realm string for the HTTP Authentication.
30  *
31  * @param PDO $pdo
32  * is a PDO connection.
33  *
34  * @param string $table
35  * is a table name where user data is stored.
36  *
37  * @throws InvalidArgumentException :
38  * if `$pdo` is null;
39  * if `$table` is empty.
40  */
41  public function __construct($realm, \PDO $pdo, $table)
42  {
43  // realm: +null
44  if (is_null($realm)) {
45  $realm = "";
46  }
47  if (! is_string($realm)) {
48  throw new \InvalidArgumentException();
49  }
50  // pdo: -null
51  if (is_null($pdo)) {
52  throw new \InvalidArgumentException();
53  }
54  // table: -empty
55  if (! is_string($table) || empty($table)) {
56  throw new \InvalidArgumentException();
57  }
58  //
59  $this->realm = $realm;
60  $this->pdo = $pdo;
61  $this->table = $table;
62  }
63  /**
64  * @copydoc AbstractAuthentication#getAccountAttribute()
65  *
66  * @implements AbstractAuthentication
67  */
68  public function getAccountAttribute($name) {
69  // name: -empty
70  if (! is_string($name) || empty($name)) {
71  throw new \InvalidArgumentException();
72  }
73  //
74  if(!$this->authenticate()) return null;
75  assert(isset($this->account));
76  return @$this->account->{$name};
77  }
78  /**
79  * @copydoc AbstractAuthentication#getPasswordHash()
80  *
81  * @implements AbstractAuthentication
82  */
83  public function getPasswordHash($password)
84  {
85  // password: -null
86  if (! is_string($password)) {
87  throw new \InvalidArgumentException();
88  }
89  //
90  return password_hash($password, PASSWORD_BCRYPT);
91  }
92  /**
93  * @copydoc AbstractAuthentication#signOut()
94  *
95  * @implements AbstractAuthentication
96  */
97  public function signOut() {
98  $this->account = null;
99  $www_authenticate = "WWW-Authenticate: Basic";
100  if (! empty($this->realm))
101  $www_authenticate .= "realm=\"{$this->realm}\"";
102  header($www_authenticate);
103  // header("HTTP/1.0 401 Unauthorized");
104  // exit();
105  http_response_code(401);
106  }
107  /**
108  * @copydoc AbstractAuthentication#authenticate()
109  *
110  * @implements AbstractAuthentication
111  */
112  public function authenticate()
113  {
114  //
115  if (isset($this->account)) return true;
116  if ($this->processAuthentication()) return true;
117  $this->signOut();
118  return false;
119  }
120  // Private
121  private function processAuthentication()
122  {
123  //
124  if (! isset($_SERVER["PHP_AUTH_USER"]))
125  return false;
126  $username = $_SERVER['PHP_AUTH_USER'];
127  if (empty($username))
128  return false;
129  $acc_sql = "select * from {$this->table} where username = ";
130  $acc_sql .= $this->pdo->quote($username);
131  $account = $this->pdo->query($acc_sql)->fetchObject();
132  if (empty($account))
133  return false;
134  $hash = $account->password;
135  if (empty($hash)) {
136  throw new \UnexpectedValueException(
137  _("Empty password") . ": {$account->username}");
138  }
139  $password = $_SERVER['PHP_AUTH_PW'];
140  if (! password_verify($password, $hash))
141  return false;
142  $this->account = $account;
143  return true;
144  }
145  private $account = null;
146  private $realm;
147  private $pdo;
148  private $table;
149 }
Performs basic HTTP authentication.
getPasswordHash($password)
Creates a new password hash.
getAccountAttribute($name)
Returns an account attribute.
__construct($realm,\PDO $pdo, $table)
Creates a new instance.