Skip to content

Commit

Permalink
Merge pull request #26 from jadmsaadaot/handle-returning-users
Browse files Browse the repository at this point in the history
Handle returning users by checking their guid
  • Loading branch information
jadmsaadaot authored Aug 13, 2024
2 parents aceaa57 + 18c13a0 commit 3bee952
Show file tree
Hide file tree
Showing 26 changed files with 343 additions and 291 deletions.
55 changes: 55 additions & 0 deletions submit-api/migrations/versions/aeb2ae9d64b9_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""Add auth_guid column to account_users
Revision ID: aeb2ae9d64b9
Revises: 8e112bda0a34
Create Date: 2024-08-12 10:18:32.687612
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = 'aeb2ae9d64b9'
down_revision = '8e112bda0a34'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('staff_users', schema=None) as batch_op:
batch_op.drop_index('ix_staff_users_username')

op.drop_table('staff_users')
with op.batch_alter_table('account_users', schema=None) as batch_op:
batch_op.add_column(sa.Column('auth_guid', sa.String(), nullable=False, unique=True))
batch_op.create_index('ix_account_users_auth_guid', ['auth_guid'], unique=True)

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('account_users', schema=None) as batch_op:
batch_op.drop_index('ix_account_users_auth_guid')
batch_op.drop_column('auth_guid')

op.create_table('staff_users',
sa.Column('created_date', postgresql.TIMESTAMP(), autoincrement=False, nullable=False),
sa.Column('updated_date', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
sa.Column('first_name', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
sa.Column('middle_name', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
sa.Column('last_name', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
sa.Column('username', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
sa.Column('email_address', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
sa.Column('contact_number', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
sa.Column('created_by', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
sa.Column('updated_by', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
sa.PrimaryKeyConstraint('id', name='staff_users_pkey')
)
with op.batch_alter_table('staff_users', schema=None) as batch_op:
batch_op.create_index('ix_staff_users_username', ['username'], unique=True)

# ### end Alembic commands ###
1 change: 0 additions & 1 deletion submit-api/src/submit_api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"""This exports all of the models and schemas used by the application."""

from .db import db, ma, migrate
from .user import User
from .account_role import AccountRole
from .account_user import AccountUser
from .role import Role
Expand Down
2 changes: 2 additions & 0 deletions submit-api/src/submit_api/models/account_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class AccountUser(BaseModel):
position = Column(db.String(100), nullable=False)
work_email_address = Column(db.String(100), nullable=False)
work_contact_number = Column(db.String(50), nullable=False)
auth_guid = Column(db.String(), nullable=False)

@classmethod
def create_account_user(cls, data, session=None) -> AccountUser:
Expand All @@ -35,6 +36,7 @@ def create_account_user(cls, data, session=None) -> AccountUser:
position=data.get('position', None),
work_email_address=data.get('work_email_address', None),
work_contact_number=data.get('work_contact_number', None),
auth_guid=data.get('auth_guid', None)
)
if session:
session.add(account_user)
Expand Down
1 change: 1 addition & 0 deletions submit-api/src/submit_api/models/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ def session_scope():
session.commit()
except Exception as e: # noqa: B901, E722
print(str(e))
print(f"Rolling back the session; error: {e}")
session.rollback()
raise
29 changes: 29 additions & 0 deletions submit-api/src/submit_api/models/queries/account_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright © 2024 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Model to handle all complex operations related to User."""
from submit_api.models import AccountUser, db


# pylint: disable=too-few-public-methods
class UserQueries:
"""Query module for complex user queries"""

@classmethod
def get_by_guid(cls, guid: str):
"""Find user by guid"""
print(guid)
result = (db.session.query(AccountUser)
.filter(AccountUser.auth_guid == guid)
.first())
return result
59 changes: 0 additions & 59 deletions submit-api/src/submit_api/models/user.py

This file was deleted.

4 changes: 2 additions & 2 deletions submit-api/src/submit_api/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
from .apihelper import Api

from .ops import API as OPS_API
from .user import API as USER_API
from .account import API as ACCOUNT_API
from .user import API as USER_API

__all__ = ('API_BLUEPRINT', 'OPS_BLUEPRINT')

Expand All @@ -54,5 +54,5 @@

# HANDLER = ExceptionHandler(API)

API.add_namespace(USER_API)
API.add_namespace(ACCOUNT_API)
API.add_namespace(USER_API)
2 changes: 1 addition & 1 deletion submit-api/src/submit_api/resources/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
from submit_api.services.account_service import AccountService
from submit_api.utils.util import cors_preflight
from submit_api.schemas.account import AccountSchema, AccountCreateSchema
from submit_api.exceptions import ResourceNotFoundError
from .apihelper import Api as ApiHelper
from ..exceptions import ResourceNotFoundError

API = Namespace("accounts", description="Endpoints for Account Management")
"""Custom exception messages
Expand Down
89 changes: 18 additions & 71 deletions submit-api/src/submit_api/resources/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,93 +11,40 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""API endpoints for managing an user resource."""
"""API endpoints for managing an account resource."""

from http import HTTPStatus

from flask_restx import Namespace, Resource
from submit_api.services.user_service import UserService
from flask_restx import Namespace, Resource, cors
from submit_api.utils.util import cors_preflight
from submit_api.schemas.user import UserSchema, UserRequestSchema
from submit_api.exceptions import ResourceNotFoundError
from .apihelper import Api as ApiHelper
from ..schemas.user import UserSchema
from ..services.user_service import UserService

API = Namespace("users", description="Endpoints for User Management")
API = Namespace("users", description="Endpoints for Account Management")
"""Custom exception messages
"""

user_request_model = ApiHelper.convert_ma_schema_to_restx_model(
API, UserRequestSchema(), "User"
user_model = ApiHelper.convert_ma_schema_to_restx_model(
API, UserSchema(), "User"
)
user_list_model = ApiHelper.convert_ma_schema_to_restx_model(
API, UserSchema(), "UserListItem"
)


@cors_preflight("GET, OPTIONS, POST")
@API.route("", methods=["POST", "GET", "OPTIONS"])
class Users(Resource):
"""Resource for managing users."""

@staticmethod
@API.response(code=200, description="Success", model=[user_list_model])
@ApiHelper.swagger_decorators(API, endpoint_description="Fetch all users")
def get():
"""Fetch all users."""
users = UserService.get_all_users()
user_list_schema = UserSchema(many=True)
return user_list_schema.dump(users), HTTPStatus.OK

@staticmethod
@ApiHelper.swagger_decorators(API, endpoint_description="Create a user")
@API.expect(user_request_model)
@API.response(code=201, model=user_request_model, description="UserCreated")
@API.response(400, "Bad Request")
def post():
"""Create a user."""
user_data = UserRequestSchema().load(API.payload)
created_user = UserService.create_user(user_data)
return UserSchema().dump(created_user), HTTPStatus.CREATED


@cors_preflight("GET, OPTIONS, PATCH, DELETE")
@API.route("/<user_id>", methods=["PATCH", "GET", "OPTIONS", "DELETE"])
@API.doc(params={"user_id": "The user identifier"})
@cors_preflight("GET, OPTIONS")
@API.route("/guid/<string:guid>", methods=["GET", "OPTIONS"])
@API.doc(params={"guid": "The user global unique identifier"})
class User(Resource):
"""Resource for managing a single user"""
"""Resource for managing a single account"""

@staticmethod
@ApiHelper.swagger_decorators(API, endpoint_description="Fetch a user by id")
@API.response(code=200, model=user_list_model, description="Success")
@ApiHelper.swagger_decorators(API, endpoint_description="Fetch a user by guid")
@API.response(code=200, model=user_model, description="Success")
@API.response(404, "Not Found")
def get(user_id):
"""Fetch a user by id."""
user = UserService.get_user_by_id(user_id)
@cors.crossdomain(origin="*")
def get(guid):
"""Fetch an account by id."""
user = UserService.get_by_auth_guid(guid)
if not user:
raise ResourceNotFoundError(f"User with {user_id} not found")
return ResourceNotFoundError(f"User with guid {guid} not found")
return UserSchema().dump(user), HTTPStatus.OK

@staticmethod
@ApiHelper.swagger_decorators(API, endpoint_description="Update a user by id")
@API.expect(user_request_model)
@API.response(code=200, model=user_list_model, description="Success")
@API.response(400, "Bad Request")
@API.response(404, "Not Found")
def patch(user_id):
"""Update a user by id."""
user_data = UserRequestSchema().load(API.payload)
updated_user = UserService.update_user(user_id, user_data)
if not updated_user:
raise ResourceNotFoundError(f"User with {user_id} not found")
return UserSchema().dump(updated_user), HTTPStatus.OK

@staticmethod
@ApiHelper.swagger_decorators(API, endpoint_description="Delete a user by id")
@API.response(code=200, model=user_list_model, description="Deleted")
@API.response(404, "Not Found")
def delete(user_id):
"""Delete a user by id."""
deleted_user = UserService.delete_user(user_id)
if not deleted_user:
raise ResourceNotFoundError(f"User with {user_id} not found")
return UserSchema().dump(deleted_user), HTTPStatus.OK
1 change: 1 addition & 0 deletions submit-api/src/submit_api/schemas/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ class Meta: # pylint: disable=too-few-public-methods
work_contact_number = fields.Str(data_key="work_contact_number")
position = fields.Str(data_key="position")
proponent_id = fields.Str(data_key="proponent_id")
auth_guid = fields.Str(data_key="auth_guid")
19 changes: 19 additions & 0 deletions submit-api/src/submit_api/schemas/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Engagement model class.
Manages the engagement
"""

from marshmallow import EXCLUDE, Schema, fields


class ProjectSchema(Schema):
"""Account schema."""

class Meta: # pylint: disable=too-few-public-methods
"""Exclude unknown fields in the deserialized output."""

unknown = EXCLUDE

id = fields.Int(data_key="id")
project_id = fields.Str(data_key="project_id")
account_id = fields.Str(data_key="account_id")
23 changes: 3 additions & 20 deletions submit-api/src/submit_api/schemas/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,7 @@ class Meta: # pylint: disable=too-few-public-methods

id = fields.Int(data_key="id")
first_name = fields.Str(data_key="first_name")
middle_name = fields.Str(data_key="description")
last_name = fields.Str(data_key="last_name")
email_address = fields.Str(data_key="email_address")
contact_number = fields.Str(data_key="contact_number")
username = fields.Str(data_key="username")


class UserRequestSchema(Schema):
"""User Request Schema"""

class Meta: # pylint: disable=too-few-public-methods
"""Exclude unknown fields in the deserialized output."""

unknown = EXCLUDE

first_name = fields.Str(data_key="first_name")
middle_name = fields.Str(data_key="description")
last_name = fields.Str(data_key="last_name")
email_address = fields.Str(data_key="email_address")
contact_number = fields.Str(data_key="contact_number")
username = fields.Str(data_key="username")
work_email_address = fields.Str(data_key="email_address")
work_contact_number = fields.Str(data_key="contact_number")
account_id = fields.Int(data_key="account_id")
11 changes: 6 additions & 5 deletions submit-api/src/submit_api/services/account_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ def create_account(cls, data):
account = AccountModel.create_account(account_data, session)
account_user_data = {
"account_id": account.id,
"first_name": data["first_name"],
"last_name": data["last_name"],
"position": data["position"],
"work_email_address": data["work_email_address"],
"work_contact_number": data["work_contact_number"],
"first_name": data.get("first_name"),
"last_name": data.get("last_name"),
"position": data.get("position"),
"work_email_address": data.get("work_email_address"),
"work_contact_number": data.get("work_contact_number"),
'auth_guid': data.get('auth_guid')
}
account_user = AccountUserModel.create_account_user(account_user_data, session)

Expand Down
Loading

0 comments on commit 3bee952

Please sign in to comment.