mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-01-07 22:53:45 -06:00
Update the setup script and config database to handle versioning.
This allows us to update the configuration database schema as needed, and use the setup script to update it to the current version. NOTE: Existing databases will need to be recreated once following this commit. It doesn't seem worth handling the "upgrade from v0" case when I'm probably the only active developer right now.
This commit is contained in:
parent
f040efb473
commit
7f68d6fced
@ -123,6 +123,10 @@ MINIFY_HTML = True;
|
||||
# User account and settings storage
|
||||
##########################################################################
|
||||
|
||||
# The schema version number for the configuration database
|
||||
# DO NOT CHANGE UNLESS YOU ARE A PGADMIN DEVELOPER!!
|
||||
SETTINGS_SCHEMA_VERSION = 2
|
||||
|
||||
# The default path to the SQLite database used to store user accounts and
|
||||
# settings. This default places the file in the same directory as this
|
||||
# config file, but generates an absolute path for use througout the app.
|
||||
|
@ -7,7 +7,16 @@
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""Defines the models for the configuration database."""
|
||||
"""Defines the models for the configuration database.
|
||||
|
||||
If any of the models are updated, you (yes, you, the developer) MUST do two
|
||||
things:
|
||||
|
||||
1) Increment SETTINGS_SCHEMA_VERSION in config.py
|
||||
|
||||
2) Modify setup.py to ensure that the appropriate changes are made to the config
|
||||
database to upgrade it to the new version.
|
||||
"""
|
||||
|
||||
from flask.ext.sqlalchemy import SQLAlchemy
|
||||
from flask.ext.security import UserMixin, RoleMixin
|
||||
@ -19,21 +28,26 @@ roles_users = db.Table('roles_users',
|
||||
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
|
||||
db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
|
||||
|
||||
class Version(db.Model):
|
||||
"""Version numbers for reference/upgrade purposes"""
|
||||
__tablename__ = 'version'
|
||||
name = db.Column(db.String(32), primary_key=True)
|
||||
value = db.Column(db.Integer(), nullable=False)
|
||||
|
||||
class Role(db.Model, RoleMixin):
|
||||
"""Define a security role"""
|
||||
__tablename__ = 'role'
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
name = db.Column(db.String(80), unique=True)
|
||||
description = db.Column(db.String(255))
|
||||
name = db.Column(db.String(128), unique=True, nullable=False)
|
||||
description = db.Column(db.String(256), nullable=False)
|
||||
|
||||
class User(db.Model, UserMixin):
|
||||
"""Define a user object"""
|
||||
__tablename__ = 'user'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
email = db.Column(db.String(255), unique=True)
|
||||
password = db.Column(db.String(255))
|
||||
active = db.Column(db.Boolean())
|
||||
active = db.Column(db.Boolean())
|
||||
email = db.Column(db.String(256), unique=True, nullable=False)
|
||||
password = db.Column(db.String(256))
|
||||
active = db.Column(db.Boolean(), nullable=False)
|
||||
confirmed_at = db.Column(db.DateTime())
|
||||
roles = db.relationship('Role', secondary=roles_users,
|
||||
backref=db.backref('users', lazy='dynamic'))
|
||||
@ -42,14 +56,29 @@ class Setting(db.Model):
|
||||
"""Define a setting object"""
|
||||
__tablename__ = 'setting'
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
|
||||
setting = db.Column(db.String(255), primary_key=True)
|
||||
setting = db.Column(db.String(256), primary_key=True)
|
||||
value = db.Column(db.String(1024))
|
||||
|
||||
|
||||
class ServerGroup(db.Model):
|
||||
"""Define a server group for the treeview"""
|
||||
__tablename__ = 'servergroup'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
name = db.Column(db.String(80))
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
name = db.Column(db.String(128), nullable=False)
|
||||
__table_args__ = (db.UniqueConstraint('user_id', 'name'),)
|
||||
|
||||
|
||||
class Server(db.Model):
|
||||
"""Define a registered Postgres server"""
|
||||
__tablename__ = 'server'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
servergroup_id = db.Column(db.Integer, db.ForeignKey('servergroup.id'), nullable=False)
|
||||
name = db.Column(db.String(128), nullable=False)
|
||||
host = db.Column(db.String(128), nullable=False)
|
||||
port = db.Column(db.Integer(), db.CheckConstraint('port >= 1024 AND port <= 65534'), nullable=False)
|
||||
maintenance_db = db.Column(db.String(64), nullable=False)
|
||||
username = db.Column(db.String(64), nullable=False)
|
||||
ssl_mode = db.Column(db.String(16), nullable=False)
|
||||
|
||||
|
||||
|
147
web/setup.py
147
web/setup.py
@ -14,7 +14,7 @@ from flask import Flask
|
||||
from flask.ext.sqlalchemy import SQLAlchemy
|
||||
from flask.ext.security import Security, SQLAlchemyUserDatastore
|
||||
from flask.ext.security.utils import encrypt_password
|
||||
from pgadmin.settings.settings_model import db, Role, User, ServerGroup
|
||||
from pgadmin.settings.settings_model import db, Role, User, Server, ServerGroup, Version
|
||||
|
||||
import getpass, os, random, sys, string
|
||||
|
||||
@ -26,6 +26,100 @@ app.config.from_object(config)
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + config.SQLITE_PATH.replace('\\', '/')
|
||||
db.init_app(app)
|
||||
|
||||
def do_setup():
|
||||
"""Create a new settings database from scratch"""
|
||||
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)])
|
||||
|
||||
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()
|
||||
|
||||
# Setup Flask-Security
|
||||
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||
security = Security(app, user_datastore)
|
||||
|
||||
with app.app_context():
|
||||
password = encrypt_password(p1)
|
||||
|
||||
db.create_all()
|
||||
user_datastore.create_role(name='Administrators', description='pgAdmin Administrators Role')
|
||||
user_datastore.create_user(email=email, password=password)
|
||||
user_datastore.add_role_to_user(email, 'Administrators')
|
||||
|
||||
# Get the user's ID and create the default server group
|
||||
user = User.query.filter_by(email=email).first()
|
||||
server_group = ServerGroup(user_id=user.id, name="Servers")
|
||||
db.session.merge(server_group)
|
||||
|
||||
# Set the schema version
|
||||
version = Version(name='ConfigDB', value=config.SETTINGS_SCHEMA_VERSION)
|
||||
db.session.merge(version)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# Done!
|
||||
print ""
|
||||
print "The configuration database has been created at %s" % config.SQLITE_PATH
|
||||
|
||||
def do_upgrade():
|
||||
"""Upgrade an existing settings database"""
|
||||
# Setup Flask-Security
|
||||
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||
security = Security(app, user_datastore)
|
||||
|
||||
with app.app_context():
|
||||
version = Version.query.filter_by(name='ConfigDB').first()
|
||||
|
||||
# Pre-flight checks
|
||||
if int(version.value) > int(config.SETTINGS_SCHEMA_VERSION):
|
||||
print "The database schema version is %d, whilst the version required by the software is %d.\nExiting..." \
|
||||
% (version.value, config.SETTINGS_SCHEMA_VERSION)
|
||||
sys.exit(1)
|
||||
elif int(version.value) == int(config.SETTINGS_SCHEMA_VERSION):
|
||||
print "The database schema version is %d as required.\nExiting..." % (version.value)
|
||||
sys.exit(1)
|
||||
|
||||
print "NOTE: Upgrading database schema from version %d to %d." % (version.value, config.SETTINGS_SCHEMA_VERSION)
|
||||
|
||||
#######################################################################
|
||||
# Run whatever is required to update the database schema to the current
|
||||
# version. Always use "< REQUIRED_VERSION" as the test for readability
|
||||
#######################################################################
|
||||
|
||||
# Changes introduced in schema version 2
|
||||
if int(version.value) < 2:
|
||||
# Create the 'server' table
|
||||
db.metadata.create_all(db.engine, tables=[Server.__table__])
|
||||
|
||||
# Finally, update the schema version
|
||||
version.value = config.SETTINGS_SCHEMA_VERSION
|
||||
db.session.merge(version)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# Done!
|
||||
print ""
|
||||
print "The configuration database %s has been upgraded to version %d" % (config.SQLITE_PATH, config.SETTINGS_SCHEMA_VERSION)
|
||||
|
||||
###############################################################################
|
||||
# Do stuff!
|
||||
###############################################################################
|
||||
|
||||
print "pgAdmin 4 - Application Initialisation"
|
||||
print "======================================\n"
|
||||
|
||||
@ -40,49 +134,8 @@ if not os.path.isfile(local_config):
|
||||
|
||||
# Check if the database exists. If it does, tell the user and exit.
|
||||
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)
|
||||
|
||||
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)])
|
||||
|
||||
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()
|
||||
|
||||
# Setup Flask-Security
|
||||
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||
security = Security(app, user_datastore)
|
||||
|
||||
with app.app_context():
|
||||
password = encrypt_password(p1)
|
||||
|
||||
db.create_all()
|
||||
user_datastore.create_role(name='Administrators', description='pgAdmin Administrators Role')
|
||||
user_datastore.create_user(email=email, password=password)
|
||||
user_datastore.add_role_to_user(email, 'Administrators')
|
||||
|
||||
# Get the user's ID and create the default server group
|
||||
user = User.query.filter_by(email=email).first()
|
||||
server_group = ServerGroup(user_id=user.id, name="Servers")
|
||||
db.session.merge(server_group)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# Done!
|
||||
print ""
|
||||
print "The configuration database has been created at %s" % config.SQLITE_PATH
|
||||
print "The configuration database %s already exists.\nEntering upgrade mode...\n" % config.SQLITE_PATH
|
||||
do_upgrade()
|
||||
else:
|
||||
print "The configuration database %s does not exist.\nEntering initial setup mode...\n" % config.SQLITE_PATH
|
||||
do_setup()
|
Loading…
Reference in New Issue
Block a user