mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added support for Two-factor authentication for improving security. Fixes #6543
This commit is contained in:
committed by
Akshay Joshi
parent
fe096116be
commit
36c9eb3dfd
@@ -25,6 +25,7 @@ from flask import current_app, render_template, url_for, make_response, \
|
||||
from flask_babel import gettext
|
||||
from flask_gravatar import Gravatar
|
||||
from flask_login import current_user, login_required
|
||||
from flask_login.utils import login_url
|
||||
from flask_security.changeable import change_user_password
|
||||
from flask_security.decorators import anonymous_user_required
|
||||
from flask_security.recoverable import reset_password_token_status, \
|
||||
@@ -38,6 +39,8 @@ from werkzeug.datastructures import MultiDict
|
||||
|
||||
import config
|
||||
from pgadmin import current_blueprint
|
||||
from pgadmin.authenticate import get_logout_url
|
||||
from pgadmin.authenticate.mfa.utils import mfa_required, is_mfa_enabled
|
||||
from pgadmin.settings import get_setting, store_setting
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.ajax import make_json_response
|
||||
@@ -695,6 +698,7 @@ def check_browser_upgrade():
|
||||
@blueprint.route("/")
|
||||
@pgCSRFProtect.exempt
|
||||
@login_required
|
||||
@mfa_required
|
||||
def index():
|
||||
"""Render and process the main browser window."""
|
||||
# Register Gravatar module with the app only if required
|
||||
@@ -753,7 +757,11 @@ def index():
|
||||
username=current_user.username,
|
||||
auth_source=auth_source,
|
||||
is_admin=current_user.has_role("Administrator"),
|
||||
logout_url=_get_logout_url(),
|
||||
logout_url=get_logout_url(),
|
||||
requirejs=True,
|
||||
basejs=True,
|
||||
mfa_enabled=is_mfa_enabled(),
|
||||
login_url=login_url,
|
||||
_=gettext,
|
||||
auth_only_internal=auth_only_internal
|
||||
))
|
||||
@@ -843,7 +851,7 @@ def utils():
|
||||
app_version_int=config.APP_VERSION_INT,
|
||||
pg_libpq_version=pg_libpq_version,
|
||||
support_ssh_tunnel=config.SUPPORT_SSH_TUNNEL,
|
||||
logout_url=_get_logout_url(),
|
||||
logout_url=get_logout_url(),
|
||||
platform=sys.platform,
|
||||
qt_default_placeholder=QT_DEFAULT_PLACEHOLDER,
|
||||
enable_psql=config.ENABLE_PSQL
|
||||
|
||||
@@ -22,7 +22,7 @@ define('pgadmin.browser', [
|
||||
'pgadmin.browser.menu', 'pgadmin.browser.panel', 'pgadmin.browser.layout',
|
||||
'pgadmin.browser.runtime', 'pgadmin.browser.error', 'pgadmin.browser.frame',
|
||||
'pgadmin.browser.node', 'pgadmin.browser.collection', 'pgadmin.browser.activity',
|
||||
'sources/codemirror/addon/fold/pgadmin-sqlfoldcode',
|
||||
'sources/codemirror/addon/fold/pgadmin-sqlfoldcode', 'pgadmin.browser.dialog',
|
||||
'pgadmin.browser.keyboard', 'sources/tree/pgadmin_tree_save_state','jquery.acisortable',
|
||||
'jquery.acifragment',
|
||||
], function(
|
||||
@@ -172,7 +172,7 @@ define('pgadmin.browser', [
|
||||
let ih = window.innerHeight;
|
||||
if (ih > passed_height){
|
||||
return passed_height;
|
||||
}else{
|
||||
} else {
|
||||
if (ih > pgAdmin.Browser.stdH.lg)
|
||||
return pgAdmin.Browser.stdH.lg;
|
||||
else if (ih > pgAdmin.Browser.stdH.md)
|
||||
|
||||
110
web/pgadmin/browser/static/js/dialog.js
Normal file
110
web/pgadmin/browser/static/js/dialog.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import gettext from 'sources/gettext';
|
||||
import * as alertify from 'pgadmin.alertifyjs';
|
||||
import url_for from 'sources/url_for';
|
||||
import pgAdmin from 'sources/pgadmin';
|
||||
|
||||
let counter = 1;
|
||||
|
||||
function url_dialog(_title, _url, _help_filename, _width, _height) {
|
||||
|
||||
let pgBrowser = pgAdmin.Browser;
|
||||
|
||||
const dlgName = 'UrlDialog' + counter++;
|
||||
|
||||
alertify.dialog(dlgName, function factory() {
|
||||
return {
|
||||
main: function(_title) {
|
||||
this.set({'title': _title});
|
||||
},
|
||||
build: function() {
|
||||
alertify.pgDialogBuild.apply(this);
|
||||
},
|
||||
settings: {
|
||||
url: _url,
|
||||
title: _title,
|
||||
},
|
||||
setup: function() {
|
||||
return {
|
||||
buttons: [{
|
||||
text: '',
|
||||
key: 112,
|
||||
className: 'btn btn-primary-icon pull-left fa fa-question pg-alertify-icon-button',
|
||||
attrs: {
|
||||
name: 'dialog_help',
|
||||
type: 'button',
|
||||
label: _title,
|
||||
url: url_for('help.static', {
|
||||
'filename': _help_filename,
|
||||
}),
|
||||
},
|
||||
}, {
|
||||
text: gettext('Close'),
|
||||
key: 27,
|
||||
className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button',
|
||||
attrs: {
|
||||
name: 'close',
|
||||
type: 'button',
|
||||
},
|
||||
}],
|
||||
// Set options for dialog
|
||||
options: {
|
||||
//disable both padding and overflow control.
|
||||
padding: !1,
|
||||
overflow: !1,
|
||||
modal: false,
|
||||
resizable: true,
|
||||
maximizable: true,
|
||||
pinnable: false,
|
||||
closableByDimmer: false,
|
||||
closable: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
hooks: {
|
||||
// Triggered when the dialog is closed
|
||||
onclose: function() {
|
||||
// Clear the view
|
||||
return setTimeout((function() {
|
||||
return (alertify[dlgName]()).destroy();
|
||||
}), 1000);
|
||||
},
|
||||
},
|
||||
prepare: function() {
|
||||
// create the iframe element
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.frameBorder = 'no';
|
||||
iframe.width = '100%';
|
||||
iframe.height = '100%';
|
||||
iframe.src = this.setting('url');
|
||||
// add it to the dialog
|
||||
this.elements.content.appendChild(iframe);
|
||||
},
|
||||
callback: function(e) {
|
||||
if (e.button.element.name == 'dialog_help') {
|
||||
e.cancel = true;
|
||||
pgBrowser.showHelp(
|
||||
e.button.element.name, e.button.element.getAttribute('url'),
|
||||
null, null
|
||||
);
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
(alertify[dlgName](_title)).show().resizeTo(_width || pgBrowser.stdW.lg, _height || pgBrowser.stdH.md);
|
||||
}
|
||||
|
||||
pgAdmin.ui.dialogs.url_dialog = url_dialog;
|
||||
|
||||
export {
|
||||
url_dialog,
|
||||
};
|
||||
@@ -152,6 +152,17 @@ window.onload = function(e){
|
||||
</li>
|
||||
<li class="dropdown-divider"></li>
|
||||
{% endif %}
|
||||
{% if mfa_enabled is defined and mfa_enabled is true %}
|
||||
<li>
|
||||
<a class="dropdown-item" href="#" role="menuitem"
|
||||
onclick="javascript:pgAdmin.ui.dialogs.url_dialog(
|
||||
'{{ _("Authentiction") }}',
|
||||
'{{ login_url("mfa.register", next_url="internal") }}',
|
||||
'mfa.html', '90%', '90%'
|
||||
);">{{ _('Two-Factor Authentication') }}</a>
|
||||
</li>
|
||||
<li class="dropdown-divider"></li>
|
||||
{% endif %}
|
||||
{% if is_admin %}
|
||||
<li><a class="dropdown-item" href="#" role="menuitem" onclick="pgAdmin.Browser.UserManagement.show_users()">{{ _('Users') }}</a></li>
|
||||
<li class="dropdown-divider"></li>
|
||||
|
||||
Reference in New Issue
Block a user