FOSSology  4.7.0-rc1
Open Source License Compliance by Open Source Software
UserDao.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014-2017 Siemens AG
4  Author: J. Najjar, S. Weber, A. Wührl
5  SPDX-FileCopyrightText: © 2021-2022 Orange
6  Contributors: Piotr Pszczola, Bartlomiej Drozdz
7 
8  SPDX-License-Identifier: GPL-2.0-only
9 */
10 
11 namespace Fossology\Lib\Dao;
12 
15 use Monolog\Logger;
16 use Symfony\Component\HttpFoundation\Session\Session;
17 
18 class UserDao
19 {
20  const USER = 0;
21  const ADMIN = 1;
22  const ADVISOR = 2;
23 
24  const USER_ACTIVE_STATUS = 'active';
25 
26  const SUPER_USER = 'fossy';
27 
28  /* @var DbManager */
29  private $dbManager;
30  /* @var Logger */
31  private $logger;
33  private $session;
34 
35  function __construct(DbManager $dbManager, Logger $logger)
36  {
37  $this->dbManager = $dbManager;
38  $this->logger = $logger;
39 
40  global $container;
41  $this->session = $container->get('session');
42  }
43 
47  public function getUserChoices($groupId=null)
48  {
49  if (empty($groupId)) {
50  $groupId = Auth::getGroupId();
51  }
52  $userChoices = array();
53  $statementN = __METHOD__;
54  $sql = "SELECT user_pk, user_name, user_desc FROM users LEFT JOIN group_user_member AS gum ON users.user_pk = gum.user_fk"
55  . " WHERE gum.group_fk = $1 AND users.user_status='active'";
56  $this->dbManager->prepare($statementN, $sql);
57  $res = $this->dbManager->execute($statementN, array($groupId));
58  while ($rw = $this->dbManager->fetchArray($res)) {
59  $userChoices[$rw['user_pk']] = $rw['user_desc'] . ' (' . $rw['user_name'] . ')';
60  }
61  $this->dbManager->freeResult($res);
62  return $userChoices;
63  }
64 
71  public function getUsersByGroup($groupId=null)
72  {
73  if (empty($groupId)) {
74  $groupId = Auth::getGroupId();
75  }
76  $userChoices = array();
77  $statementN = __METHOD__;
78  $sql = "SELECT user_pk, user_name FROM users LEFT JOIN group_user_member AS gum ON users.user_pk = gum.user_fk"
79  . " WHERE gum.group_fk = $1 AND users.user_status='active'";
80  $this->dbManager->prepare($statementN, $sql);
81  $res = $this->dbManager->execute($statementN, array($groupId));
82  while ($rw = $this->dbManager->fetchArray($res)) {
83  $userChoices[$rw['user_pk']] = $rw['user_name'];
84  }
85  $this->dbManager->freeResult($res);
86  return $userChoices;
87  }
88 
94  function getAdminGroupMap($userId,$userLevel=0)
95  {
96  if ($userLevel == PLUGIN_DB_ADMIN) {
97  return $this->dbManager->createMap('groups', 'group_pk', 'group_name');
98  }
99  $sql = "SELECT group_pk, group_name FROM groups, group_user_member"
100  . " WHERE group_pk=group_fk AND user_fk=$1 AND group_perm=$2";
101  $param = array($userId,self::ADMIN);
102  $this->dbManager->prepare($stmt=__METHOD__, $sql);
103  $res = $this->dbManager->execute($stmt,$param);
104  $groupMap = array();
105  while ($row = $this->dbManager->fetchArray($res)) {
106  $groupMap[$row['group_pk']] = $row['group_name'];
107  }
108  $this->dbManager->freeResult($res);
109  return $groupMap;
110  }
111 
117  function getUserGroupMap($userId)
118  {
119  $sql = "SELECT group_pk, group_name FROM groups, group_user_member WHERE group_pk=group_fk AND user_fk=$1";
120  $this->dbManager->prepare($stmt=__METHOD__, $sql);
121  $res = $this->dbManager->execute($stmt,array($userId));
122  $groupMap = array();
123  while ($row = $this->dbManager->fetchArray($res)) {
124  $groupMap[$row['group_pk']] = $row['group_name'];
125  }
126  $this->dbManager->freeResult($res);
127  return $groupMap;
128  }
129 
135  function getDeletableAdminGroupMap($userId,$userLevel=0)
136  {
137  if ($userLevel == PLUGIN_DB_ADMIN) {
138  $sql = "SELECT group_pk, group_name FROM groups LEFT JOIN users ON group_name=user_name "
139  . "WHERE user_name IS NULL";
140  $param = array();
141  } else {
142  $sql = "SELECT group_pk, group_name FROM groups LEFT JOIN users ON group_name=user_name "
143  . " INNER JOIN group_user_member ON group_pk=group_user_member.group_fk AND user_fk=$1 AND group_perm=$2 "
144  . "WHERE user_name IS NULL";
145  $param = array($userId,1);
146  }
147  $this->dbManager->prepare($stmt=__METHOD__.".$userLevel", $sql);
148  $res = $this->dbManager->execute($stmt,$param);
149  $groupMap = array();
150  while ($row = $this->dbManager->fetchArray($res)) {
151  $groupMap[$row['group_pk']] = $row['group_name'];
152  }
153  $this->dbManager->freeResult($res);
154  return $groupMap;
155  }
156 
157 
164  function deleteGroup($groupId)
165  {
166  if (!$this->session->isStarted()) {
167  $this->session->setName('Login');
168  $this->session->start();
169  }
170  $groupArray = $this->dbManager->getSingleRow('SELECT group_pk, group_name FROM groups WHERE group_pk=$1',
171  array($groupId),__METHOD__.'.exists');
172  if ($groupArray===false) {
173  throw new \Exception( _("Group does not exist. Not deleted.") );
174  }
175  $groupConstraint = $this->dbManager->getSingleRow('SELECT count(*) cnt FROM users WHERE user_name=$1',
176  array($groupArray['group_name']),__METHOD__.'.contraint');
177  if ($groupConstraint['cnt']) {
178  throw new \Exception( _("Group must not be deleted due to name constraint.") );
179  }
180  if ($_SESSION[Auth::USER_LEVEL] != PLUGIN_DB_ADMIN) {
181  $userId = Auth::getUserId();
182  $adminLevel = $this->dbManager->getSingleRow("SELECT count(*) cnt FROM group_user_member WHERE group_fk=$1 and user_fk=$2 and group_perm=1",
183  array($groupId,$userId),__METHOD__.'.admin_lvl');
184  if ($adminLevel['cnt']< 1) {
185  $text = _("Permission Denied.");
186  throw new \Exception($text);
187  }
188  }
189 
190  $this->dbManager->begin();
191  $this->dbManager->getSingleRow("DELETE FROM perm_upload WHERE group_fk=$1",array($groupId),__METHOD__.'.perm_upload');
192  $this->dbManager->getSingleRow("DELETE FROM group_user_member WHERE group_fk=$1",array($groupId),__METHOD__.'.gum');
193  $this->dbManager->getSingleRow("UPDATE users SET new_upload_group_fk=NULL, new_upload_perm=NULL WHERE new_upload_group_fk=$1",
194  array($groupId),__METHOD__.'.upload_group');
195  $newGroupIdStmt = '(SELECT group_fk FROM group_user_member WHERE user_fk=user_pk LIMIT 1)';
196  $this->dbManager->getSingleRow("UPDATE users SET group_fk=$newGroupIdStmt WHERE group_fk=$1",
197  array($groupId),__METHOD__.'.active_group');
198  $this->dbManager->getSingleRow("DELETE FROM groups WHERE group_pk=$1",array($groupId),__METHOD__.'.delete');
199  $this->dbManager->commit();
200 
201  $newGroupId= $this->dbManager->getSingleRow("SELECT group_fk FROM users WHERE user_pk=$1",
202  array($this->session->get(AUTH::USER_ID)), __METHOD__.'.group_after_update');
203  $_SESSION[Auth::GROUP_ID] = $newGroupId['group_fk'];
204  $this->session->set(Auth::GROUP_ID, $newGroupId['group_fk']);
205 
206  return true;
207  }
208 
209  function updateUserTable()
210  {
211  $statementBasename = __FUNCTION__;
212 
213  /* No users with no seed and no perm -- make them read-only */
214  $this->dbManager->getSingleRow("UPDATE users SET user_perm = $1 WHERE user_perm IS NULL;",
215  array(PLUGIN_DB_READ),
216  $statementBasename . '.setDefaultPermission');
217  /* There must always be at least one default user. */
218  $defaultUser = $this->getUserByName('Default User');
219 
220  if (empty($defaultUser['user_name'])) {
221  $level = PLUGIN_DB_NONE;
222  $this->dbManager->getSingleRow("
223  INSERT INTO users (user_name,user_desc,user_seed,user_pass,user_perm,user_email,root_folder_fk)
224  VALUES ('Default User','Default User when nobody is logged in','Seed','Pass', $1,NULL,1);",
225  array($level), $statementBasename . '.createDefaultUser');
226  }
227  /* There must always be at least one user with user-admin access.
228  If he does not exist, make it SUPER_USER with the same password. */
229  $perm = PLUGIN_DB_ADMIN;
230  $row = $this->getUserByPermission($perm);
231  if (empty($row['user_name'])) {
232  /* No user with PLUGIN_DB_ADMIN access. */
233  $options = array('cost' => 10);
234  $hash = password_hash(self::SUPER_USER, PASSWORD_DEFAULT, $options);
235  $row0 = $this->getUserByName(self::SUPER_USER);
236 
237  if (empty($row0['user_name'])) {
238  $this->dbManager->getSingleRow("
239  INSERT INTO users (user_name, user_desc, user_seed, user_pass, user_perm, user_email, email_notify, root_folder_fk)
240  VALUES ($1,'Default Administrator',$2, $3, $4, $1,'y',1)",
241  array(self::SUPER_USER, 'Seed', $hash, $perm), $statementBasename . '.createDefaultAdmin');
242  } else {
243  $this->dbManager->getSingleRow("UPDATE users SET user_perm = $1, email_notify = 'y'," .
244  " user_email=$2 WHERE user_name =$2",
245  array($perm, self::SUPER_USER), $statementBasename . '.updateDefaultUserToDefaultAdmin');
246  }
247  $row = $this->getUserByPermission($perm);
248  }
249 
250  return empty($row['user_name']) ? 1 : 0;
251  }
252 
257  public function getUserByName($userName)
258  {
259  return $this->dbManager->getSingleRow("SELECT * FROM users WHERE user_name = $1", array($userName), __FUNCTION__);
260  }
261 
266  public function getUserByPk($userPk)
267  {
268  return $this->dbManager->getSingleRow("SELECT * FROM users WHERE user_pk = $1", array($userPk), __FUNCTION__);
269  }
270 
275  public function getGroupIdByName($groupName)
276  {
277  $row = $this->dbManager->getSingleRow("SELECT * FROM groups WHERE group_name = $1", array($groupName), __FUNCTION__);
278  return $row['group_pk'];
279  }
280 
285  private function getUserByPermission($permission)
286  {
287  return $this->dbManager->getSingleRow("SELECT * FROM users WHERE user_perm = $1", array($permission), __FUNCTION__);
288  }
289 
294  public function setDefaultGroupMembership($userId, $groupId)
295  {
296  $this->dbManager->getSingleRow("UPDATE users SET group_fk=$2 WHERE user_pk=$1",
297  array($userId, $groupId), __FUNCTION__);
298  }
299 
300  public function getUserAndDefaultGroupByUserName(&$userName, $oauth=false)
301  {
302  $searchEmail = " ";
303  $statement = __METHOD__;
304  if ($oauth) {
305  $searchEmail = " OR user_email=$1";
306  $statement .= "oauth";
307  }
308  $userRow = $this->dbManager->getSingleRow(
309  "SELECT users.*,group_name FROM users LEFT JOIN groups ON group_fk=group_pk WHERE user_name=$1$searchEmail",
310  array($userName), $statement);
311  if (empty($userRow)) {
312  throw new \Exception('invalid user name');
313  }
314  if ($oauth) {
315  $userName = $userRow['user_name'];
316  }
317  $userRow['oauth'] = $oauth;
318  if ($userRow['group_fk']) {
319  return $userRow;
320  }
321  $groupRow = $this->fixDefaultGroup($userRow['user_pk'],$userName);
322  $this->setDefaultGroupMembership($userRow['user_pk'], $groupRow['group_fk']);
323  $userRow['group_fk'] = $groupRow['group_fk'];
324  $userRow['group_name'] = $groupRow['group_name'];
325  return $userRow;
326  }
327 
332  public function isUserActive($userName)
333  {
334  $row = $this->dbManager->getSingleRow("SELECT user_status FROM users WHERE user_name=$1",
335  array($userName), __METHOD__);
336  return $row!==false && ($row['user_status']==self::USER_ACTIVE_STATUS);
337  }
338 
343  public function isUserIdActive($userId)
344  {
345  $row = $this->dbManager->getSingleRow("SELECT user_status FROM users WHERE user_pk=$1",
346  array($userId), __METHOD__);
347  return $row!==false && ($row['user_status']==self::USER_ACTIVE_STATUS);
348  }
349 
353  public function updateUserLastConnection($userId)
354  {
355  $this->dbManager->getSingleRow("UPDATE users SET last_connection=now() WHERE user_pk=$1",
356  array($userId), __FUNCTION__);
357  }
358 
364  private function fixDefaultGroup($userId, $groupName)
365  {
366  $groupRow = $this->dbManager->getSingleRow(
367  "SELECT group_fk,group_name FROM group_user_member LEFT JOIN groups ON group_fk=group_pk WHERE user_fk=$1",
368  array($userId), __FUNCTION__.".getGroup");
369  if ($groupRow) {
370  return $groupRow;
371  }
372 
373  $groupId = $this->getGroupIdByName($groupName);
374  if (empty($groupId)) {
375  $groupId = $this->addGroup($groupName);
376  $this->addGroupMembership($groupId, $userId);
377  }
378 
379  return array('group_fk'=>$groupId,'group_name'=>$groupName);
380  }
381 
382  public function isAdvisorOrAdmin($userId, $groupId)
383  {
384  $row = $this->dbManager->getSingleRow("SELECT group_perm FROM group_user_member WHERE user_fk=$1 AND group_fk=$2",
385  array($userId, $groupId), __METHOD__);
386  return $row!==false && ($row['group_perm']==self::ADVISOR || $row['group_perm']==self::ADMIN);
387  }
388 
394  public function addGroup($groupName)
395  {
396  if (empty($groupName)) {
397  throw new \Exception(_("Error: Group name must be specified."));
398  }
399 
400  $groupAlreadyExists = $this->dbManager->getSingleRow("SELECT group_pk, group_name FROM groups WHERE LOWER(group_name)=LOWER($1)",
401  array($groupName),
402  __METHOD__.'.gExists');
403  if ($groupAlreadyExists) {
404  throw new \Exception(_("Group exists. Try different Name, Group-Name checking is case-insensitive and Duplicate not allowed"));
405  }
406 
407  $this->dbManager->insertTableRow('groups', array('group_name'=>$groupName));
408  $groupNowExists = $this->dbManager->getSingleRow("SELECT * FROM groups WHERE group_name=$1",
409  array($groupName),
410  __METHOD__.'.gNowExists');
411  if (!$groupNowExists) {
412  throw new \Exception(_("Failed to create group"));
413  }
414  return $groupNowExists['group_pk'];
415  }
416 
417  public function addGroupMembership($groupId, $userId, $groupPerm=1)
418  {
419  $this->dbManager->insertTableRow('group_user_member',
420  array('group_fk'=>$groupId,'user_fk'=>$userId,'group_perm'=>$groupPerm));
421  }
422 
427  public function getUserName($userId)
428  {
429  $userRow = $this->dbManager->getSingleRow("SELECT user_name FROM users WHERE user_pk=$1",array($userId),__METHOD__);
430  if (!$userRow) {
431  throw new \Exception('unknown user with id='.$userId);
432  }
433  return $userRow['user_name'];
434  }
435 
440  public function getGroupNameById($groupId)
441  {
442  $groupRow = $this->dbManager->getSingleRow("SELECT group_name FROM groups WHERE group_pk = $1",array($groupId),__METHOD__);
443  if (empty($groupRow)) {
444  throw new \Exception('Error: GroupId ='. $groupId .' not a member of a valid group.');
445  }
446  return $groupRow['group_name'];
447  }
448 
453  public function getUserEmail($userId)
454  {
455  $userRow = $this->dbManager->getSingleRow("SELECT user_email FROM users WHERE user_pk=$1",array($userId),__METHOD__);
456  if (!$userRow) {
457  throw new \Exception('unknown user with id='.$userId);
458  }
459  return $userRow['user_email'];
460  }
461 
466  public function getAllUsers()
467  {
468  return $this->dbManager->getRows("SELECT * FROM users ORDER BY user_name;");
469  }
470 
475  function editGroup($groupId, $newGroupName)
476  {
477  $this->dbManager->getSingleRow('UPDATE groups SET group_name=$2 WHERE group_pk=$1;',
478  array($groupId, $newGroupName),__METHOD__.'.UpdateEditGroup');
479  }
480 }
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
static getUserId()
Get the current user's id.
Definition: Auth.php:68
static getGroupId()
Get the current user's group id.
Definition: Auth.php:80
getGroupIdByName($groupName)
Definition: UserDao.php:275
setDefaultGroupMembership($userId, $groupId)
Definition: UserDao.php:294
fixDefaultGroup($userId, $groupName)
Definition: UserDao.php:364
getUserByName($userName)
Definition: UserDao.php:257
editGroup($groupId, $newGroupName)
Definition: UserDao.php:475
getUserChoices($groupId=null)
Definition: UserDao.php:47
getUsersByGroup($groupId=null)
Definition: UserDao.php:71
getDeletableAdminGroupMap($userId, $userLevel=0)
get array of groups that this user has admin access to
Definition: UserDao.php:135
getUserGroupMap($userId)
get array of groups that this user has admin access to
Definition: UserDao.php:117
deleteGroup($groupId)
Delete a group (for constraint, see http://www.fossology.org/projects/fossology/wiki/GroupsPerms )
Definition: UserDao.php:164
updateUserLastConnection($userId)
Definition: UserDao.php:353
getAdminGroupMap($userId, $userLevel=0)
get array of groups that this user has admin access to
Definition: UserDao.php:94
getUserByPermission($permission)
Definition: UserDao.php:285
getGroupNameById($groupId)
Definition: UserDao.php:440
#define PLUGIN_DB_NONE
Plugin requires no DB permission.
Definition: libfossology.h:36
#define PLUGIN_DB_READ
Plugin requires read permission on DB.
Definition: libfossology.h:37
#define PLUGIN_DB_ADMIN
Plugin requires admin level permission on DB.
Definition: libfossology.h:39
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16