]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Core/Authentication.php
49d7976f279492f77135464f76cb7e54ada1fa3f
[galette.git] / galette / lib / Galette / Core / Authentication.php
1 <?php
2
3 /**
4 * Copyright © 2003-2024 The Galette Team
5 *
6 * This file is part of Galette (https://galette.eu).
7 *
8 * Galette is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Galette is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 namespace Galette\Core;
23
24 use Galette\Entity\Group;
25
26 /**
27 * Abstract authentication class for galette
28 *
29 * @author Johan Cwiklinski <johan@x-tnd.be>
30 *
31 * @property ?string $login
32 * @property ?string $name
33 * @property ?string $surname
34 * @property ?integer $id
35 * @property string $lang
36 * @property array<int, Group|int> $managed_groups
37 */
38
39 abstract class Authentication
40 {
41 public const ACCESS_PUBLIC = -1;
42 public const ACCESS_USER = 0;
43 public const ACCESS_MANAGER = 1;
44 public const ACCESS_STAFF = 2;
45 public const ACCESS_ADMIN = 3;
46 public const ACCESS_SUPERADMIN = 4;
47
48 protected string $login;
49 protected string $name;
50 protected ?string $surname;
51 protected bool $admin = false;
52 protected int $id;
53 protected string $lang;
54 protected bool $logged = false;
55 protected bool $active = false;
56 protected bool $superadmin = false;
57 protected bool $staff = false;
58 protected bool $uptodate = false;
59 /** @var array<int, Group|int> */
60 protected array $managed_groups = [];
61 protected bool $cron = false;
62
63 /**
64 * Logs in user.
65 *
66 * @param string $user user's login
67 * @param string $passe user's password
68 *
69 * @return boolean
70 */
71 abstract public function logIn(string $user, string $passe): bool;
72
73 /**
74 * Does this login already exists ?
75 * These function should be used for setting admin login into Preferences
76 *
77 * @param string $user the username
78 *
79 * @return boolean true if the username already exists, false otherwise
80 */
81 abstract public function loginExists(string $user): bool;
82
83 /**
84 * Login for the superuser
85 *
86 * @param string $login name
87 * @param Preferences $preferences Preferences instance
88 *
89 * @return bool
90 */
91 public function logAdmin(string $login, Preferences $preferences): bool
92 {
93 $this->logged = true;
94 $this->name = 'Admin';
95 $this->login = $login;
96 $this->admin = true;
97 $this->active = true;
98 $this->staff = false;
99 $this->uptodate = false;
100 $this->id = 0;
101 $this->lang = $preferences->pref_lang;
102 //a flag for super admin only, since it's not a regular user
103 $this->superadmin = true;
104 return true;
105 }
106
107 /**
108 * Authenticate from cron
109 *
110 * @param string $name Service name
111 * @param Preferences $preferences Preferences instance
112 *
113 * @return bool
114 */
115 abstract public function logCron(string $name, Preferences $preferences): bool;
116
117 /**
118 * Log out user and unset variables
119 *
120 * @return bool
121 */
122 public function logOut(): bool
123 {
124 unset($this->id);
125 $this->logged = false;
126 unset($this->name);
127 unset($this->login);
128 $this->admin = false;
129 $this->active = false;
130 $this->superadmin = false;
131 $this->staff = false;
132 $this->uptodate = false;
133 unset($this->lang);
134 return true;
135 }
136
137 /**
138 * Is user logged-in?
139 *
140 * @return bool
141 */
142 public function isLogged(): bool
143 {
144 return $this->logged;
145 }
146
147 /**
148 * Is user admin?
149 *
150 * @return bool
151 */
152 public function isAdmin(): bool
153 {
154 return $this->admin;
155 }
156
157 /**
158 * Is user super admin?
159 *
160 * @return bool
161 */
162 public function isSuperAdmin(): bool
163 {
164 return $this->superadmin;
165 }
166
167 /**
168 * Is user active?
169 *
170 * @return bool
171 */
172 public function isActive(): bool
173 {
174 return $this->active;
175 }
176
177 /**
178 * Is user member of staff?
179 *
180 * @return bool
181 */
182 public function isStaff(): bool
183 {
184 return $this->staff;
185 }
186
187 /**
188 * is user a crontab?
189 *
190 * @return bool
191 */
192 public function isCron(): bool
193 {
194 return $this->cron;
195 }
196
197 /**
198 * Is user a group manager?
199 * If no group id is specified, check if user is manager for at
200 * least one group.
201 *
202 * @param array<int>|int $id_group Group(s) identifier(s)
203 *
204 * @return boolean
205 */
206 public function isGroupManager(array|int $id_group = null): bool
207 {
208 $manager = false;
209 if ($this->isAdmin() || $this->isStaff()) {
210 return true;
211 } else {
212 if ($id_group === null) {
213 $manager = count($this->managed_groups) > 0;
214 } else {
215 $groups = is_array($id_group) ? $id_group : (array)$id_group;
216
217 foreach ($groups as $group) {
218 if (in_array($group, $this->managed_groups)) {
219 $manager = true;
220 break;
221 }
222 }
223 }
224 }
225 return $manager;
226 }
227
228 /**
229 * Get managed groups
230 *
231 * @return array<int, Group|int>
232 */
233 public function getManagedGroups(): array
234 {
235 return $this->managed_groups;
236 }
237
238 /**
239 * Get compact menu mode
240 *
241 * @return bool
242 */
243 public function getCompactMenu(): bool
244 {
245 return $this->logged && isset($_COOKIE['galette_compact_menu']) && $_COOKIE['galette_compact_menu'];
246 }
247
248 /**
249 * Is dark mode enabled?
250 *
251 * @return bool
252 */
253 public function isDarkModeEnabled(): bool
254 {
255 return isset($_COOKIE['galette_dark_mode']) && $_COOKIE['galette_dark_mode'];
256 }
257
258 /**
259 * Is user currently up to date?
260 * An up-to-date member is active and either due free, or with up-to-date
261 * subscription
262 *
263 * @return bool
264 */
265 public function isUp2Date(): bool
266 {
267 return $this->uptodate;
268 }
269
270 /**
271 * Display logged in member name
272 *
273 * @param boolean $only_name If we want only the name without any additional text
274 *
275 * @return string
276 */
277 public function loggedInAs(bool $only_name = false): string
278 {
279 $n = $this->name . ' ' . ($this->surname ?? '') . ' (' . $this->login . ')';
280 if ($only_name === false) {
281 return str_replace(
282 '%login',
283 $n,
284 _T("Logged in as:<br/>%login")
285 );
286 } else {
287 return $n;
288 }
289 }
290
291 /**
292 * Global getter method
293 *
294 * @param string $name name of the property we want to retrieve
295 *
296 * @return mixed
297 */
298 public function __get(string $name)
299 {
300 $forbidden = array('logged', 'admin', 'active', 'superadmin', 'staff', 'cron', 'uptodate');
301 if (in_array($name, $forbidden)) {
302 throw new \RuntimeException('Property ' . $name . ' is forbidden!');
303 }
304
305 switch ($name) {
306 case 'id':
307 if (isset($this->$name)) {
308 return (int)$this->$name;
309 }
310 return null;
311 case 'login':
312 case 'lang':
313 if (isset($this->$name)) {
314 return $this->$name;
315 }
316 return null;
317 default:
318 if (!isset($this->$name)) {
319 throw new \RuntimeException('Property ' . $name . ' is not set!');
320 }
321 return $this->$name;
322 }
323 }
324
325 /**
326 * Global isset method
327 * Required for twig to access properties via __get
328 *
329 * @param string $name name of the property we want to retrieve
330 *
331 * @return bool
332 */
333 public function __isset(string $name): bool
334 {
335 $forbidden = array('logged', 'admin', 'active', 'superadmin', 'staff', 'cron', 'uptodate');
336 if (isset($this->$name) && !in_array($name, $forbidden)) {
337 return true;
338 } else {
339 return false;
340 }
341 }
342
343
344 /**
345 * get user access level
346 *
347 * @return integer
348 */
349 public function getAccessLevel(): int
350 {
351
352 if ($this->isSuperAdmin()) {
353 return self::ACCESS_SUPERADMIN;
354 } elseif ($this->isAdmin()) {
355 return self::ACCESS_ADMIN;
356 } elseif ($this->isStaff()) {
357 return self::ACCESS_STAFF;
358 } elseif ($this->isGroupManager()) {
359 return self::ACCESS_MANAGER;
360 } elseif ($this->isLogged()) {
361 return self::ACCESS_USER;
362 } else {
363 return self::ACCESS_PUBLIC;
364 }
365 }
366 }