mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-09 23:15:58 -06:00
1) Added email id validation on the login page.
2) Added validation for the file manager.
This commit is contained in:
parent
6ded547a0d
commit
b82e6dbdb8
@ -17,16 +17,18 @@ from flask_babelex import gettext
|
||||
|
||||
from .registry import AuthSourceRegistry
|
||||
from pgadmin.model import User
|
||||
from pgadmin.utils.validation_utils import validate_email
|
||||
|
||||
|
||||
@six.add_metaclass(AuthSourceRegistry)
|
||||
class BaseAuthentication(object):
|
||||
|
||||
DEFAULT_MSG = {
|
||||
'USER_DOES_NOT_EXIST': 'Incorrect username or password.',
|
||||
'LOGIN_FAILED': 'Login failed',
|
||||
'EMAIL_NOT_PROVIDED': 'Email/Username not provided',
|
||||
'PASSWORD_NOT_PROVIDED': 'Password not provided'
|
||||
'USER_DOES_NOT_EXIST': gettext('Incorrect username or password.'),
|
||||
'LOGIN_FAILED': gettext('Login failed'),
|
||||
'EMAIL_NOT_PROVIDED': gettext('Email/Username not provided'),
|
||||
'PASSWORD_NOT_PROVIDED': gettext('Password not provided'),
|
||||
'INVALID_EMAIL': gettext('Email/Username is not valid')
|
||||
}
|
||||
|
||||
@abstractproperty
|
||||
@ -85,7 +87,10 @@ class InternalAuthentication(BaseAuthentication):
|
||||
|
||||
def validate(self, form):
|
||||
"""User validation"""
|
||||
|
||||
# validate the email id first
|
||||
if not validate_email(form.data['email']):
|
||||
form.errors['email'] = [self.messages('INVALID_EMAIL')]
|
||||
return False
|
||||
# Flask security validation
|
||||
return form.validate_on_submit()
|
||||
|
||||
|
@ -18,6 +18,7 @@ from urllib.parse import unquote
|
||||
from sys import platform as _platform
|
||||
import config
|
||||
import codecs
|
||||
import pathlib
|
||||
from werkzeug.exceptions import InternalServerError
|
||||
|
||||
import simplejson as json
|
||||
@ -317,6 +318,11 @@ class Filemanager(object):
|
||||
# Stores list of dict for filename & its encoding
|
||||
loaded_file_encoding_list = []
|
||||
|
||||
ERROR_NOT_ALLOWED = {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 0
|
||||
}
|
||||
|
||||
def __init__(self, trans_id):
|
||||
self.trans_id = trans_id
|
||||
self.patherror = encode_json(
|
||||
@ -822,10 +828,7 @@ class Filemanager(object):
|
||||
Rename file or folder
|
||||
"""
|
||||
if not self.validate_request('rename'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 0
|
||||
}
|
||||
return self.ERROR_NOT_ALLOWED
|
||||
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
|
||||
@ -883,10 +886,7 @@ class Filemanager(object):
|
||||
Delete file or folder
|
||||
"""
|
||||
if not self.validate_request('delete'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 0
|
||||
}
|
||||
return self.ERROR_NOT_ALLOWED
|
||||
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
orig_path = "{0}{1}".format(the_dir, path)
|
||||
@ -924,10 +924,7 @@ class Filemanager(object):
|
||||
File upload functionality
|
||||
"""
|
||||
if not self.validate_request('upload'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 0
|
||||
}
|
||||
return self.ERROR_NOT_ALLOWED
|
||||
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
err_msg = ''
|
||||
@ -940,6 +937,12 @@ class Filemanager(object):
|
||||
orig_path = "{0}{1}".format(the_dir, path)
|
||||
new_name = "{0}{1}".format(orig_path, file_name)
|
||||
|
||||
try:
|
||||
# Check if the new file is inside the users directory
|
||||
pathlib.Path(new_name).relative_to(the_dir)
|
||||
except ValueError as _:
|
||||
return self.ERROR_NOT_ALLOWED
|
||||
|
||||
with open(new_name, 'wb') as f:
|
||||
while True:
|
||||
# 4MB chunk (4 * 1024 * 1024 Bytes)
|
||||
@ -1103,10 +1106,7 @@ class Filemanager(object):
|
||||
Functionality to create new folder
|
||||
"""
|
||||
if not self.validate_request('create'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 0
|
||||
}
|
||||
return self.ERROR_NOT_ALLOWED
|
||||
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
|
||||
@ -1156,10 +1156,7 @@ class Filemanager(object):
|
||||
Functionality to download file
|
||||
"""
|
||||
if not self.validate_request('download'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 0
|
||||
}
|
||||
return self.ERROR_NOT_ALLOWED
|
||||
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
orig_path = "{0}{1}".format(the_dir, path)
|
||||
|
@ -14,6 +14,8 @@ import os
|
||||
import re
|
||||
import getpass
|
||||
|
||||
from pgadmin.utils.validation_utils import validate_email
|
||||
|
||||
|
||||
def user_info_desktop():
|
||||
print("NOTE: Configuring authentication for DESKTOP mode.")
|
||||
@ -43,14 +45,8 @@ def user_info_server():
|
||||
"pgAdmin user account:\n"
|
||||
)
|
||||
|
||||
email_filter = re.compile(
|
||||
"^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9]"
|
||||
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9]"
|
||||
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
|
||||
)
|
||||
|
||||
email = input("Email address: ")
|
||||
while email == '' or not email_filter.match(email):
|
||||
while not validate_email(email):
|
||||
print('Invalid email address. Please try again.')
|
||||
email = input("Email address: ")
|
||||
|
||||
|
@ -22,9 +22,10 @@ from werkzeug.exceptions import InternalServerError
|
||||
import config
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.ajax import make_response as ajax_response, \
|
||||
make_json_response, bad_request, internal_server_error
|
||||
make_json_response, bad_request, internal_server_error, forbidden
|
||||
from pgadmin.utils.csrf import pgCSRFProtect
|
||||
from pgadmin.utils.constants import MIMETYPE_APP_JS
|
||||
from pgadmin.utils.validation_utils import validate_email
|
||||
from pgadmin.model import db, Role, User, UserPreference, Server, \
|
||||
ServerGroup, Process, Setting
|
||||
|
||||
@ -104,16 +105,11 @@ def validate_password(data, new_data):
|
||||
|
||||
def validate_user(data):
|
||||
new_data = dict()
|
||||
email_filter = re.compile(
|
||||
"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9]"
|
||||
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9]"
|
||||
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
|
||||
)
|
||||
|
||||
validate_password(data, new_data)
|
||||
|
||||
if 'email' in data and data['email'] and data['email'] != "":
|
||||
if email_filter.match(data['email']):
|
||||
if validate_email(data['email']):
|
||||
new_data['email'] = data['email']
|
||||
else:
|
||||
raise InternalServerError(_("Invalid email address."))
|
||||
@ -383,6 +379,18 @@ def update(uid):
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
|
||||
# Username and email can not be changed for internal users
|
||||
if usr.auth_source == current_app.PGADMIN_DEFAULT_AUTH_SOURCE:
|
||||
non_editable_params = ('username', 'email')
|
||||
|
||||
for f in non_editable_params:
|
||||
if f in data:
|
||||
return forbidden(
|
||||
errmsg=_(
|
||||
"'{0}' is not allowed to modify."
|
||||
).format(f)
|
||||
)
|
||||
|
||||
try:
|
||||
new_data = validate_user(data)
|
||||
|
||||
|
@ -34,9 +34,18 @@ def get_storage_directory():
|
||||
if storage_dir is None:
|
||||
return None
|
||||
|
||||
username = current_user.username.split('@')[0]
|
||||
if len(username) == 0 or username[0].isdigit():
|
||||
username = 'pga_user_' + username
|
||||
def _preprocess_username(un):
|
||||
ret_un = un
|
||||
if len(ret_un) == 0 or ret_un[0].isdigit():
|
||||
ret_un = 'pga_user_' + username
|
||||
|
||||
ret_un = ret_un.replace('@', '_')\
|
||||
.replace('/', 'slash')\
|
||||
.replace('\\', 'slash')
|
||||
|
||||
return ret_un
|
||||
|
||||
username = _preprocess_username(current_user.username.split('@')[0])
|
||||
|
||||
# Figure out the old-style storage directory name
|
||||
old_storage_dir = os.path.join(
|
||||
@ -45,11 +54,13 @@ def get_storage_directory():
|
||||
username
|
||||
)
|
||||
|
||||
username = _preprocess_username(current_user.username)
|
||||
|
||||
# Figure out the new style storage directory name
|
||||
storage_dir = os.path.join(
|
||||
storage_dir.decode('utf-8') if hasattr(storage_dir, 'decode')
|
||||
else storage_dir,
|
||||
current_user.username.replace('@', '_')
|
||||
username
|
||||
)
|
||||
|
||||
# Rename an old-style storage directory, if the new style doesn't exist
|
||||
|
26
web/pgadmin/utils/validation_utils.py
Normal file
26
web/pgadmin/utils/validation_utils.py
Normal file
@ -0,0 +1,26 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def validate_email(email):
|
||||
if email == '' or email is None:
|
||||
return False
|
||||
|
||||
email_filter = re.compile(
|
||||
"^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9]"
|
||||
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9]"
|
||||
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
|
||||
)
|
||||
|
||||
if not email_filter.match(email):
|
||||
return False
|
||||
|
||||
return True
|
Loading…
Reference in New Issue
Block a user