mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Remove Bootstrap and jQuery from authentication pages and rewrite them in ReactJS. #6295
This commit is contained in:
@@ -27,7 +27,8 @@ from flask_socketio import disconnect, ConnectionRefusedError
|
||||
|
||||
from pgadmin.model import db, User
|
||||
from pgadmin.utils import PgAdminModule, get_safe_post_login_redirect
|
||||
from pgadmin.utils.constants import KERBEROS, INTERNAL, OAUTH2, LDAP
|
||||
from pgadmin.utils.constants import KERBEROS, INTERNAL, OAUTH2, LDAP,\
|
||||
MessageType
|
||||
from pgadmin.authenticate.registry import AuthSourceRegistry
|
||||
|
||||
MODULE_NAME = 'authenticate'
|
||||
@@ -132,7 +133,7 @@ def _login():
|
||||
if user.login_attempts >= config.MAX_LOGIN_ATTEMPTS > 0:
|
||||
flash(gettext('Your account is locked. Please contact the '
|
||||
'Administrator.'),
|
||||
'warning')
|
||||
MessageType.WARNING)
|
||||
logout_user()
|
||||
return redirect(get_post_logout_redirect())
|
||||
|
||||
@@ -158,7 +159,7 @@ def _login():
|
||||
if flash_login_attempt_error:
|
||||
error = error + flash_login_attempt_error
|
||||
flash_login_attempt_error = None
|
||||
flash(error, 'warning')
|
||||
flash(error, MessageType.WARNING)
|
||||
|
||||
return redirect(get_post_logout_redirect())
|
||||
|
||||
@@ -175,7 +176,7 @@ def _login():
|
||||
return redirect('{0}?next={1}'.format(url_for(
|
||||
'authenticate.kerberos_login'), url_for('browser.index')))
|
||||
|
||||
flash(msg, 'danger')
|
||||
flash(msg, MessageType.ERROR)
|
||||
return redirect(get_post_logout_redirect())
|
||||
|
||||
session['auth_source_manager'] = current_auth_obj
|
||||
@@ -194,7 +195,7 @@ def _login():
|
||||
return msg
|
||||
if 'auth_obj' in session:
|
||||
session.pop('auth_obj')
|
||||
flash(msg, 'danger')
|
||||
flash(msg, MessageType.ERROR)
|
||||
form_class = _security.forms.get('login_form').cls
|
||||
form = form_class()
|
||||
|
||||
@@ -268,7 +269,7 @@ class AuthSourceManager:
|
||||
if status:
|
||||
return True
|
||||
if err_msg:
|
||||
flash(err_msg, 'warning')
|
||||
flash(err_msg, MessageType.WARNING)
|
||||
return False
|
||||
|
||||
def authenticate(self):
|
||||
|
||||
@@ -23,7 +23,7 @@ from flask_security import login_required
|
||||
import config
|
||||
from pgadmin.model import User
|
||||
from pgadmin.tools.user_management import create_user
|
||||
from pgadmin.utils.constants import KERBEROS
|
||||
from pgadmin.utils.constants import KERBEROS, MessageType
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.ajax import make_json_response, internal_server_error
|
||||
|
||||
@@ -199,7 +199,7 @@ class KerberosAuthentication(BaseAuthentication):
|
||||
retval = self.__auto_create_user(
|
||||
str(negotiate.initiator_name))
|
||||
elif isinstance(negotiate, Exception):
|
||||
flash(gettext(negotiate), 'danger')
|
||||
flash(gettext(negotiate), MessageType.ERROR)
|
||||
retval = [status,
|
||||
Response(render_template(
|
||||
"security/login_user.html",
|
||||
@@ -209,8 +209,8 @@ class KerberosAuthentication(BaseAuthentication):
|
||||
str(base64.b64encode(negotiate), 'utf-8'))
|
||||
return False, Response("Success", 200, headers)
|
||||
else:
|
||||
flash(gettext("Kerberos authentication failed."
|
||||
" Couldn't find kerberos ticket."), 'danger')
|
||||
flash(gettext("Kerberos authentication failed. Couldn't find "
|
||||
"kerberos ticket."), MessageType.ERROR)
|
||||
headers.add('WWW-Authenticate', 'Negotiate')
|
||||
retval = [False,
|
||||
Response(render_template(
|
||||
|
||||
@@ -24,6 +24,7 @@ from pgadmin.model import UserMFA
|
||||
|
||||
from .registry import BaseMFAuth
|
||||
from .utils import ValidationException, fetch_auth_option, mfa_add
|
||||
from pgadmin.utils.constants import MessageType
|
||||
|
||||
|
||||
_TOTP_AUTH_METHOD = "authenticator"
|
||||
@@ -119,14 +120,7 @@ class TOTPAuthenticator(BaseMFAuth):
|
||||
Returns:
|
||||
str: Authentication view as a string
|
||||
"""
|
||||
return (
|
||||
"<div class='form-group'>{auth_description}</div>"
|
||||
"<div class='form-group'>"
|
||||
" <input class='form-control' placeholder='{otp_placeholder}'"
|
||||
" name='code' type='password' autofocus='' pattern='\\d*'"
|
||||
" autocomplete='one-time-code' require/>"
|
||||
"</div>"
|
||||
).format(
|
||||
return dict(
|
||||
auth_description=_(
|
||||
"Enter the code shown in your authenticator application for "
|
||||
"TOTP (Time-based One-Time Password)"
|
||||
@@ -162,6 +156,17 @@ class TOTPAuthenticator(BaseMFAuth):
|
||||
img.save(buffered, format="JPEG")
|
||||
img_base64 = base64.b64encode(buffered.getvalue())
|
||||
|
||||
return dict(
|
||||
auth_title=_(_TOTP_AUTHENTICATOR),
|
||||
auth_method=_TOTP_AUTH_METHOD,
|
||||
image=img_base64.decode("utf-8"),
|
||||
qrcode_alt_text=_("TOTP Authenticator QRCode"),
|
||||
auth_description=_(
|
||||
"Scan the QR code and the enter the code from the "
|
||||
"TOTP Authenticator application"
|
||||
), otp_placeholder=_("Enter code")
|
||||
)
|
||||
|
||||
return "".join([
|
||||
"<h5 class='form-group text-center'>{auth_title}</h5>",
|
||||
"<input type='hidden' name='{auth_method}' value='SETUP'/>",
|
||||
@@ -210,13 +215,13 @@ class TOTPAuthenticator(BaseMFAuth):
|
||||
authenticator_opt = session.get('mfa_authenticator_opt', None)
|
||||
if authenticator_opt is None or \
|
||||
pyotp.TOTP(authenticator_opt).verify(code) is False:
|
||||
flash(_("Failed to validate the code"), "danger")
|
||||
flash(_("Failed to validate the code"), MessageType.ERROR)
|
||||
return self._registration_view()
|
||||
|
||||
mfa_add(_TOTP_AUTH_METHOD, authenticator_opt)
|
||||
flash(_(
|
||||
"TOTP Authenticator registered successfully for authentication."
|
||||
), "success")
|
||||
), MessageType.SUCCESS)
|
||||
session.pop('mfa_authenticator_opt', None)
|
||||
|
||||
return None
|
||||
|
||||
@@ -18,6 +18,7 @@ import config
|
||||
from pgadmin.utils.csrf import pgCSRFProtect
|
||||
from .registry import BaseMFAuth
|
||||
from .utils import ValidationException, mfa_add, fetch_auth_option
|
||||
from pgadmin.utils.constants import MessageType
|
||||
|
||||
|
||||
def __generate_otp() -> str:
|
||||
@@ -154,10 +155,7 @@ def send_email_code() -> Response:
|
||||
if success is False:
|
||||
return Response(message, http_code, mimetype='text/html')
|
||||
|
||||
return Response(render_template(
|
||||
"mfa/email_code_sent.html", _=_,
|
||||
message=message,
|
||||
), http_code, mimetype='text/html')
|
||||
return dict(message=message)
|
||||
|
||||
|
||||
@pgCSRFProtect.exempt
|
||||
@@ -204,28 +202,15 @@ class EmailAuthentication(BaseMFAuth):
|
||||
|
||||
def validation_view(self):
|
||||
session.pop("mfa_email_code", None)
|
||||
return render_template(
|
||||
"mfa/email_view.html", _=_
|
||||
return dict(
|
||||
description=_("Verify with Email Authentication"),
|
||||
button_label=_("Send Code"),
|
||||
button_label_sending=_("Sending Code...")
|
||||
)
|
||||
|
||||
def _registration_view(self):
|
||||
email = getattr(current_user, 'email', '')
|
||||
return "\n".join([
|
||||
"<h5 class='form-group text-center'>{label}</h5>",
|
||||
"<input type='hidden' name='{auth_method}' value='SETUP'/>",
|
||||
"<input type='hidden' name='validate' value='send_code'/>",
|
||||
"<div class='form-group pt-3'>{description}</div>",
|
||||
"<div class='form-group'>",
|
||||
" <input class='form-control' name='send_to' type='email'",
|
||||
" placeholder='{email_address_placeholder}'",
|
||||
" autofocus='' value='{email_address}' required",
|
||||
" pattern='[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{{2,}}$'/>",
|
||||
"</div></div>",
|
||||
"<div class='alert alert-warning alert-dismissible fade show'",
|
||||
" role='alert'>",
|
||||
" <strong>{note_label}:</strong><span>{note}</span>",
|
||||
"</div>",
|
||||
]).format(
|
||||
return dict(
|
||||
label=email_authentication_label(),
|
||||
auth_method=EMAIL_AUTH_METHOD,
|
||||
description=_("Enter the email address to send a code"),
|
||||
@@ -247,20 +232,10 @@ class EmailAuthentication(BaseMFAuth):
|
||||
)
|
||||
|
||||
if success is False:
|
||||
flash(message, 'danger')
|
||||
flash(message, MessageType.ERROR)
|
||||
return None
|
||||
|
||||
return "\n".join([
|
||||
"<h5 class='form-group text-center'>{label}</h5>",
|
||||
"<input type='hidden' name='{auth_method}' value='SETUP'/>",
|
||||
"<input type='hidden' name='validate' value='verify_code'/>",
|
||||
"<div class='form-group pt-3'>{message}</div>",
|
||||
"<div class='form-group'>",
|
||||
" <input class='form-control' placeholder='{otp_placeholder}'",
|
||||
" pattern='\\d{{6}}' type='password' autofocus=''",
|
||||
" autocomplete='one-time-code' name='code' require>",
|
||||
"</div>",
|
||||
]).format(
|
||||
return dict(
|
||||
label=email_authentication_label(),
|
||||
auth_method=EMAIL_AUTH_METHOD,
|
||||
message=message,
|
||||
@@ -282,13 +257,13 @@ class EmailAuthentication(BaseMFAuth):
|
||||
|
||||
flash(_(
|
||||
"Email Authentication registered successfully."
|
||||
), "success")
|
||||
), MessageType.SUCCESS)
|
||||
|
||||
session.pop('mfa_email_code', None)
|
||||
|
||||
return None
|
||||
|
||||
flash(_('Invalid code'), 'danger')
|
||||
flash(_('Invalid code'), MessageType.ERROR)
|
||||
|
||||
return self._registration_view()
|
||||
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2023, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
let mfa_form_elem = document.getElementById('mfa_form');
|
||||
|
||||
if (mfa_form_elem)
|
||||
mfa_form_elem.setAttribute('class', '');
|
||||
|
||||
function sendCodeToEmail(data, _json, _callback) {
|
||||
const URL = '{{ url_for('mfa.send_email_code') }}';
|
||||
let accept = 'text/html; charset=utf-8;';
|
||||
|
||||
let btn_send_code_elem = document.getElementById('btn_send_code');
|
||||
if (btn_send_code_elem) btn_send_code_elem.disabled = true;
|
||||
|
||||
if (!data) {
|
||||
data = {'code': ''};
|
||||
}
|
||||
|
||||
if (_json) {
|
||||
accept = 'application/json; charset=utf-8;';
|
||||
}
|
||||
|
||||
clear_error();
|
||||
|
||||
fetch(URL, {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Accept': accept,
|
||||
'Content-Type': 'application/json; charset=utf-8;',
|
||||
'{{ current_app.config.get('WTF_CSRF_HEADERS')[0] }}': '{{ csrf_token() }}'
|
||||
},
|
||||
redirect: 'follow',
|
||||
body: JSON.stringify(data)
|
||||
}).then((resp) => {
|
||||
if (_callback) {
|
||||
setTimeout(() => (_callback(resp)), 1);
|
||||
return null;
|
||||
}
|
||||
if (!resp.ok) {
|
||||
let btn_send_code_elem = document.getElementById('btn_send_code');
|
||||
if (btn_send_code_elem) btn_send_code_elem.disabled = true;
|
||||
resp.text().then(msg => render_error(msg));
|
||||
|
||||
return;
|
||||
}
|
||||
if (_json) return resp.json();
|
||||
return resp.text();
|
||||
}).then((string) => {
|
||||
if (!string)
|
||||
return;
|
||||
document.getElementById("mfa_email_auth").innerHTML = string;
|
||||
document.getElementById("mfa_form").classList = ["show_validate_btn"];
|
||||
setTimeout(() => {
|
||||
document.getElementById("showme").classList = [];
|
||||
}, 20000);
|
||||
});
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<div class="form-group">
|
||||
<div class="form-group">{{ message }}</div>
|
||||
<div id="showme" class="hidden">
|
||||
<div class="form-group pb-3">
|
||||
<div class="card ">
|
||||
<div class="card-body">
|
||||
<div class="alert alert-warning d-flex flex-row mb-0">
|
||||
<i class="fas fa-lg fa-exclamation-triangle mr-3 align-self-center"></i>
|
||||
<div class="h-100">
|
||||
<span class="text-primary">{{ _("Haven't received an email?") }} <a class="enable_me_in_20 alert-link" href="#" onClick="javascript:sendCodeToEmail()" disabled>{{ _("Send again") }}</a></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<input class='form-control' placeholder='{{ _("Enter code") }}' name='code' type='password' autofocus='' pattern='\d*' autocomplete="one-time-code">
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,7 +0,0 @@
|
||||
<div class="form-group">
|
||||
<div class="form-group text-center h6">{{ _("Verify with Email Authentication") }}</div>
|
||||
<div class="form-group" id="mfa_email_auth">
|
||||
<button class="btn btn-primary btn-block btn-validate" id="btn_send_code"
|
||||
type="button" onclick="sendCodeToEmail()">{{ _("Send Code") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,78 +1,10 @@
|
||||
{% set auth_page = true %}
|
||||
{% extends "security/panel.html" %}
|
||||
{% block panel_image %}
|
||||
<div class="pr-4">
|
||||
<img src="{{ url_for('static', filename='img/login.svg') }}" alt="{{ _('Registration') }}">
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block panel_title %}{{ _('Authentication registration') }}{% endblock %}
|
||||
{% block panel_body %}
|
||||
<style>
|
||||
|
||||
div.form-group > label > .icon {
|
||||
min-width: 30px;
|
||||
min-height: 35px;
|
||||
}
|
||||
|
||||
{% if error_message is none %}
|
||||
|
||||
{% for mfa in mfa_list %}{% if mfa.icon|length > 0 %}
|
||||
|
||||
div#mfa-{{mfa.id | e}} .icon {
|
||||
background: url({{ mfa.icon }}) 0% 0% no-repeat transparent;
|
||||
min-height: 30px;
|
||||
min-width: 30px;
|
||||
}{% endif %}{% endfor %}
|
||||
</style>
|
||||
|
||||
<form id='mfa_view' method='post'
|
||||
action='{{ url_for("mfa.register") }}'>
|
||||
<div class='form-group'>
|
||||
{% if mfa_view is not defined or mfa_view is none %}
|
||||
<div class='form-group'>
|
||||
{% for mfa in mfa_list %}
|
||||
<div id="mfa-{{ mfa.id }}">
|
||||
<label class="my-1 d-flex align-items-center">
|
||||
<i class="fas mr-2 icon"></i>
|
||||
<span>{{ mfa.label | safe }}</span>
|
||||
<span class="ml-auto">
|
||||
<button class='btn btn-primary btn-block btn-validate' name='{{ mfa.id }}'
|
||||
type='submit'
|
||||
value='{% if mfa.registered %}DELETE{% else %}SETUP{% endif %}'>{% if mfa.registered %}{{ _("Delete") }}{% else %}{{ _("Setup") }}{% endif %}</button>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if next_url != 'internal' %}
|
||||
<div class="row align-items-center p-2">
|
||||
<button class='btn btn-primary btn-block btn-validate col' type='submit'
|
||||
value='{{ _("Continue") }}'>{{ _("Continue") }}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class='form-group'>
|
||||
{{ mfa_view | safe }}
|
||||
</div>
|
||||
<div class="row align-items-center p-2">
|
||||
<button class="btn btn-primary col mr-1" type="submit" name="continue" value="Continue">{{ _("Continue") }}</button>
|
||||
<button class="btn btn-secondary col" type="submit" name="cancel" value="Cancel">{{ _("Cancel") }}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
<input type="hidden" name="next" value="{{ next_url | safe }}"/>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="form-group pb-3">
|
||||
<div class="card ">
|
||||
<div class="card-body">
|
||||
<div class="alert alert-warning d-flex flex-row mb-0">
|
||||
<i class="fas fa-lg fa-exclamation-triangle mr-3 align-self-center"></i>
|
||||
<div class="h-100">
|
||||
<span class="text-primary text-danger">{{ error_message }}</a></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% set page_name = 'mfa_register' %}
|
||||
{% set page_props = {
|
||||
'actionUrl': url_for('mfa.register'),
|
||||
'mfaList': mfa_list,
|
||||
'nextUrl': next_url,
|
||||
'mfaView': mfa_view,
|
||||
'errorMessage': error_message,
|
||||
} %}
|
||||
{% extends "security/render_page.html" %}
|
||||
{% block title %}{{ _('Authentication Registration') }}{% endblock %}
|
||||
|
||||
@@ -1,121 +1,11 @@
|
||||
{% extends "security/panel.html" %}
|
||||
{% block panel_image %}
|
||||
<div class="pr-4">
|
||||
<img src="{{ url_for('static', filename='img/login.svg') }}" alt="{{ _('Authentication') }}">
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block panel_title %}{{ _('Authentication') }}{% endblock %}
|
||||
{% block panel_body %}
|
||||
<script>
|
||||
function onMFAChange(val) {
|
||||
const mfa_methods = {
|
||||
{% for key in views %}"{{views[key].id | e}}": { "label": "{{ views[key].label | e }}", "view": {{ views[key].view | tojson }}, "script": {{ views[key].script | tojson }} },
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
var method = mfa_methods[val];
|
||||
|
||||
if (method == undefined)
|
||||
return false;
|
||||
|
||||
window.init_mfa_method = null;
|
||||
|
||||
// Reset form classes - to show the 'Validate' button by default.
|
||||
document.getElementById(
|
||||
"mfa_form"
|
||||
).classList = ["show_validate_btn"];
|
||||
document.getElementById("mfa_method_prepend").setAttribute(
|
||||
'data-auth-method', val
|
||||
);
|
||||
document.getElementById("mfa_view").innerHTML = method.view;
|
||||
var elem = document.getElementById("mfa_method_script");
|
||||
|
||||
if (elem) {
|
||||
elem.remove();
|
||||
}
|
||||
clear_error();
|
||||
|
||||
if (method.script) {
|
||||
var elem = document.createElement('script');
|
||||
elem.src = method.script;
|
||||
elem.id = "mfa_method_script";
|
||||
document.body.appendChild(elem);
|
||||
}
|
||||
}
|
||||
|
||||
function render_error(err) {
|
||||
let divElem = document.createElement('div');
|
||||
|
||||
divElem.setAttribute(
|
||||
'style',
|
||||
'position: fixed; top: 20px; right: 20px; width: 400px; z-index: 9999'
|
||||
);
|
||||
divElem.setAttribute('id', 'alert-container');
|
||||
|
||||
divElem.innerHTML = [
|
||||
"<div class='alert alert-danger alert-dismissible fade show'",
|
||||
" role='alert'>",
|
||||
" <span id='alert_msg'></span>",
|
||||
" <button onclick='hide()' type='button' class='close'",
|
||||
" data-dismiss='alert' aria-label='Close'>",
|
||||
" <span aria-hidden='true'>×</span>",
|
||||
" </button>",
|
||||
"</div>",
|
||||
].join('')
|
||||
|
||||
var alertContainer = document.getElementById("alert-container");
|
||||
if (alertContainer) {
|
||||
alertContainer.remove();
|
||||
}
|
||||
document.body.appendChild(divElem);
|
||||
var alertMsg = document.getElementById("alert_msg");
|
||||
|
||||
alertMsg.innerHTML = err;
|
||||
};
|
||||
|
||||
function clear_error() {
|
||||
var alertContainer = document.getElementById("alert-container");
|
||||
if (alertContainer) {
|
||||
alertContainer.remove();
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = () => {
|
||||
{% for key in views %}{% if views[key].selected is true %}onMFAChange("{{ views[key].id | e }}");{% endif %}{% endfor %}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
form #validate-btn-group {
|
||||
display: none;
|
||||
}
|
||||
form.show_validate_btn #validate-btn-group {
|
||||
display: block;
|
||||
}
|
||||
|
||||
{% for key in views %}{% if views[key].icon|length > 0 %}
|
||||
|
||||
form #mfa_method_prepend[data-auth-method={{views[key].id | e}}] {
|
||||
background: url({{ views[key].icon }}) 0% 0% no-repeat #eee;
|
||||
}{% endif %}{% endfor %}
|
||||
|
||||
</style>
|
||||
<form action="{{ url_for('mfa.validate') }}" method="POST"
|
||||
name="mfa_form" id="mfa_form" class="show_validate_btn">
|
||||
<div class="form-group">
|
||||
<div class="from-group">
|
||||
<div class="input-group pb-2">
|
||||
<div class="input-group-prepend">
|
||||
<label class="input-group-text" for="mfa_method" id="mfa_method_prepend"> </label>
|
||||
</div>
|
||||
<select name="mfa_method" id="mfa_method" class="auth-select custom-select" onchange="onMFAChange(this.value);">
|
||||
{% for key in views %}<option value="{{views[key].id | e}}" {% if views[key].selected is true %}selected{% endif %}>{{ views[key].label | e }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="from-group pt-2 pb-2" id="mfa_view"></div>
|
||||
</div>
|
||||
<div class="row align-items-center p-2" id='validate-btn-group'>
|
||||
<button class="col btn btn-primary btn-block btn-validate" type="submit" value="{{ _('Validate') }}">{{ _('Validate') }}</button>
|
||||
</div>
|
||||
<div class="form-group text-right p-2"><a class="text-right" role="link" href="{{ logout_url }}">{{ _('Logout') }}</a></div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
{% set page_name = 'mfa_validate' %}
|
||||
{% set page_props = {
|
||||
'actionUrl': url_for('mfa.validate'),
|
||||
'views': views,
|
||||
'logoutUrl': logout_url,
|
||||
'sendEmailUrl': url_for("mfa.send_email_code"),
|
||||
'csrfHeader': current_app.config.get("WTF_CSRF_HEADERS")[0],
|
||||
'csrfToken': csrf_token()
|
||||
} %}
|
||||
{% extends "security/render_page.html" %}
|
||||
{% block title %}{{ _('Authentication') }}{% endblock %}
|
||||
|
||||
@@ -22,6 +22,7 @@ from pgadmin.utils.ajax import bad_request
|
||||
from .utils import user_supported_mfa_methods, mfa_user_registered, \
|
||||
mfa_suppored_methods, ValidationException, mfa_delete, is_mfa_enabled, \
|
||||
is_mfa_session_authenticated
|
||||
from pgadmin.utils.constants import MessageType
|
||||
|
||||
|
||||
_INDEX_URL = "browser.index"
|
||||
@@ -118,11 +119,11 @@ def validate_view() -> Response:
|
||||
"MFA validation failed for the user '{}' with an error: "
|
||||
"{}"
|
||||
).format(current_user.username, str(ve)))
|
||||
flash(str(ve), "danger")
|
||||
flash(str(ve), MessageType.ERROR)
|
||||
return_code = 401
|
||||
except Exception as ex:
|
||||
current_app.logger.exception(ex)
|
||||
flash(str(ex), "danger")
|
||||
flash(str(ex), MessageType.ERROR)
|
||||
return_code = 500
|
||||
|
||||
mfa_views = {
|
||||
@@ -166,7 +167,8 @@ def _mfa_registration_view(
|
||||
|
||||
if form_data[mfa.name] == 'SETUP':
|
||||
if supported_mfa['registered'] is True:
|
||||
flash(_("'{}' is already registerd'").format(mfa.label), "success")
|
||||
flash(_("'{}' is already registerd'").format(mfa.label),
|
||||
MessageType.SUCCESS)
|
||||
return None
|
||||
|
||||
return mfa.registration_view(form_data)
|
||||
@@ -174,13 +176,13 @@ def _mfa_registration_view(
|
||||
if mfa_delete(mfa.name) is True:
|
||||
flash(_(
|
||||
"'{}' unregistered from the authentication list."
|
||||
).format(mfa.label), "success")
|
||||
).format(mfa.label), MessageType.SUCCESS)
|
||||
|
||||
return None
|
||||
|
||||
flash(_(
|
||||
"'{}' is not found in the authentication list."
|
||||
).format(mfa.label), "warning")
|
||||
).format(mfa.label), MessageType.WARNING)
|
||||
|
||||
return None
|
||||
|
||||
@@ -255,7 +257,7 @@ def __handle_registration_view_for_post_method(
|
||||
if view is False:
|
||||
if next_url != 'internal':
|
||||
return None, redirect(next_url), None
|
||||
flash(_("Please close the dialog."), "info")
|
||||
flash(_("Please close the dialog."), MessageType.INFO)
|
||||
|
||||
if view is not None:
|
||||
return None, Response(
|
||||
@@ -336,7 +338,8 @@ def registration_view() -> Response:
|
||||
)
|
||||
elif is_mfa_session_authenticated() is False and \
|
||||
found_one_mfa is True:
|
||||
flash(_("Complete the authentication process first"), "danger")
|
||||
flash(_("Complete the authentication process first"),
|
||||
MessageType.ERROR)
|
||||
return redirect(login_url("mfa.validate", next_url=next_url))
|
||||
|
||||
return Response(render_template(
|
||||
|
||||
@@ -21,7 +21,7 @@ from flask_security.utils import get_post_logout_redirect, logout_user
|
||||
from pgadmin.authenticate.internal import BaseAuthentication
|
||||
from pgadmin.model import User
|
||||
from pgadmin.tools.user_management import create_user
|
||||
from pgadmin.utils.constants import OAUTH2
|
||||
from pgadmin.utils.constants import OAUTH2, MessageType
|
||||
from pgadmin.utils import PgAdminModule, get_safe_post_login_redirect
|
||||
from pgadmin.utils.csrf import pgCSRFProtect
|
||||
from pgadmin.model import db
|
||||
@@ -61,7 +61,7 @@ def init_app(app):
|
||||
if 'auth_obj' in session:
|
||||
session.pop('auth_obj')
|
||||
logout_user()
|
||||
flash(msg, 'danger')
|
||||
flash(msg, MessageType.ERROR)
|
||||
return redirect(get_safe_post_login_redirect())
|
||||
|
||||
@blueprint.route('/logout', endpoint="logout",
|
||||
|
||||
Reference in New Issue
Block a user