Skip to content

Commit

Permalink
chore(master): merge maint-0.9
Browse files Browse the repository at this point in the history
chore(maint-0.9): release 0.9.5 (reanahub#219)
feat(cli): add new `migrate-secret-key` command (reanahub#240)
ci(python): test more Python versions (reanahub#239)
ci(actions): pin setuptools 70 (reanahub#239)

Note: The merge commit removes the changes related to pinning
`setuptools` to version 70, because this was only necessary for the
`maint-0.9` branches, as well as other 0.9.4 release-related changes.
  • Loading branch information
tiborsimko committed Dec 4, 2024
2 parents 05a34ba + 922a2b6 commit 7349c46
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.9.4"
".": "0.9.5"
}
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## [0.9.5](https://github.com/reanahub/reana-db/compare/0.9.4...0.9.5) (2024-11-26)


### Features

* **cli:** add new `migrate-secret-key` command ([#240](https://github.com/reanahub/reana-db/issues/240)) ([efcbe72](https://github.com/reanahub/reana-db/commit/efcbe724a2797edf94a531a2fd49ae0dc25d29f7))


### Continuous integration

* **actions:** pin setuptools 70 ([#239](https://github.com/reanahub/reana-db/issues/239)) ([3202759](https://github.com/reanahub/reana-db/commit/320275969c64513f695ce59a145088f6222aa594))
* **python:** test more Python versions ([#239](https://github.com/reanahub/reana-db/issues/239)) ([e0cba7f](https://github.com/reanahub/reana-db/commit/e0cba7faa97cbf2919c4008ec884ea46ec817cd5))

## [0.9.4](https://github.com/reanahub/reana-db/compare/0.9.3...0.9.4) (2024-03-01)


Expand Down
20 changes: 20 additions & 0 deletions reana_db/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from reana_db.database import init_db
from reana_db.models import Resource, ResourceType
from reana_db.utils import (
change_key_encrypted_columns,
update_users_cpu_quota,
update_users_disk_quota,
update_workflows_cpu_quota,
Expand All @@ -43,6 +44,25 @@ def init():
click.secho("Database initialised.", fg="green")


@cli.command()
@click.option(
"--old-key",
required=True,
help="Previous key used to encrypt database columns.",
)
def migrate_secret_key(old_key):
"""Change the secret key used to encrypt database columns."""
click.echo("Migrating secret key...")

try:
change_key_encrypted_columns(old_key)
except Exception:
logging.exception("Failed to migrate secret key")
sys.exit(1)

click.echo("Successfully migrated secret key")


@cli.group("alembic")
@click.pass_context
def alembic_group(ctx):
Expand Down
11 changes: 10 additions & 1 deletion reana_db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ def generate_uuid():
return str(uuid.uuid4())


def _secret_key():
"""Secret key used to encrypt databse columns.
Do not use `DB_SECRET_KEY` directly, as that does not let us change the key
at runtime, which is needed when migrating between different keys.
"""
return reana_db.config.DB_SECRET_KEY


class QuotaBase:
"""Quota base functionality."""

Expand Down Expand Up @@ -333,7 +342,7 @@ class UserToken(Base, Timestamp):

id_ = Column(UUIDType, primary_key=True, default=generate_uuid)
token = Column(
EncryptedType(String(length=255), DB_SECRET_KEY, AesEngine, "pkcs5"),
EncryptedType(String(length=255), _secret_key, AesEngine, "pkcs5"),
unique=True,
)
status = Column(Enum(UserTokenStatus))
Expand Down
30 changes: 30 additions & 0 deletions reana_db/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,3 +670,33 @@ def update_workflows_disk_quota() -> None:
for workflow in workflows:
store_workflow_disk_quota(workflow)
timer.count_event()


def change_key_encrypted_columns(old_key):
"""Re-encrypt database columns with new secret key.
REANA should be already deployed with the new secret key in `REANA_SECRET_KEY`.
The old key is needed to decrypt the database and is passed as parameter.
"""
from reana_db.database import Session
from reana_db.models import UserToken
from reana_db import config

new_key = config.DB_SECRET_KEY

# set old key to be able to decrypt columns in database
config.DB_SECRET_KEY = old_key

# read the columns from the database
user_tokens = Session.query(UserToken.id_, UserToken.token).all()
Session.expunge_all()

# revert to new key
config.DB_SECRET_KEY = new_key

# write columns to the database to encrypt them with new key
for user_token in user_tokens:
UserToken.query.filter_by(id_=user_token.id_).update(
{"token": user_token.token}
)
Session.commit()

0 comments on commit 7349c46

Please sign in to comment.