21 use Symfony\Component\HttpFoundation\Request;
25 const NAME =
"user_edit";
40 function __construct()
42 parent::__construct(self::NAME, array(
43 self::TITLE => _(
"Edit User Account"),
44 self::MENU_LIST =>
'Admin::Users::Edit User Account',
45 self::REQUIRES_LOGIN =>
true,
50 $this->authHelper = $this->
getObject(
'helper.authHelper');
51 $this->userDao = $this->
getObject(
'dao.user');
66 $user_pk = Auth::getUserId();
72 $vars = array(
'refreshUri' =>
Traceback_uri() .
"?mod=" . self::NAME);
76 $newClient = $this->addNewClient($request);
77 }
catch (\Exception $e) {
78 $newClient = $e->getMessage();
83 $newToken = $this->generateNewToken($request);
84 }
catch (\Exception $e) {
85 $vars[
'message'] = $e->getMessage();
89 $user_pk_to_modify = intval($request->get(
'user_pk'));
90 if (! ($SessionIsAdmin || empty($user_pk_to_modify) ||
91 $user_pk == $user_pk_to_modify)) {
92 $vars[
'content'] = _(
"Your request is not valid.");
93 return $this->
render(
'include/base.html.twig', $this->mergeWithDefault($vars));
100 $BtnText = $request->get(
'UpdateBtn');
101 if (! empty($BtnText)) {
105 $rv = $this->
UpdateUser($UserRec, $SessionIsAdmin);
108 $vars[
'message'] =
"User $UserRec[user_name] updated.";
111 $UserRec = $this->
CreateUserRec($request, $UserRec[
'user_pk']);
112 if ($user_pk == $user_pk_to_modify) {
113 $_SESSION[
'User'] = $UserRec[
'user_name'];
116 if (empty($UserRec[
'user_name']) || $_SESSION[
'User'] != $UserRec[
'user_name']) {
117 $UserRec = $this->
CreateUserRec($request, $UserRec[
'user_pk']);
119 $vars[
'message'] = $rv;
122 $NewUserpk = intval($request->get(
'newuser'));
127 $vars = array_merge($vars, $this->
DisplayForm($UserRec, $SessionIsAdmin));
128 $vars[
'userId'] = $UserRec[
'user_pk'];
129 $vars[
'newToken'] = $newToken;
130 $vars[
'newClient'] = $newClient;
135 $vars[
'maxTokenDate'] = $this->authHelper->getMaxTokenValidity();
136 $vars[
'writeAccess'] = ($_SESSION[Auth::USER_LEVEL] >= 3);
138 $vars[
'policyDisabled'] =
"true";
139 $vars[
'formName'] =
"user_edit";
140 $vars[
'passwordPolicy'] =
"";
142 if ($policy !=
"No policy defined.") {
143 $vars[
'passwordPolicy'] = $policy;
145 $restToken = Auth::getRestTokenType();
146 if ($restToken == Auth::TOKEN_OAUTH) {
147 $restToken =
"oauth";
148 } elseif ($restToken == Auth::TOKEN_BOTH) {
151 $restToken =
"token";
153 $vars[
'resttoken'] = $restToken;
155 return $this->
render(
'user_edit.html.twig', $this->mergeWithDefault($vars));
169 $vars = array(
'isSessionAdmin' => $SessionIsAdmin,
170 'userId' => $UserRec[
'user_pk']);
171 $vars[
'userDescReadOnly'] = $SysConf[
'SYSCONFIG'][
'UserDescReadOnly'];
176 if ($SessionIsAdmin) {
177 $stmt = __METHOD__ .
'.asSessionAdmin';
178 $sql =
"SELECT * FROM users ORDER BY user_name";
182 while ($row = $this->
dbManager->fetchArray($res)) {
183 $allUsers[$row[
'user_pk']] = htmlentities($row[
'user_name']);
186 $vars[
'allUsers'] = $allUsers;
189 $vars[
'userName'] = $UserRec[
'user_name'];
190 $vars[
'userDescription'] = $UserRec[
'user_desc'];
191 $vars[
'userEMail'] = $UserRec[
"user_email"];
192 $vars[
'eMailNotification'] = ($UserRec[
'email_notify'] ==
'y');
193 $spdxSettings = isset($UserRec[
'spdx_settings']) ? explode(
',', $UserRec[
'spdx_settings']) : [
'unchecked',
'unchecked',
'unchecked'];
194 if (count($spdxSettings) < 3) {
195 $spdxSettings = array_pad($spdxSettings, 3,
'unchecked');
197 $vars[
'osselotExportEnabled'] = ($spdxSettings[0] ===
'checked');
198 $vars[
'spdxLicenseCommentDefault'] = ($spdxSettings[1] ===
'checked');
199 $vars[
'ignoreFilesWOInfoDefault'] = ($spdxSettings[2] ===
'checked');
201 if ($SessionIsAdmin) {
202 $vars[
'allAccessLevels'] = array(
204 PLUGIN_DB_READ => _(
"Read-only (read, but no writes or downloads)"),
205 PLUGIN_DB_WRITE => _(
"Read-Write (read, download, or edit information)"),
206 PLUGIN_DB_CADMIN => _(
"Clearing Administrator (read, download, edit information and edit decisions)"),
207 PLUGIN_DB_ADMIN => _(
"Full Administrator (all access including adding and deleting users)")
209 $vars[
'accessLevel'] = $UserRec[
'user_perm'];
211 $vars[
'allUserStatuses'] = array(
212 "active" => _(
"Active"),
213 "inactive" => _(
"Inactive")
216 $vars[
'userStatus'] = $UserRec[
'user_status'];
218 $SelectedFolderPk = $UserRec[
'root_folder_fk'];
219 $vars[
'folderListOption'] =
FolderListOption($ParentFolder = -1, $Depth = 0, $IncludeTop = 1, $SelectedFolderPk);
222 $SelectedDefaultFolderPk = $UserRec[
'default_folder_fk'];
223 $vars[
'folderListOption2'] =
FolderListOption($ParentFolder = $UserRec[
'root_folder_fk'], $Depth = 0, $IncludeTop = 1, $SelectedDefaultFolderPk);
225 $vars[
'isBlankPassword'] = ($UserRec[
'_blank_pass'] ==
'on');
227 "agent_adj2nest",
"wget_agent"), $UserRec[
'user_name']);
230 $vars[
'uploadVisibility'] = $UserRec[
'upload_visibility'];
249 if (empty($UserRec[
'user_pk'])) {
250 $Errors .=
"<li>" . _(
"Consistency error (User_pk missing). Please start over.") .
"</li>";
254 if (empty($UserRec[
'user_name'])) {
255 $Errors .=
"<li>" . _(
"Username must be specified.") .
"</li>";
259 $CheckUserRec =
GetSingleRec(
"users",
"WHERE user_name='$UserRec[user_name]'");
260 if ((!empty($CheckUserRec)) and ( $CheckUserRec[
'user_pk'] != $UserRec[
'user_pk'])) {
261 $Errors .=
"<li>" . _(
"Username is not unique.") .
"</li>";
265 if ($UserRec[
'_pass1'] != $UserRec[
'_pass2']) {
266 $Errors .=
"<li>" . _(
"Passwords do not match.") .
"</li>";
269 $oldEmail = $this->
dbManager->getSingleRow(
270 "SELECT user_email FROM users WHERE user_pk = $1;",
271 array($UserRec[
'user_pk']), __METHOD__.
"oldEmail");
272 if (strcmp($oldEmail[
'user_email'],$UserRec[
'user_email']) != 0) {
274 $Check = preg_replace(
"/[^a-zA-Z0-9@_.+-]/",
"", $UserRec[
'user_email']);
275 if ($Check != $UserRec[
'user_email']) {
276 $Errors .=
"<li>" . _(
"Invalid email address.") .
"</li>";
281 if (!empty($UserRec[
'user_email'])) {
282 $email_count = $this->
dbManager->getSingleRow(
283 "SELECT COUNT(*) as count FROM users WHERE user_email = $1 LIMIT 1;",
284 array($UserRec[
'user_email']), __METHOD__.
"email_count")[
"count"];
286 if ($email_count > 0) {
287 $Errors .=
"<li>" . _(
"Email address already exists.") .
"</li>";
293 $Errors .=
"<li>" . _(
"Password policy enabled, can't have a blank password.") .
"</li>";
297 if (!empty($UserRec[
'_blank_pass']) && ( !empty($UserRec[
'_pass1']) || ! empty($UserRec[
'_pass2']))) {
298 $Errors .=
"<li>" . _(
"You cannot specify both a password and a blank password.") .
"</li>";
302 if (!empty($UserRec[
'_pass1']) && !empty($UserRec[
'_pass2'])) {
304 $result = preg_match(
'/^' . $policyRegex .
'$/m', $UserRec[
'_pass1']);
306 $Errors .=
"<li>" . _(
"Password does not match policy.");
313 if (!empty($UserRec[
'group_fk'])) {
314 $group_map = $this->userDao->getUserGroupMap($UserRec[
'user_pk']);
315 if (!in_array($UserRec[
'group_fk'], array_keys($group_map))) {
316 $Errors .=
"<li>" . _(
"User is not member of provided group.") .
322 if ((!Auth::isAdmin()) && ($UserRec[
'user_name'] != $_SESSION[
'User'])) {
323 $Errors .=
"<li>" . _(
"Only admin can change the username.") .
"</li>";
327 if (!empty($Errors)) {
328 return _(
"Errors") .
":<ol>$Errors </ol>";
333 if (!empty($UserRec[
'_blank_pass']) ) {
334 $UserRec[
'user_seed'] =
'';
335 $options = array(
'cost' => 10);
336 $UserRec[
'user_pass'] = password_hash(
"", PASSWORD_DEFAULT, $options);
337 }
else if (empty($UserRec[
'_pass1'])) {
338 unset( $UserRec[
'user_pass']);
339 unset( $UserRec[
'user_seed']);
343 $sql =
"UPDATE users SET ";
345 foreach ($UserRec as $key=>$val) {
346 if ($key[0] ==
'_' || $key ==
"user_pk") {
349 if (!$SessionIsAdmin && ($key ==
"user_perm" || $key ==
"root_folder_fk" || $key ==
"user_status")) {
355 $sql .=
"$key='" . pg_escape_string($val) .
"'";
358 $sql .=
" WHERE user_pk=$UserRec[user_pk]";
361 pg_free_result($result);
375 if (empty($user_pk)) {
376 throw new Exception(
"Invalid access. Your session has expired.",1);
379 $UserRec =
GetSingleRec(
"users",
"WHERE user_pk=$user_pk");
380 if (empty($UserRec)) {
381 throw new Exception(
"Invalid user. ",1);
411 if (!empty($user_pk)) {
413 $UserRec[
'_pass1'] =
"";
414 $UserRec[
'_pass2'] =
"";
415 $UserRec[
'_blank_pass'] = password_verify(
'', $UserRec[
'user_pass']) ?
"on" :
"";
418 $UserRec[
'user_pk'] = intval($request->get(
'user_pk'));
419 $UserRec[
'user_name'] = stripslashes($request->get(
'user_name'));
420 $UserRec[
'root_folder_fk'] = intval($request->get(
'root_folder_fk'));
421 $UserRec[
'upload_visibility'] = stripslashes($request->get(
'public'));
422 $UserRec[
'default_folder_fk'] = intval($request->get(
'default_folder_fk'));
423 $UserRec[
'user_desc'] = stripslashes($request->get(
'user_desc'));
424 $defaultGroup = $request->get(
'default_group_fk',
null);
425 if ($defaultGroup !==
null) {
426 $UserRec[
'group_fk'] = intval($defaultGroup);
429 $UserRec[
'_pass1'] = stripslashes($request->get(
'_pass1'));
430 $UserRec[
'_pass2'] = stripslashes($request->get(
'_pass2'));
431 if (!empty($UserRec[
'_pass1'])) {
432 $UserRec[
'user_seed'] =
'Seed';
433 $options = array(
'cost' => 10);
434 $UserRec[
'user_pass'] = password_hash($UserRec[
'_pass1'], PASSWORD_DEFAULT, $options);
435 $UserRec[
'_blank_pass'] =
"";
437 $UserRec[
'user_pass'] =
"";
438 $UserRec[
'_blank_pass'] = stripslashes($request->get(
"_blank_pass"));
439 if (empty($UserRec[
'_blank_pass'])) {
440 $StoredUserRec = $this->
GetUserRec($UserRec[
'user_pk']);
441 $options = array(
'cost' => 10);
442 $UserRec[
'_blank_pass'] = password_verify($StoredUserRec[
'user_pass'], password_hash(
"", PASSWORD_DEFAULT, $options)) ?
"on" :
"";
446 $UserRec[
'user_perm'] = intval($request->get(
'user_perm'));
447 $UserRec[
'user_status'] = stripslashes($request->get(
'user_status'));
448 $UserRec[
'user_email'] = stripslashes($request->get(
'user_email'));
449 $UserRec[
'email_notify'] = stripslashes($request->get(
'email_notify'));
450 if (!empty($UserRec[
'email_notify'])) {
451 $UserRec[
'email_notify'] =
'y';
453 $UserRec[
'user_agent_list'] = is_null($request->get(
'user_agent_list')) ?
userAgents() : $request->get(
'user_agent_list');
454 $UserRec[
'default_bucketpool_fk'] = intval($request->get(
"default_bucketpool_fk"));
456 if ($this->
dbManager->existsColumn(
'users',
'spdx_settings')) {
457 $osselotEnabled = !empty($request->get(
'osselot_export_enabled')) ?
'checked' :
'unchecked';
458 $spdxCommentEnabled = !empty($request->get(
'spdx_license_comment_default')) ?
'checked' :
'unchecked';
459 $ignoreFilesEnabled = !empty($request->get(
'ignore_files_wo_info_default')) ?
'checked' :
'unchecked';
461 $UserRec[
'spdx_settings'] =
"$osselotEnabled,$spdxCommentEnabled,$ignoreFilesEnabled";
478 function generateNewToken(Request $request)
482 $user_pk = Auth::getUserId();
483 $tokenName = $request->get(
'pat_name');
484 $tokenExpiry = $request->get(
'pat_expiry');
485 if ($_SESSION[Auth::USER_LEVEL] < 3) {
488 $tokenScope = $request->get(
'pat_scope');
490 $tokenScope = array_search($tokenScope, RestHelper::SCOPE_DB_MAP);
491 if ($tokenScope ===
false) {
492 throw new \UnexpectedValueException(
"Invalid token scope " .
493 $request->get(
'pat_scope') .
".");
495 $tokenScope = RestHelper::SCOPE_DB_MAP[$tokenScope];
497 $restHelper = $container->get(
'helper.restHelper');
499 $restHelper->validateTokenRequest($tokenExpiry, $tokenName, $tokenScope);
501 throw new \UnexpectedValueException($e->getMessage());
505 $restDbHelper = $container->get(
'helper.dbHelper');
507 openssl_random_pseudo_bytes(RestHelper::TOKEN_KEY_LENGTH / 2));
509 $jti = $restDbHelper->insertNewTokenKey($user_pk, $tokenExpiry,
510 $tokenScope, $tokenName, $key);
514 openssl_random_pseudo_bytes(RestHelper::TOKEN_KEY_LENGTH / 2));
516 $jti = $restDbHelper->insertNewTokenKey($user_pk, $tokenExpiry,
517 $tokenScope, $tokenName, $key);
525 throw new \UnexpectedValueException($e->getMessage());
527 return $this->authHelper->generateJwtToken($tokenExpiry,
528 $jti[
'created_on'], $jti[
'jti'], $tokenScope, $key);
540 $user_pk = Auth::getUserId();
541 $sql =
"SELECT pat_pk, user_fk, expire_on, token_scope, token_name, created_on, active " .
542 "FROM personal_access_tokens " .
543 "WHERE user_fk = $1 AND active = true AND client_id IS NULL;";
544 $rows = $this->
dbManager->getRows($sql, [$user_pk],
545 __METHOD__ .
".getActiveTokens");
547 foreach ($rows as $row) {
549 $this->authHelper->isTokenActive($row, $row[
"pat_pk"]);
554 "id" => $row[
"pat_pk"] .
"." . $user_pk,
555 "name" => $row[
"token_name"],
556 "created" => $row[
"created_on"],
557 "expire" => $row[
"expire_on"],
558 "scope" => $row[
"token_scope"]
560 $response[] = $entry;
562 array_multisort(array_column($response,
"created"), SORT_ASC, $response);
572 $user_pk = Auth::getUserId();
574 $sql =
"SELECT pat_pk, user_fk, expire_on, token_scope, token_name, created_on " .
575 "FROM personal_access_tokens " .
576 "WHERE user_fk = $1 AND active = false " .
577 "AND expire_on >= (SELECT CURRENT_DATE - ($2)::integer) " .
578 "AND client_id IS NULL;";
579 $rows = $this->
dbManager->getRows($sql, [$user_pk, $retentionPeriod],
580 __METHOD__ .
".getExpiredTokens");
582 foreach ($rows as $row) {
584 "id" => $row[
"pat_pk"] .
"." . $user_pk,
585 "name" => $row[
"token_name"],
586 "created" => $row[
"created_on"],
587 "expire" => $row[
"expire_on"],
588 "scope" => $row[
"token_scope"]
590 $response[] = $entry;
592 array_multisort(array_column($response,
"created"), SORT_ASC, $response);
603 $groups = $this->userDao->getUserGroupMap($userRec[
'user_pk']);
604 $userDefaults = $this->userDao->getUserAndDefaultGroupByUserName($userRec[
'user_name']);
606 foreach ($groups as $groupId => $groupName) {
607 $options .=
"<option value='$groupId' ";
608 if ($groupId == $userDefaults[
'group_fk']) {
609 $options .=
"selected='selected'";
611 $options .=
">$groupName</option>";
626 private function addNewClient(Request $request)
630 $user_pk = Auth::getUserId();
633 if ($_SESSION[Auth::USER_LEVEL] < 3) {
639 $restHelper = $container->get(
'helper.restHelper');
641 $restHelper->validateNewOauthClient($user_pk, $clientName, $clientScope,
644 throw new \UnexpectedValueException($e->getMessage());
647 $restHelper->getDbHelper()->addNewClient($clientName, $user_pk,
648 $clientId, $clientScope);
649 return "Client \"$clientName\" added with ID \"$clientId\"";
661 $user_pk = Auth::getUserId();
662 $sql =
"SELECT pat_pk, user_fk, token_scope, token_name, " .
663 "created_on, active, client_id " .
664 "FROM personal_access_tokens " .
665 "WHERE user_fk = $1 AND active = true AND token_key IS NULL;";
666 $rows = $this->
dbManager->getRows($sql, [$user_pk],
667 __METHOD__ .
".getActiveClients");
669 foreach ($rows as $row) {
671 "id" => $row[
"pat_pk"] .
"." . $user_pk,
672 "name" => $row[
"token_name"],
673 "created" => $row[
"created_on"],
674 "clientid" => $row[
"client_id"],
675 "scope" => $row[
"token_scope"]
677 $response[] = $entry;
679 array_multisort(array_column($response,
"created"), SORT_ASC, $response);
689 $user_pk = Auth::getUserId();
690 $sql =
"SELECT pat_pk, user_fk, token_scope, token_name, " .
691 "created_on, active, client_id " .
692 "FROM personal_access_tokens " .
693 "WHERE user_fk = $1 AND active = false AND token_key IS NULL;";
694 $rows = $this->
dbManager->getRows($sql, [$user_pk],
695 __METHOD__ .
".getRevokedClients");
697 foreach ($rows as $row) {
699 "id" => $row[
"pat_pk"] .
"." . $user_pk,
700 "name" => $row[
"token_name"],
701 "created" => $row[
"created_on"],
702 "clientid" => $row[
"client_id"],
703 "scope" => $row[
"token_scope"]
705 $response[] = $entry;
707 array_multisort(array_column($response,
"created"), SORT_ASC, $response);
718 return $SysConf[
'SYSCONFIG'][
'PATMaxPostExpiryRetention'];
Contains the constants and helpers for authentication of user.
Exception when a token has duplicate key for same user.
Exception when a token has duplicate name for same user.
render($templateName, $vars=null, $headers=null)
Provides helper methods for REST api.
Provides helper methods to access database for REST api.
Provides various DAO helper functions for REST api.
CreateUserRec(Request $request, $user_pk="")
Create a user record.
GetUserRec($user_pk)
Get a user record.
getListOfExpiredClients()
getListOfActiveClients()
Get a list of active clients for current user.
IsSessionAdmin($UserRec)
Determine if the session user is an admin.
UpdateUser($UserRec, $SessionIsAdmin)
Validate and update the user data.
getListOfActiveTokens()
Get a list of active tokens for current user.
handle(Request $request)
Allow user to change their account settings (users db table).
DisplayForm($UserRec, $SessionIsAdmin)
Display the user record edit form.
getUserGroupSelect($userRec)
getMaxExpiredTokenRetentionPeriod()
getMaxExpiredTokenRetentionPeriod() get the refresh time from DB. @Returns number of days to retain e...
userAgents($agents=null)
Read the UI form and format the user selected agents into a comma separated list.
AgentCheckBoxMake($upload_pk, $SkipAgents=array(), $specified_username="")
Generate a checkbox list of available agents.
generate_password_policy_string()
generate_password_policy()
SelectBucketPool($selected, $active='Y')
Return a select list containing all the active bucketpool's.
DBCheckResult($result, $sql, $filenm, $lineno)
Check the postgres result for unexpected errors. If found, treat them as fatal.
GetSingleRec($Table, $Where="")
Retrieve a single database record.
FolderListOption($ParentFolder, $Depth, $IncludeTop=1, $SelectId=-1, $linkParent=false, $OldParent=0)
Create the folder tree, using OPTION tags.
Traceback_uri()
Get the URI without query to this location.
GetParm($parameterName, $parameterType)
This function will retrieve the variables and check data types.
#define PLUGIN_DB_WRITE
Plugin requires write permission on DB.
#define PERM_READ
Read-only permission.
#define PLUGIN_DB_NONE
Plugin requires no DB permission.
#define PLUGIN_DB_READ
Plugin requires read permission on DB.
#define PLUGIN_DB_ADMIN
Plugin requires admin level permission on DB.
foreach($Options as $Option=> $OptVal) if(0==$reference_flag &&0==$nomos_flag) $PG_CONN
fo_dbManager * dbManager
fo_dbManager object