Skip to content
Snippets Groups Projects
Commit a97358ed authored by Julian's avatar Julian
Browse files

Fix "Migrate OAuth2 and API clients to database"

The migration originally failed to convert the passwords/secrets to the
format expected by PasswordHash resulting in invalid password hashes. With
this change, the migration works correctly.

Also fixes minor template bug.
parent fa67bde0
Branches
Tags
No related merge requests found
...@@ -5,6 +5,11 @@ Revises: 09d2edcaf0cc ...@@ -5,6 +5,11 @@ Revises: 09d2edcaf0cc
Create Date: 2022-02-17 21:14:00.440057 Create Date: 2022-02-17 21:14:00.440057
""" """
import secrets
import hashlib
import base64
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from flask import current_app from flask import current_app
...@@ -14,6 +19,13 @@ down_revision = '09d2edcaf0cc' ...@@ -14,6 +19,13 @@ down_revision = '09d2edcaf0cc'
branch_labels = None branch_labels = None
depends_on = None depends_on = None
def hash_ssha512(password):
salt = secrets.token_bytes(8)
ctx = hashlib.new('sha512')
ctx.update(password.encode())
ctx.update(salt)
return '{ssha512}' + base64.b64encode(ctx.digest() + salt).decode()
def upgrade(): def upgrade():
used_service_names = set() used_service_names = set()
services = {} # name -> limit_access, access_group_name services = {} # name -> limit_access, access_group_name
...@@ -117,7 +129,7 @@ def upgrade(): ...@@ -117,7 +129,7 @@ def upgrade():
sa.UniqueConstraint('auth_username', name=op.f('uq_api_client_auth_username')) sa.UniqueConstraint('auth_username', name=op.f('uq_api_client_auth_username'))
) )
for service_name, auth_username, auth_password, perm_users, perm_checkpassword, perm_mail_aliases in api_clients: for service_name, auth_username, auth_password, perm_users, perm_checkpassword, perm_mail_aliases in api_clients:
op.execute(api_client_table.insert().values(service_id=sa.select([service_table.c.id]).where(service_table.c.name==service_name).as_scalar(), auth_username=auth_username, auth_password=auth_password, perm_users=perm_users, perm_checkpassword=perm_checkpassword, perm_mail_aliases=perm_mail_aliases)) op.execute(api_client_table.insert().values(service_id=sa.select([service_table.c.id]).where(service_table.c.name==service_name).as_scalar(), auth_username=auth_username, auth_password=hash_ssha512(auth_password), perm_users=perm_users, perm_checkpassword=perm_checkpassword, perm_mail_aliases=perm_mail_aliases))
oauth2client_table = op.create_table('oauth2client', oauth2client_table = op.create_table('oauth2client',
sa.Column('db_id', sa.Integer(), autoincrement=True, nullable=False), sa.Column('db_id', sa.Integer(), autoincrement=True, nullable=False),
...@@ -144,7 +156,7 @@ def upgrade(): ...@@ -144,7 +156,7 @@ def upgrade():
sa.PrimaryKeyConstraint('id', name=op.f('pk_oauth2redirect_uri')) sa.PrimaryKeyConstraint('id', name=op.f('pk_oauth2redirect_uri'))
) )
for service_name, client_id, client_secret, redirect_uris, logout_uris in oauth2_clients: for service_name, client_id, client_secret, redirect_uris, logout_uris in oauth2_clients:
op.execute(oauth2client_table.insert().values(service_id=sa.select([service_table.c.id]).where(service_table.c.name==service_name).as_scalar(), client_id=client_id, client_secret=client_secret)) op.execute(oauth2client_table.insert().values(service_id=sa.select([service_table.c.id]).where(service_table.c.name==service_name).as_scalar(), client_id=client_id, client_secret=hash_ssha512(client_secret)))
for method, uri, in logout_uris: for method, uri, in logout_uris:
op.execute(oauth2logout_uri_table.insert().values(client_db_id=sa.select([oauth2client_table.c.db_id]).where(oauth2client_table.c.client_id==client_id).as_scalar(), method=method, uri=uri)) op.execute(oauth2logout_uri_table.insert().values(client_db_id=sa.select([oauth2client_table.c.db_id]).where(oauth2client_table.c.client_id==client_id).as_scalar(), method=method, uri=uri))
for uri in redirect_uris: for uri in redirect_uris:
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
{% endmacro %} {% endmacro %}
{% if request.user and request.user.is_in_group(config['ACL_ADMIN_GROUP']) %} {% if request.user and request.user.is_in_group(config['ACL_ADMIN_GROUP']) %}
<div class="text-right"> <div class="text-right mt-2">
<a href="{{ url_for('service.index') }}" class="btn btn-primary">{{ _('Manage OAuth2 and API clients') }}</a> <a href="{{ url_for('service.index') }}" class="btn btn-primary">{{ _('Manage OAuth2 and API clients') }}</a>
</div> </div>
{% endif %} {% endif %}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment