1. Unverified email id is getting locked.

2. Admin should be able to lock the user, as currently it only unlocks it via
   user management dialog.
3. There were some indefinite login page loading issues when trying to log in
   with invalid password, where it should redirect to the login page again instead.

refs #6337 (Initial patch by Khushboo Vashi)
This commit is contained in:
Rahul Shirsat 2021-08-09 20:55:06 +05:30 committed by Akshay Joshi
parent dc4f59e664
commit ab04b30726
10 changed files with 63 additions and 6 deletions

View File

@ -35,6 +35,7 @@ Mode is pre-configured for security.
login
user_management
change_user_password
restore_locked_user
ldap
kerberos
oauth2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -0,0 +1,50 @@
.. _restore_locked_user:
*****************************
`Lock/Restore Account`:index:
*****************************
Account locking/unlocking via user management dialog:
An admin can lock and unlock user from the user management dialog. This allows the admin to lock or restore
the user when there are several failed login attempts. This page guides you through configuring per-user
locking/restoring. For more details visit :ref:`User management <user_management>`.
.. csv-table::
:header: "**Parameter**", "**Description**"
:class: longtable
:widths: 35, 55
"MAX_LOGIN_ATTEMPTS", "Which sets the number of failed login that
are allowed. If this value is exceeded, the account is locked and can be reset by an administrator.
By setting the variable to the value zero this feature is deactivated."
When Administrator itself gets locked, following steps may be considered to restore it:
- Increase MAX_LOGIN_ATTEMPTS, and try to successfully login to restore the account.
OR
By updating SQLite DB (pgAdmin4.db):
* Locate the pgAdmin4.db file and open it using any DB Browser (or DB Browser for SQLite)
* After opening the DB file, head towards 'Execute SQL' section.
* Run below query -
*UPDATE USER SET LOCKED = false, LOGIN_ATTEMPTS = 0 WHERE USERNAME = <YOUR_EMAIL_ID>*
* Make sure the query changes are committed.
Account locking by failed login attempts:
.. image:: images/login_attempt_user.png
:alt: Failed login attempt for current user
:align: center
pgAdmin application is configured to lock a user account when a number of consecutive failed login attempts are
exceeded.
MAX_LOGIN_ATTEMPTS is defaulted to 3 unsuccessful login attempts, after which the account would be locked.
The only way to restore the user account is by contacting the Administrator and ask to unlock it.

View File

@ -58,6 +58,8 @@ Provide information about the new pgAdmin role in the row:
as authentication source since LDAP password is not stored in the pgAdmin database.
* Re-enter the password in the *Confirm password* field. This field is disabled
if you select *ldap* as authentication source.
* Move the *Locked* switch to the *True* position if you want to lock the account;
the default is *False*. This functionality is useful when a user is locked by trying unsuccessful login attempts.
To discard a user, and revoke access to pgAdmin, click the trash icon to the
left of the row and confirm deletion in the *Delete user?* dialog.

View File

@ -582,6 +582,10 @@ AUTHENTICATION_SOURCES = ['internal']
##########################################################################
MAX_LOGIN_ATTEMPTS = 3
##########################################################################
# Only consider password to check the failed login attempts, email is
# excluded from this check
LOGIN_ATTEMPT_FIELDS = ['password']
##########################################################################
# LDAP Configuration
##########################################################################

View File

@ -74,7 +74,7 @@ def login():
if not auth_obj.validate():
for field in form.errors:
flash_login_attempt_error = None
if user:
if user and field in config.LOGIN_ATTEMPT_FIELDS:
if config.MAX_LOGIN_ATTEMPTS > 0:
user.login_attempts += 1
left_attempts = \

View File

@ -129,9 +129,12 @@ def validate_user(data):
if 'auth_source' in data and data['auth_source'] != "":
new_data['auth_source'] = data['auth_source']
if 'locked' in data and not data['locked']:
if 'locked' in data and type(data['locked']) == bool:
new_data['locked'] = data['locked']
new_data['login_attempts'] = 0
if data['locked']:
new_data['login_attempts'] = config.MAX_LOGIN_ATTEMPTS
else:
new_data['login_attempts'] = 0
return new_data

View File

@ -444,9 +444,6 @@ define([
disabled: false,
sortable: false,
editable: function (m){
if (!m.get('locked')) {
return false;
}
return (m.get('id') != userInfo['id']);
},
}],