Ensure the initial password is properly hashed during setup in web mode. Fixes #2492

REL-1_X
Ashesh Vashi 2017-07-10 16:08:35 +01:00 committed by Dave Page
parent f06c3578f6
commit b095d1f33a
4 changed files with 88 additions and 24 deletions

View File

@ -86,6 +86,7 @@ Bug fixes
| `Bug #2486 <https://redmine.postgresql.org/issues/2486>`_ - Ensure the feature tests use the correct test settings database
| `Bug #2487 <https://redmine.postgresql.org/issues/2487>`_ - Maintain a client-side cache of preference values, populated using an async call
| `Bug #2489 <https://redmine.postgresql.org/issues/2489>`_ - Fix clipboard handling with large datasets
| `Bug #2492 <https://redmine.postgresql.org/issues/2492>`_ - Ensure the initial password is properly hashed during setup in web mode
| `Bug #2498 <https://redmine.postgresql.org/issues/2498>`_ - Properly handle bytea[], and 'infinity'::real/real[]
| `Bug #2502 <https://redmine.postgresql.org/issues/2502>`_ - Properly handle bytea[], and 'infinity'::real/real[]
| `Bug #2503 <https://redmine.postgresql.org/issues/2503>`_ - Handle missing/dropped synonyms gracefully

View File

@ -0,0 +1,47 @@
"""Encrypt the existing user password.
Revision ID: f195f9a4923d
Revises: 3c1e4b6eda55
Create Date: 2017-06-15 17:18:50.667139
"""
from flask import current_app
from flask_security import Security, SQLAlchemyUserDatastore
from flask_security.utils import verify_and_update_password
from pgadmin.model import Keys, db, User, Role
import config
# revision identifiers, used by Alembic.
revision = 'f195f9a4923d'
down_revision = '3c1e4b6eda55'
branch_labels = None
depends_on = None
def upgrade():
app = current_app
db.session.flush()
current_salt = Keys.query.filter_by(name = 'SECURITY_PASSWORD_SALT').first().value
app.config.update(dict(SECURITY_PASSWORD_SALT=current_salt))
app.config['SECURITY_PASSWORD_HASH'] = config.SECURITY_PASSWORD_HASH
if app.extensions.get('security') is None:
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
Security(app, user_datastore, register_blueprint=False)
else:
app.config['SECURITY_PASSWORD_SALT'] = current_salt
users = User.query.all()
# This will upgrade the plaintext password of all the user as per the
# SECURITY_PASSWORD_HASH.
for user in users:
if user.password is not None:
verify_and_update_password(user.password, user)
db.session.commit()
def downgrade():
pass

View File

@ -15,8 +15,15 @@ Create Date: 2017-03-13 11:15:16.401139
"""
from alembic import op
import base64
from flask import current_app
from flask_security import Security, SQLAlchemyUserDatastore
from flask_security.utils import encrypt_password
import os
import sqlalchemy as sa
from pgadmin.model import db
import config
from pgadmin.model import db, User, Role
from pgadmin.setup import get_version
from pgadmin.setup import user_info
@ -90,17 +97,6 @@ def upgrade():
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
sa.PrimaryKeyConstraint('id')
)
email, password = user_info()
db.engine.execute("""
INSERT INTO "user"
VALUES(1, '%s',
'%s',
1, NULL)
""" % (email, password))
db.engine.execute("""
INSERT INTO "version"
VALUES('ConfigDB', 2);
""")
db.engine.execute("""
INSERT INTO "role"
VALUES(1, 'Administrators', 'pgAdmin Administrators Role')
@ -113,6 +109,32 @@ VALUES(1, 1);
INSERT INTO "servergroup"
VALUES(1, 1, 'Servers')
""")
email, password = user_info()
current_salt = getattr(
config, 'SECURITY_PASSWORD_SALT', base64.urlsafe_b64encode(
os.urandom(32)
).decode()
)
if current_app.extensions.get('security') is None:
current_app.config['SECURITY_PASSWORD_SALT'] = current_salt
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
Security(current_app, user_datastore, register_blueprint=False)
else:
current_app.config['SECURITY_PASSWORD_SALT'] = current_salt
setattr(config, 'SECURITY_PASSWORD_SALT', current_salt)
password = encrypt_password(password)
db.engine.execute("""
INSERT INTO "user"
VALUES(1, '%s',
'%s',
1, NULL)
""" % (email, password))
db.engine.execute("""
INSERT INTO "version"
VALUES('ConfigDB', 2);
""")
# ### end Alembic commands ###

View File

@ -13,7 +13,6 @@ and settings database."""
import os
import sys
from flask import Flask
# We need to include the root directory in sys.path to ensure that we can
# find everything we need when running in the standalone runtime.
@ -21,29 +20,24 @@ root = os.path.dirname(os.path.realpath(__file__))
if sys.path[0] != root:
sys.path.insert(0, root)
from pgadmin import create_app
if __name__ == '__main__':
# Configuration settings
import config
from pgadmin.model import db, SCHEMA_VERSION
from pgadmin.model import SCHEMA_VERSION
from pgadmin.setup import db_upgrade, create_app_data_directory
config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
app = Flask(__name__)
app.config.from_object(config)
if "PGADMIN_TESTING_MODE" in os. environ and \
os.environ["PGADMIN_TESTING_MODE"] == "1":
config.SQLITE_PATH = config.TEST_SQLITE_PATH
create_app_data_directory(config)
app.config['SQLALCHEMY_DATABASE_URI'] = \
'sqlite:///' + config.SQLITE_PATH.replace('\\', '/')
db.init_app(app)
app = create_app()
print(u"pgAdmin 4 - Application Initialisation")
print(u"======================================\n")
db_upgrade(app)
with app.app_context():
db_upgrade(app)