FOSSology  4.4.0
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 
70  function getAdminGroupMap($userId,$userLevel=0)
71  {
72  if ($userLevel == PLUGIN_DB_ADMIN) {
73  return $this->dbManager->createMap('groups', 'group_pk', 'group_name');
74  }
75  $sql = "SELECT group_pk, group_name FROM groups, group_user_member"
76  . " WHERE group_pk=group_fk AND user_fk=$1 AND group_perm=$2";
77  $param = array($userId,self::ADMIN);
78  $this->dbManager->prepare($stmt=__METHOD__, $sql);
79  $res = $this->dbManager->execute($stmt,$param);
80  $groupMap = array();
81  while ($row = $this->dbManager->fetchArray($res)) {
82  $groupMap[$row['group_pk']] = $row['group_name'];
83  }
84  $this->dbManager->freeResult($res);
85  return $groupMap;
86  }
87 
93  function getUserGroupMap($userId)
94  {
95  $sql = "SELECT group_pk, group_name FROM groups, group_user_member WHERE group_pk=group_fk AND user_fk=$1";
96  $this->dbManager->prepare($stmt=__METHOD__, $sql);
97  $res = $this->dbManager->execute($stmt,array($userId));
98  $groupMap = array();
99  while ($row = $this->dbManager->fetchArray($res)) {
100  $groupMap[$row['group_pk']] = $row['group_name'];
101  }
102  $this->dbManager->freeResult($res);
103  return $groupMap;
104  }
105 
111  function getDeletableAdminGroupMap($userId,$userLevel=0)
112  {
113  if ($userLevel == PLUGIN_DB_ADMIN) {
114  $sql = "SELECT group_pk, group_name FROM groups LEFT JOIN users ON group_name=user_name "
115  . "WHERE user_name IS NULL";
116  $param = array();
117  } else {
118  $sql = "SELECT group_pk, group_name FROM groups LEFT JOIN users ON group_name=user_name "
119  . " INNER JOIN group_user_member ON group_pk=group_user_member.group_fk AND user_fk=$1 AND group_perm=$2 "
120  . "WHERE user_name IS NULL";
121  $param = array($userId,1);
122  }
123  $this->dbManager->prepare($stmt=__METHOD__.".$userLevel", $sql);
124  $res = $this->dbManager->execute($stmt,$param);
125  $groupMap = array();
126  while ($row = $this->dbManager->fetchArray($res)) {
127  $groupMap[$row['group_pk']] = $row['group_name'];
128  }
129  $this->dbManager->freeResult($res);
130  return $groupMap;
131  }
132 
133 
140  function deleteGroup($groupId)
141  {
142  if (!$this->session->isStarted()) {
143  $this->session->setName('Login');
144  $this->session->start();
145  }
146  $groupArray = $this->dbManager->getSingleRow('SELECT group_pk, group_name FROM groups WHERE group_pk=$1',
147  array($groupId),__METHOD__.'.exists');
148  if ($groupArray===false) {
149  throw new \Exception( _("Group does not exist. Not deleted.") );
150  }
151  $groupConstraint = $this->dbManager->getSingleRow('SELECT count(*) cnt FROM users WHERE user_name=$1',
152  array($groupArray['group_name']),__METHOD__.'.contraint');
153  if ($groupConstraint['cnt']) {
154  throw new \Exception( _("Group must not be deleted due to name constraint.") );
155  }
156  if ($_SESSION[Auth::USER_LEVEL] != PLUGIN_DB_ADMIN) {
157  $userId = Auth::getUserId();
158  $adminLevel = $this->dbManager->getSingleRow("SELECT count(*) cnt FROM group_user_member WHERE group_fk=$1 and user_fk=$2 and group_perm=1",
159  array($groupId,$userId),__METHOD__.'.admin_lvl');
160  if ($adminLevel['cnt']< 1) {
161  $text = _("Permission Denied.");
162  throw new \Exception($text);
163  }
164  }
165 
166  $this->dbManager->begin();
167  $this->dbManager->getSingleRow("DELETE FROM perm_upload WHERE group_fk=$1",array($groupId),__METHOD__.'.perm_upload');
168  $this->dbManager->getSingleRow("DELETE FROM group_user_member WHERE group_fk=$1",array($groupId),__METHOD__.'.gum');
169  $this->dbManager->getSingleRow("UPDATE users SET new_upload_group_fk=NULL, new_upload_perm=NULL WHERE new_upload_group_fk=$1",
170  array($groupId),__METHOD__.'.upload_group');
171  $newGroupIdStmt = '(SELECT group_fk FROM group_user_member WHERE user_fk=user_pk LIMIT 1)';
172  $this->dbManager->getSingleRow("UPDATE users SET group_fk=$newGroupIdStmt WHERE group_fk=$1",
173  array($groupId),__METHOD__.'.active_group');
174  $this->dbManager->getSingleRow("DELETE FROM groups WHERE group_pk=$1",array($groupId),__METHOD__.'.delete');
175  $this->dbManager->commit();
176 
177  $newGroupId= $this->dbManager->getSingleRow("SELECT group_fk FROM users WHERE user_pk=$1",
178  array($this->session->get(AUTH::USER_ID)), __METHOD__.'.group_after_update');
179  $_SESSION[Auth::GROUP_ID] = $newGroupId['group_fk'];
180  $this->session->set(Auth::GROUP_ID, $newGroupId['group_fk']);
181 
182  return true;
183  }
184 
185  function updateUserTable()
186  {
187  $statementBasename = __FUNCTION__;
188 
189  /* No users with no seed and no perm -- make them read-only */
190  $this->dbManager->getSingleRow("UPDATE users SET user_perm = $1 WHERE user_perm IS NULL;",
191  array(PLUGIN_DB_READ),
192  $statementBasename . '.setDefaultPermission');
193  /* There must always be at least one default user. */
194  $defaultUser = $this->getUserByName('Default User');
195 
196  if (empty($defaultUser['user_name'])) {
197  $level = PLUGIN_DB_NONE;
198  $this->dbManager->getSingleRow("
199  INSERT INTO users (user_name,user_desc,user_seed,user_pass,user_perm,user_email,root_folder_fk)
200  VALUES ('Default User','Default User when nobody is logged in','Seed','Pass', $1,NULL,1);",
201  array($level), $statementBasename . '.createDefaultUser');
202  }
203  /* There must always be at least one user with user-admin access.
204  If he does not exist, make it SUPER_USER with the same password. */
205  $perm = PLUGIN_DB_ADMIN;
206  $row = $this->getUserByPermission($perm);
207  if (empty($row['user_name'])) {
208  /* No user with PLUGIN_DB_ADMIN access. */
209  $options = array('cost' => 10);
210  $hash = password_hash(self::SUPER_USER, PASSWORD_DEFAULT, $options);
211  $row0 = $this->getUserByName(self::SUPER_USER);
212 
213  if (empty($row0['user_name'])) {
214  $this->dbManager->getSingleRow("
215  INSERT INTO users (user_name, user_desc, user_seed, user_pass, user_perm, user_email, email_notify, root_folder_fk)
216  VALUES ($1,'Default Administrator',$2, $3, $4, $1,'y',1)",
217  array(self::SUPER_USER, 'Seed', $hash, $perm), $statementBasename . '.createDefaultAdmin');
218  } else {
219  $this->dbManager->getSingleRow("UPDATE users SET user_perm = $1, email_notify = 'y'," .
220  " user_email=$2 WHERE user_name =$2",
221  array($perm, self::SUPER_USER), $statementBasename . '.updateDefaultUserToDefaultAdmin');
222  }
223  $row = $this->getUserByPermission($perm);
224  }
225 
226  return empty($row['user_name']) ? 1 : 0;
227  }
228 
233  public function getUserByName($userName)
234  {
235  return $this->dbManager->getSingleRow("SELECT * FROM users WHERE user_name = $1", array($userName), __FUNCTION__);
236  }
237 
242  public function getUserByPk($userPk)
243  {
244  return $this->dbManager->getSingleRow("SELECT * FROM users WHERE user_pk = $1", array($userPk), __FUNCTION__);
245  }
246 
251  public function getGroupIdByName($groupName)
252  {
253  $row = $this->dbManager->getSingleRow("SELECT * FROM groups WHERE group_name = $1", array($groupName), __FUNCTION__);
254  return $row['group_pk'];
255  }
256 
261  private function getUserByPermission($permission)
262  {
263  return $this->dbManager->getSingleRow("SELECT * FROM users WHERE user_perm = $1", array($permission), __FUNCTION__);
264  }
265 
270  public function setDefaultGroupMembership($userId, $groupId)
271  {
272  $this->dbManager->getSingleRow("UPDATE users SET group_fk=$2 WHERE user_pk=$1",
273  array($userId, $groupId), __FUNCTION__);
274  }
275 
276  public function getUserAndDefaultGroupByUserName(&$userName, $oauth=false)
277  {
278  $searchEmail = " ";
279  $statement = __METHOD__;
280  if ($oauth) {
281  $searchEmail = " OR user_email=$1";
282  $statement .= "oauth";
283  }
284  $userRow = $this->dbManager->getSingleRow(
285  "SELECT users.*,group_name FROM users LEFT JOIN groups ON group_fk=group_pk WHERE user_name=$1$searchEmail",
286  array($userName), $statement);
287  if (empty($userRow)) {
288  throw new \Exception('invalid user name');
289  }
290  if ($oauth) {
291  $userName = $userRow['user_name'];
292  }
293  $userRow['oauth'] = $oauth;
294  if ($userRow['group_fk']) {
295  return $userRow;
296  }
297  $groupRow = $this->fixDefaultGroup($userRow['user_pk'],$userName);
298  $this->setDefaultGroupMembership($userRow['user_pk'], $groupRow['group_fk']);
299  $userRow['group_fk'] = $groupRow['group_fk'];
300  $userRow['group_name'] = $groupRow['group_name'];
301  return $userRow;
302  }
303 
308  public function isUserActive($userName)
309  {
310  $row = $this->dbManager->getSingleRow("SELECT user_status FROM users WHERE user_name=$1",
311  array($userName), __METHOD__);
312  return $row!==false && ($row['user_status']==self::USER_ACTIVE_STATUS);
313  }
314 
319  public function isUserIdActive($userId)
320  {
321  $row = $this->dbManager->getSingleRow("SELECT user_status FROM users WHERE user_pk=$1",
322  array($userId), __METHOD__);
323  return $row!==false && ($row['user_status']==self::USER_ACTIVE_STATUS);
324  }
325 
329  public function updateUserLastConnection($userId)
330  {
331  $this->dbManager->getSingleRow("UPDATE users SET last_connection=now() WHERE user_pk=$1",
332  array($userId), __FUNCTION__);
333  }
334 
340  private function fixDefaultGroup($userId, $groupName)
341  {
342  $groupRow = $this->dbManager->getSingleRow(
343  "SELECT group_fk,group_name FROM group_user_member LEFT JOIN groups ON group_fk=group_pk WHERE user_fk=$1",
344  array($userId), __FUNCTION__.".getGroup");
345  if ($groupRow) {
346  return $groupRow;
347  }
348 
349  $groupId = $this->getGroupIdByName($groupName);
350  if (empty($groupId)) {
351  $groupId = $this->addGroup($groupName);
352  $this->addGroupMembership($groupId, $userId);
353  }
354 
355  return array('group_fk'=>$groupId,'group_name'=>$groupName);
356  }
357 
358  public function isAdvisorOrAdmin($userId, $groupId)
359  {
360  $row = $this->dbManager->getSingleRow("SELECT group_perm FROM group_user_member WHERE user_fk=$1 AND group_fk=$2",
361  array($userId, $groupId), __METHOD__);
362  return $row!==false && ($row['group_perm']==self::ADVISOR || $row['group_perm']==self::ADMIN);
363  }
364 
370  public function addGroup($groupName)
371  {
372  if (empty($groupName)) {
373  throw new \Exception(_("Error: Group name must be specified."));
374  }
375 
376  $groupAlreadyExists = $this->dbManager->getSingleRow("SELECT group_pk, group_name FROM groups WHERE LOWER(group_name)=LOWER($1)",
377  array($groupName),
378  __METHOD__.'.gExists');
379  if ($groupAlreadyExists) {
380  throw new \Exception(_("Group exists. Try different Name, Group-Name checking is case-insensitive and Duplicate not allowed"));
381  }
382 
383  $this->dbManager->insertTableRow('groups', array('group_name'=>$groupName));
384  $groupNowExists = $this->dbManager->getSingleRow("SELECT * FROM groups WHERE group_name=$1",
385  array($groupName),
386  __METHOD__.'.gNowExists');
387  if (!$groupNowExists) {
388  throw new \Exception(_("Failed to create group"));
389  }
390  return $groupNowExists['group_pk'];
391  }
392 
393  public function addGroupMembership($groupId, $userId, $groupPerm=1)
394  {
395  $this->dbManager->insertTableRow('group_user_member',
396  array('group_fk'=>$groupId,'user_fk'=>$userId,'group_perm'=>$groupPerm));
397  }
398 
403  public function getUserName($userId)
404  {
405  $userRow = $this->dbManager->getSingleRow("SELECT user_name FROM users WHERE user_pk=$1",array($userId),__METHOD__);
406  if (!$userRow) {
407  throw new \Exception('unknown user with id='.$userId);
408  }
409  return $userRow['user_name'];
410  }
411 
416  public function getGroupNameById($groupId)
417  {
418  $groupRow = $this->dbManager->getSingleRow("SELECT group_name FROM groups WHERE group_pk = $1",array($groupId),__METHOD__);
419  if (empty($groupRow)) {
420  throw new \Exception('Error: GroupId ='. $groupId .' not a member of a valid group.');
421  }
422  return $groupRow['group_name'];
423  }
424 
429  public function getUserEmail($userId)
430  {
431  $userRow = $this->dbManager->getSingleRow("SELECT user_email FROM users WHERE user_pk=$1",array($userId),__METHOD__);
432  if (!$userRow) {
433  throw new \Exception('unknown user with id='.$userId);
434  }
435  return $userRow['user_email'];
436  }
437 
442  public function getAllUsers()
443  {
444  return $this->dbManager->getRows("SELECT * FROM users ORDER BY user_name;");
445  }
446 }
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:251
setDefaultGroupMembership($userId, $groupId)
Definition: UserDao.php:270
fixDefaultGroup($userId, $groupName)
Definition: UserDao.php:340
getUserByName($userName)
Definition: UserDao.php:233
getUserChoices($groupId=null)
Definition: UserDao.php:47
getDeletableAdminGroupMap($userId, $userLevel=0)
get array of groups that this user has admin access to
Definition: UserDao.php:111
getUserGroupMap($userId)
get array of groups that this user has admin access to
Definition: UserDao.php:93
deleteGroup($groupId)
Delete a group (for constraint, see http://www.fossology.org/projects/fossology/wiki/GroupsPerms )
Definition: UserDao.php:140
updateUserLastConnection($userId)
Definition: UserDao.php:329
getAdminGroupMap($userId, $userLevel=0)
get array of groups that this user has admin access to
Definition: UserDao.php:70
getUserByPermission($permission)
Definition: UserDao.php:261
getGroupNameById($groupId)
Definition: UserDao.php:416
#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