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

Development Utilities and Misc Fixes #40

Merged
merged 2 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Remove username column from users table

Revision ID: dc3dd97eae46
Revises: 945ca77479d1
Create Date: 2024-03-05 13:21:29.812837

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "dc3dd97eae46"
down_revision: Union[str, None] = "945ca77479d1"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade():
op.drop_column("users", "username")


def downgrade():
op.add_column(
"users",
sa.Column("username", sa.String, nullable=True),
)
1 change: 0 additions & 1 deletion nad_ch/application/use_cases/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def get_or_create_user(ctx: ApplicationContext, provider_name: str, email: str)

new_user = User(
email=email,
username=email.split("@")[0],
login_provider=provider_name,
logout_url=ctx.auth.get_logout_url(provider_name),
)
Expand Down
2 changes: 1 addition & 1 deletion nad_ch/controllers/web/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<div class="grid-row">
<div class="grid-col">
{% if current_user.is_authenticated %}
<p>Hi, {{ current_user.username }}!</p>
<p>Hi, {{ current_user.email }}!</p>
<p>Thanks for logging in with {{ current_user.login_provider }}.</p>
{% else %}
<ul class="usa-card-group">
Expand Down
5 changes: 2 additions & 3 deletions nad_ch/domain/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ def has_report(self) -> bool:


class User(Entity):
def __init__(self, username, email, login_provider, logout_url, id: int = None):
def __init__(self, email, login_provider, logout_url, id: int = None):
super().__init__(id)
self.username = username
self.email = email
self.login_provider = login_provider
self.logout_url = logout_url
Expand All @@ -91,4 +90,4 @@ def get_id(self) -> str:
raise NotImplementedError("No `id` attribute - override `get_id`") from None

def __repr__(self):
return f"User {self.id}, {self.username}, {self.email})"
return f"User {self.id}, {self.email})"
7 changes: 7 additions & 0 deletions nad_ch/infrastructure/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ def fetch_user_email_from_login_provider(

return None

def get_logout_url(self, provider_name: str) -> str | None:
provider_config = self._providers[provider_name]
if not provider_config:
return None

return provider_config["logout_url"]

def make_login_url(self, provider_name: str, state_token: str) -> str | None:
provider_config = self._providers[provider_name]
if not provider_config:
Expand Down
3 changes: 0 additions & 3 deletions nad_ch/infrastructure/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ def to_entity(self, producer: DataProducer):
class UserModel(UserMixin, CommonBase):
__tablename__ = "users"

username = Column(String)
email = Column(String)
login_provider = Column(String)
logout_url = Column(String)
Expand All @@ -123,7 +122,6 @@ def from_entity(user):
model = UserModel(
id=user.id,
email=user.email,
username=user.username,
login_provider=user.login_provider,
logout_url=user.logout_url,
)
Expand All @@ -133,7 +131,6 @@ def to_entity(self):
entity = User(
id=self.id,
email=self.email,
username=self.username,
login_provider=self.login_provider,
logout_url=self.logout_url,
)
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pytest-env = "^1.1.3"
cli = "nad_ch.main:run_cli"
format = "scripts.format:main"
lint = "flake8.main.cli:main"
migrate_down = "scripts.migrate_down:main"
migrate_up = "scripts.migrate_up:main"
seed = "scripts.seed:main"
start-web = "nad_ch.main:serve_flask_app"
test = "pytest:main"

Expand Down
2 changes: 1 addition & 1 deletion scripts/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


def main():
subprocess.run(["black", "./nad_ch", "./alembic", "./tests"])
subprocess.run(["black", "./alembic", "./nad_ch", "./scripts", "./tests"])


if __name__ == "__main__":
Expand Down
45 changes: 45 additions & 0 deletions scripts/migrate_down.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import os
from alembic.config import Config
from alembic import command
from boto3.session import Session
from botocore.client import Config as BotocoreConfig
from nad_ch.config.development_local import (
S3_ENDPOINT,
S3_ACCESS_KEY,
S3_SECRET_ACCESS_KEY,
S3_BUCKET_NAME,
)


def main():
if os.getenv("APP_ENV") != "dev_local":
raise Exception("This script can only be run in a local dev environment.")

current_script_path = os.path.abspath(__file__)
project_root = os.path.dirname(os.path.dirname(current_script_path))
alembic_cfg_path = os.path.join(project_root, "alembic.ini")

alembic_cfg = Config(alembic_cfg_path)
command.downgrade(alembic_cfg, "base")

# flush storage
session = Session()
minio_client = session.client(
"s3",
endpoint_url=S3_ENDPOINT,
aws_access_key_id=S3_ACCESS_KEY,
aws_secret_access_key=S3_SECRET_ACCESS_KEY,
aws_session_token=None,
region_name="us-east-1",
verify=False,
config=BotocoreConfig(signature_version="s3v4"),
)
response = minio_client.list_objects_v2(Bucket=S3_BUCKET_NAME)

for object in response["Contents"]:
print("Deleting", object["Key"])
minio_client.delete_object(Bucket=S3_BUCKET_NAME, Key=object["Key"])


if __name__ == "__main__":
main()
19 changes: 19 additions & 0 deletions scripts/migrate_up.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import os
from alembic.config import Config
from alembic import command


def main():
if os.getenv("APP_ENV") != "dev_local":
raise Exception("This script can only be run in a local dev environment.")

current_script_path = os.path.abspath(__file__)
project_root = os.path.dirname(os.path.dirname(current_script_path))
alembic_cfg_path = os.path.join(project_root, "alembic.ini")

alembic_cfg = Config(alembic_cfg_path)
command.upgrade(alembic_cfg, "head")


if __name__ == "__main__":
main()
54 changes: 54 additions & 0 deletions scripts/seed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import os
import zipfile
from nad_ch.config import create_app_context, OAUTH2_CONFIG
from nad_ch.domain.entities import DataProducer, DataSubmission, User


def zip_directory(folder_path, zip_path):
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(folder_path):
for file in files:
zipf.write(
os.path.join(root, file),
os.path.relpath(
os.path.join(root, file), os.path.join(folder_path, "..")
),
)


def main():
if os.getenv("APP_ENV") != "dev_local":
raise Exception("This script can only be run in a local dev environment.")

ctx = create_app_context()

new_producer = DataProducer(name="New Jersey")
saved_producer = ctx.producers.add(new_producer)

new_user = User(
email="[email protected]",
login_provider="cloudgov",
logout_url=OAUTH2_CONFIG["cloudgov"]["logout_url"],
)
ctx.users.add(new_user)

current_script_path = os.path.abspath(__file__)
project_root = os.path.dirname(os.path.dirname(current_script_path))
gdb_path = os.path.join(
project_root, "tests", "test_data", "geodatabases", "Naperville.gdb"
)
zipped_gdb_path = os.path.join(
project_root, "tests", "test_data", "geodatabases", "Naperville.gdb.zip"
)
zip_directory(gdb_path, zipped_gdb_path)

filename = DataSubmission.generate_filename(zipped_gdb_path, saved_producer)
ctx.storage.upload(zipped_gdb_path, filename)
new_submission = DataSubmission(filename, saved_producer)
ctx.submissions.add(new_submission)

os.remove(zipped_gdb_path)


if __name__ == "__main__":
main()
5 changes: 1 addition & 4 deletions tests/application/use_cases/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ def test_get_or_create_user_existing_user(app_context):
app_context.auth.make_login_url = lambda x: "test"
email = "[email protected]"
login_provider = "test"
user = User(
username="johnny", email=email, login_provider=login_provider, logout_url="test"
)
user = User(email=email, login_provider=login_provider, logout_url="test")
app_context.users.add(user)
result = get_or_create_user(app_context, login_provider, email)
assert result == user
Expand All @@ -35,7 +33,6 @@ def test_get_or_create_user_new_user(app_context):
result = get_or_create_user(app_context, login_provider, email)
assert isinstance(result, User)
assert result.email == email
assert result.username == "johnny"
assert result.login_provider == login_provider


Expand Down
Loading