Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Checks for invalid characters when creating unit #1154

Merged
merged 12 commits into from
Apr 13, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ Please add a _short_ line describing the PR you make, if the PR implements a spe
- New Data Delivery System logo ([#1148](https://github.com/ScilifelabDataCentre/dds_web/pull/1148))
- Cronjob: Scheduled task for deleting unanswered invites after a week ([#1147](https://github.com/ScilifelabDataCentre/dds_web/pull/1147))
- Checkbox in registration form and policy to agree to ([#1151](https://github.com/ScilifelabDataCentre/dds_web/pull/1151))
- Patch: Add checks for valid public_id when creating new unit to avoid bucket name errors ([#1154](https://github.com/ScilifelabDataCentre/dds_web/pull/1154))
25 changes: 24 additions & 1 deletion dds_web/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import datetime
import pathlib
import sys
import re

# Installed
import click
Expand Down Expand Up @@ -368,9 +369,31 @@ def create_new_unit(
days_in_available,
days_in_expired,
):
"""Create a new unit."""
"""Create a new unit.

Rules for bucket names, which are affected by the public_id at the moment:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
"""
from dds_web.database import models

error_message = ""
if len(public_id) > 50:
error_message = "The 'public_id' can be a maximum of 50 characters"
elif re.findall(r"[^a-zA-Z0-9.-]", public_id):
error_message = (
"The 'public_id' can only contain letters, numbers, dots (.) and hyphens (-)."
)
elif public_id[0] in [".", "-"]:
error_message = "The 'public_id' must begin with a letter or number."
elif public_id.count(".") > 2:
error_message = "The 'public_id' should not contain more than two dots."
elif public_id.startswith("xn--"):
error_message = "The 'public_id' cannot begin with the 'xn--' prefix."

if error_message:
flask.current_app.logger.error(error_message)
return

new_unit = models.Unit(
name=name,
public_id=public_id,
Expand Down
2 changes: 1 addition & 1 deletion dds_web/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class Unit(db.Model):

# Columns
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
public_id = db.Column(db.String(255), unique=True, nullable=False)
public_id = db.Column(db.String(50), unique=True, nullable=False)
i-oden marked this conversation as resolved.
Show resolved Hide resolved
name = db.Column(db.String(255), unique=True, nullable=False)
external_display_name = db.Column(db.String(255), unique=False, nullable=False)
contact_email = db.Column(db.String(255), unique=False, nullable=True)
Expand Down
8 changes: 7 additions & 1 deletion migrations/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ def run_migrations_offline():

"""
url = config.get_main_option("sqlalchemy.url")
context.configure(url=url, target_metadata=target_metadata, literal_binds=True)
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
compare_type=True,
)

with context.begin_transaction():
context.run_migrations()
Expand Down Expand Up @@ -76,6 +81,7 @@ def process_revision_directives(context, revision, directives):
target_metadata=target_metadata,
process_revision_directives=process_revision_directives,
**current_app.extensions["migrate"].configure_args,
compare_type=True,
)

with context.begin_transaction():
Expand Down
110 changes: 110 additions & 0 deletions migrations/versions/1ab892d08e16_change_public_id_length.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"""change_public_id_length

Revision ID: 1ab892d08e16
Revises: 1fbd604872e9
Create Date: 2022-04-13 06:16:56.046361

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = "1ab892d08e16"
down_revision = "1fbd604872e9"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"invites",
"nonce",
existing_type=mysql.TINYBLOB(),
type_=sa.LargeBinary(length=12),
existing_nullable=True,
)
op.alter_column(
"projects",
"public_key",
existing_type=mysql.TINYBLOB(),
type_=sa.LargeBinary(length=100),
existing_nullable=True,
)
op.alter_column(
"units",
"public_id",
existing_type=mysql.VARCHAR(length=255),
type_=sa.String(length=50),
existing_nullable=False,
)
op.alter_column(
"users",
"hotp_secret",
existing_type=mysql.TINYBLOB(),
type_=sa.LargeBinary(length=20),
existing_nullable=False,
)
op.alter_column(
"users",
"kd_salt",
existing_type=mysql.TINYBLOB(),
type_=sa.LargeBinary(length=32),
existing_nullable=True,
)
op.alter_column(
"users",
"nonce",
existing_type=mysql.TINYBLOB(),
type_=sa.LargeBinary(length=12),
existing_nullable=True,
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"users",
"nonce",
existing_type=sa.LargeBinary(length=12),
type_=mysql.TINYBLOB(),
existing_nullable=True,
)
op.alter_column(
"users",
"kd_salt",
existing_type=sa.LargeBinary(length=32),
type_=mysql.TINYBLOB(),
existing_nullable=True,
)
op.alter_column(
"users",
"hotp_secret",
existing_type=sa.LargeBinary(length=20),
type_=mysql.TINYBLOB(),
existing_nullable=False,
)
op.alter_column(
"units",
"public_id",
existing_type=sa.String(length=50),
type_=mysql.VARCHAR(length=255),
existing_nullable=False,
)
op.alter_column(
"projects",
"public_key",
existing_type=sa.LargeBinary(length=100),
type_=mysql.TINYBLOB(),
existing_nullable=True,
)
op.alter_column(
"invites",
"nonce",
existing_type=sa.LargeBinary(length=12),
type_=mysql.TINYBLOB(),
existing_nullable=True,
)
# ### end Alembic commands ###