3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
6 * Default authentication class for galette
10 * Copyright © 2007-2020 The Galette Team
12 * This file is part of Galette (http://galette.tuxfamily.org).
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
27 * @category Authentication
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2007-2020 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.7dev - 2007-07-06
37 namespace Galette\Core
;
40 use Galette\Repository\Groups
;
41 use Galette\Repository\Members
;
42 use Galette\Entity\Adherent
;
43 use Galette\Entity\Status
;
48 * Default authentication class for galette
50 * @category Authentication
53 * @author Johan Cwiklinski <johan@x-tnd.be>
54 * @copyright 2007-2014 The Galette Team
55 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
56 * @link http://galette.tuxfamily.org
57 * @since Available since 0.7dev - 2007-07-06
59 class Login
extends Authentication
61 public const TABLE
= Adherent
::TABLE
;
62 public const PK
= 'login_adh';
66 private $impersonated = false;
71 * @param Db $zdb Database instance
72 * @param I18n $i18n I18n instance
74 public function __construct(Db
$zdb, I18n
$i18n)
81 * Login for the superuser
83 * @param string $login name
84 * @param Preferences $preferences Preferences instance
88 public function logAdmin($login, Preferences
$preferences)
90 parent
::logAdmin($login, $preferences);
91 $this->impersonated
= false;
95 * Log out user and unset variables
99 public function logOut()
102 $this->impersonated
= false;
108 * @param string $user user's login
109 * @param string $passe user's password
113 public function logIn($user, $passe)
116 $select = $this->select();
122 \Laminas\Db\Sql\Predicate\PredicateSet
::OP_OR
125 $results = $this->zdb
->execute($select);
127 if (isset($_SERVER['REMOTE_ADDR'])) {
128 $log_suffix .= ' Client ' . $_SERVER['REMOTE_ADDR'];
130 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
131 $log_suffix .= ' X-Forwarded-For ' . $_SERVER['HTTP_X_FORWARDED_FOR'];
134 if ($results->count() === 0) {
136 'No entry found for login `' . $user . '`' . $log_suffix,
141 $row = $results->current();
143 //check if member is active
144 if (!$row->activite_adh
== true) {
146 'Member `' . $user . ' is inactive!`' . $log_suffix,
152 //check if passwords matches
153 $pw_checked = password_verify($passe, $row->mdp_adh
);
155 //if password did not match, we try old md5 method
156 $pw_checked = (md5($passe) === $row->mdp_adh
);
159 if ($pw_checked === false) {
160 //Passwords mismatch. Log and return.
162 'Passwords mismatch for login `' . $user . '`' . $log_suffix,
168 $this->logUser($row);
171 } catch (Throwable
$e) {
173 'An error occurred: ' . $e->getMessage(),
176 Analog
::log($e->getTrace(), Analog
::ERROR
);
182 * Get select query without where clause
184 * @return \Laminas\Db\Sql\Select
186 private function select()
188 $select = $this->zdb
->select(self
::TABLE
, 'a');
203 array('b' => PREFIX_DB
. Status
::TABLE
),
204 'a.' . Status
::PK
. '=b.' . Status
::PK
,
205 array('priorite_statut')
211 * Populate object after successfull login
213 * @param \ArrayObject $row User information
217 private function logUser(\ArrayObject
$row)
219 Analog
::log('User `' . $row->login_adh
. '` logged in.', Analog
::INFO
);
220 $this->id
= $row->id_adh
;
221 $this->login
= $row->login_adh
;
222 $this->passe
= $row->mdp_adh
;
223 $this->admin
= $row->bool_admin_adh
;
224 $this->name
= $row->nom_adh
;
225 $this->surname
= $row->prenom_adh
;
226 $this->lang
= $row->pref_lang
;
227 $this->i18n
->changeLanguage($this->lang
);
228 $this->active
= $row->activite_adh
;
229 $this->logged
= true;
230 if ($row->priorite_statut
< Members
::NON_STAFF_MEMBERS
) {
233 //check if member is up to date
234 if ($row->bool_exempt_adh
== true) {
235 //member is due free, he's up to date.
236 $this->uptodate
= true;
238 //let's check from end date, if present
239 if ($row->date_echeance
== null) {
240 $this->uptodate
= false;
242 $ech = new \
DateTime($row->date_echeance
);
243 $now = new \
DateTime();
244 $now->setTime(0, 0, 0);
245 $this->uptodate
= $ech >= $now;
248 //staff members and admins are de facto groups managers. For all
249 //others, get managed groups
251 !$this->isSuperAdmin()
255 $this->managed_groups
= Groups
::loadManagedGroups(
265 * @param int $id Member ID
269 public function impersonate($id)
271 if (!$this->isSuperAdmin()) {
272 throw new \
RuntimeException(
273 'Only superadmin can impersonate!'
277 Analog
::log('Impersonating `' . $id . '`...', Analog
::INFO
);
279 $select = $this->select();
280 $select->where(array(Adherent
::PK
=> $id));
282 $results = $this->zdb
->execute($select);
283 if ($results->count() == 0) {
285 'No entry found for id `' . $id . '`',
290 $this->impersonated
= true;
291 $this->superadmin
= false;
292 $row = $results->current();
293 $this->logUser($row);
296 } catch (Throwable
$e) {
298 'An error occurred: ' . $e->getMessage(),
301 Analog
::log($e->getTraceAsString(), Analog
::ERROR
);
307 * Does this login already exists ?
308 * These function should be used for setting admin login into Preferences
310 * @param string $user the username
312 * @return true if the username already exists, false otherwise
314 public function loginExists($user)
317 $select = $this->zdb
->select(self
::TABLE
);
318 $select->where(array(self
::PK
=> $user));
319 $results = $this->zdb
->execute($select);
321 if ($results->count() > 0) {
322 /* We got results, user already exists */
325 /* No results, user does not exists yet :) */
328 } catch (Throwable
$e) {
330 'Cannot check if login exists | ' . $e->getMessage(),
333 /* If an error occurs, we consider that username already exists */
343 public function isImpersonated()
345 return $this->impersonated
;
351 * @param int $id ID to set
355 public function setId(int $id): self