mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-01-23 15:03:26 -06:00
Support a desktop authentication mode.
This uses a single default user in the config database, which is auto-logged into the app when SERVER_MODE = False. In this mode we also hide/remove user-related functions in the UI.
This commit is contained in:
parent
10515431c7
commit
7c60fb3377
@ -65,6 +65,17 @@ LOG_FILE = 'pgadmin4.log'
|
||||
# Server settings
|
||||
##########################################################################
|
||||
|
||||
# The server mode determines whether or not we're running on a web server
|
||||
# requiring user authentication, or desktop mode which uses an automatic
|
||||
# default login.
|
||||
#
|
||||
# DO NOT DISABLE SERVER MODE IF RUNNING ON A WEBSERVER!!
|
||||
SERVER_MODE = True
|
||||
|
||||
# User ID (email address) to use for the default user in desktop mode.
|
||||
# The default should be fine here, as it's not exposed in the app.
|
||||
DESKTOP_USER = 'pgadmin4@pgadmin.org'
|
||||
|
||||
# The default port on which the app server will listen if not set in the
|
||||
# environment by the runtime
|
||||
DEFAULT_SERVER_PORT = 5050
|
||||
|
@ -20,6 +20,27 @@ sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
||||
import config
|
||||
from pgadmin import create_app
|
||||
|
||||
##########################################################################
|
||||
# Sanity checks
|
||||
##########################################################################
|
||||
|
||||
# Check for local settings if running in server mode
|
||||
if config.SERVER_MODE == True:
|
||||
local_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config_local.py')
|
||||
if not os.path.isfile(local_config):
|
||||
print "The configuration file %s does not exist.\n" % local_config
|
||||
print "Before running this application, ensure that config_local.py has been created"
|
||||
print "and sets values for SECRET_KEY, SECURITY_PASSWORD_SALT and CSRF_SESSION_KEY"
|
||||
print "at bare minimum. See config.py for more information and a complete list of"
|
||||
print "settings. Exiting..."
|
||||
sys.exit(1)
|
||||
|
||||
# Check if the database exists. If it does not, tell the user and exit.
|
||||
if not os.path.isfile(config.SQLITE_PATH):
|
||||
print "The configuration database %s does not exist.\n" % config.SQLITE_PATH
|
||||
print "Please run 'python %s' to create it.\nExiting..." % os.path.join(os.path.dirname(os.path.realpath(__file__)), 'setup.py')
|
||||
sys.exit(1)
|
||||
|
||||
##########################################################################
|
||||
# Server starup
|
||||
##########################################################################
|
||||
|
@ -10,9 +10,10 @@
|
||||
"""The main pgAdmin module. This handles the application initialisation tasks,
|
||||
such as setup of logging, dynamic loading of modules etc."""
|
||||
|
||||
from flask import Flask
|
||||
from flask import Flask, abort
|
||||
from flask.ext.sqlalchemy import SQLAlchemy
|
||||
from flask.ext.security import Security, SQLAlchemyUserDatastore, login_required
|
||||
from flask_security.utils import login_user
|
||||
from flask_mail import Mail
|
||||
from settings_model import db, Role, User
|
||||
|
||||
@ -66,8 +67,12 @@ def create_app(app_name=config.APP_NAME):
|
||||
##########################################################################
|
||||
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + config.SQLITE_PATH.replace('\\', '/')
|
||||
app.config['SECURITY_RECOVERABLE'] = True
|
||||
app.config['SECURITY_CHANGEABLE'] = True
|
||||
|
||||
# Only enable password related functionality in server mode.
|
||||
if config.SERVER_MODE == True:
|
||||
# TODO: Figure out how to disable /logout and /login
|
||||
app.config['SECURITY_RECOVERABLE'] = True
|
||||
app.config['SECURITY_CHANGEABLE'] = True
|
||||
|
||||
# Create database connection object and mailer
|
||||
db.init_app(app)
|
||||
@ -100,6 +105,29 @@ def create_app(app_name=config.APP_NAME):
|
||||
app.logger.info('Registering blueprint module: %s' % f)
|
||||
app.register_blueprint(module.views.blueprint)
|
||||
|
||||
##########################################################################
|
||||
# Handle the desktop login
|
||||
##########################################################################
|
||||
|
||||
@app.before_request
|
||||
def before_request():
|
||||
"""Login the default user if running in desktop mode"""
|
||||
if config.SERVER_MODE == False:
|
||||
user = user_datastore.get_user(config.DESKTOP_USER)
|
||||
|
||||
# Throw an error if we failed to find the desktop user, to give
|
||||
# the sysadmin a hint. We'll continue to try to login anyway as
|
||||
# that'll through a nice 500 error for us.
|
||||
if user is None:
|
||||
app.logger.error('The desktop user %s was not found in the configuration database.' % config.DESKTOP_USER)
|
||||
abort(401)
|
||||
|
||||
login_user(user)
|
||||
|
||||
##########################################################################
|
||||
# All done!
|
||||
##########################################################################
|
||||
|
||||
app.logger.debug('URL map: %s' % app.url_map)
|
||||
return app
|
||||
|
||||
|
@ -17,18 +17,23 @@
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">File <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{{ url_for('security.change_password') }}">Change Password</a></li>
|
||||
<li><a href="{{ url_for('utils.test') }}">Test URL</a></li>
|
||||
<li><a href="{{ url_for('utils.ping') }}">Ping</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{% if config.SERVER_MODE %}
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><img src="{{ username | gravatar }}" width="18" height="18"> {{ username }} <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ url_for('security.change_password') }}">Change Password</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="{{ url_for('security.logout') }}">Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="#"><img src="{{ username | gravatar }}" width="18" height="18"> {{ username }}</a></li>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
32
web/setup.py
32
web/setup.py
@ -16,7 +16,7 @@ from flask.ext.security import Security, SQLAlchemyUserDatastore
|
||||
from flask.ext.security.utils import encrypt_password
|
||||
from settings_model import db, Role, User
|
||||
|
||||
import getpass, os, sys
|
||||
import getpass, os, random, sys, string
|
||||
|
||||
# Configuration settings
|
||||
import config
|
||||
@ -31,8 +31,8 @@ print "======================================\n"
|
||||
|
||||
local_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config_local.py')
|
||||
if not os.path.isfile(local_config):
|
||||
print "%s does not exist.\n" % local_config
|
||||
print "Before running this script, ensure that config_local.py has been created"
|
||||
print "The configuration file %s does not exist.\n" % local_config
|
||||
print "Before running this application, ensure that config_local.py has been created"
|
||||
print "and sets values for SECRET_KEY, SECURITY_PASSWORD_SALT and CSRF_SESSION_KEY"
|
||||
print "at bare minimum. See config.py for more information and a complete list of"
|
||||
print "settings. Exiting..."
|
||||
@ -43,18 +43,26 @@ if os.path.isfile(config.SQLITE_PATH):
|
||||
print "The configuration database %s already exists and will not be overwritten.\nExiting..." % config.SQLITE_PATH
|
||||
sys.exit(1)
|
||||
|
||||
# Prompt the user for their default username and password.
|
||||
print "Enter the email address and password to use for the initial pgAdmin user account:\n"
|
||||
email = ''
|
||||
while email == '':
|
||||
email = raw_input("Email address: ")
|
||||
if config.SERVER_MODE == False:
|
||||
print "NOTE: Configuring authentication for DESKTOP mode."
|
||||
email = config.DESKTOP_USER
|
||||
p1 = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(32)])
|
||||
|
||||
pprompt = lambda: (getpass.getpass(), getpass.getpass('Retype password: '))
|
||||
else:
|
||||
print "NOTE: Configuring authentication for SERVER mode.\n"
|
||||
|
||||
# Prompt the user for their default username and password.
|
||||
print "Enter the email address and password to use for the initial pgAdmin user account:\n"
|
||||
email = ''
|
||||
while email == '':
|
||||
email = raw_input("Email address: ")
|
||||
|
||||
pprompt = lambda: (getpass.getpass(), getpass.getpass('Retype password: '))
|
||||
|
||||
p1, p2 = pprompt()
|
||||
while p1 != p2:
|
||||
print('Passwords do not match. Try again')
|
||||
p1, p2 = pprompt()
|
||||
while p1 != p2:
|
||||
print('Passwords do not match. Try again')
|
||||
p1, p2 = pprompt()
|
||||
|
||||
# Setup Flask-Security
|
||||
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||
|
Loading…
Reference in New Issue
Block a user