Skip to content

Commit

Permalink
Merge pull request #23 from uwblueprint/safwaan/configure-auth-levels
Browse files Browse the repository at this point in the history
Add Relief Staff and Regular Staff as Roles
  • Loading branch information
Safewaan authored Feb 8, 2023
2 parents 8d739ce + 2d8855a commit cabbad1
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 25 deletions.
6 changes: 3 additions & 3 deletions backend/python/app/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

from . import db

roles_enum = db.Enum("User", "Admin", name="roles")


class User(db.Model):
__tablename__ = "users"
Expand All @@ -13,7 +11,9 @@ class User(db.Model):
first_name = db.Column(db.String, nullable=False)
last_name = db.Column(db.String, nullable=False)
auth_id = db.Column(db.String, nullable=False)
role = db.Column(roles_enum)
role = db.Column(
db.Enum("Admin", "Regular Staff", "Relief Staff", name="roles"), nullable=False
)

def to_dict(self, include_relationships=False):
# define the entities table
Expand Down
2 changes: 1 addition & 1 deletion backend/python/app/rest/auth_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def register():
Returns access token and user info in response body and sets refreshToken as an httpOnly cookie
"""
try:
request.json["role"] = "User"
request.json["role"] = "Relief Staff"
user = CreateUserDTO(**request.json)
user_service.create_user(user)
auth_dto = auth_service.generate_token(
Expand Down
13 changes: 7 additions & 6 deletions backend/python/app/rest/entity_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
# defines a shared URL prefix for all routes
blueprint = Blueprint("entity", __name__, url_prefix="/entities")


# defines GET endpoint for retrieving all entities
@blueprint.route("/", methods=["GET"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Relief Staff", "Regular Staff", "Admin"})
def get_entities():
result = entity_service.get_entities()
content_type = request.mimetype
Expand All @@ -40,7 +41,7 @@ def get_entities():

# defines GET endpoint for retrieving a single entity based on a provided id
@blueprint.route("/<int:id>", methods=["GET"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Relief Staff", "Regular Staff", "Admin"})
def get_entity(id):
try:
result = entity_service.get_entity(id)
Expand All @@ -54,7 +55,7 @@ def get_entity(id):

# define POST endpoint for creating an entity
@blueprint.route("/", methods=["POST"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Relief Staff", "Regular Staff", "Admin"})
@validate_request("EntityDTO")
def create_entity():
try:
Expand All @@ -77,7 +78,7 @@ def create_entity():

# defines PUT endpoint for updating the entity with the provided id
@blueprint.route("/<int:id>", methods=["PUT"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Relief Staff", "Regular Staff", "Admin"})
@validate_request("EntityDTO")
def update_entity(id):
try:
Expand All @@ -102,7 +103,7 @@ def update_entity(id):

# defines DELETE endpoint for deleting the entity with the provided id
@blueprint.route("/<int:id>", methods=["DELETE"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Relief Staff", "Regular Staff", "Admin"})
def delete_entity(id):
try:
result = entity_service.delete_entity(id)
Expand All @@ -115,7 +116,7 @@ def delete_entity(id):

# defines GET endpoint for a URL to the entity's file with the provided uuid
@blueprint.route("/files/<string:id>", methods=["GET"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Relief Staff", "Regular Staff", "Admin"})
def get_file(id):
try:
file_url = file_storage_service.get_file(id)
Expand Down
8 changes: 4 additions & 4 deletions backend/python/app/rest/user_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@


@blueprint.route("/", methods=["GET"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Relief Staff", "Regular Staff", "Admin"})
def get_users():
"""
Get all users, optionally filter by a user_id or email query parameter to retrieve a single user
Expand Down Expand Up @@ -96,7 +96,7 @@ def get_users():


@blueprint.route("/", methods=["POST"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Admin"})
@validate_request("CreateUserDTO")
def create_user():
"""
Expand All @@ -113,7 +113,7 @@ def create_user():


@blueprint.route("/<int:user_id>", methods=["PUT"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Relief Staff", "Regular Staff", "Admin"})
@validate_request("UpdateUserDTO")
def update_user(user_id):
"""
Expand All @@ -129,7 +129,7 @@ def update_user(user_id):


@blueprint.route("/", methods=["DELETE"], strict_slashes=False)
@require_authorization_by_role({"User", "Admin"})
@require_authorization_by_role({"Admin"})
def delete_user():
"""
Delete a user by user_id or email, specified through a query parameter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def generate_token_for_oauth(self, id_token):
first_name=google_user["firstName"],
last_name=google_user["lastName"],
email=google_user["email"],
role="User",
role="Relief Staff",
password="",
),
auth_id=google_user["localId"],
Expand Down
6 changes: 4 additions & 2 deletions backend/python/app/static/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,8 @@
"role": {
"type": "string",
"enum": [
"User",
"Relief Staff",
"Regular Staff",
"Admin"
]
},
Expand Down Expand Up @@ -863,7 +864,8 @@
"role": {
"type": "string",
"enum": [
"User",
"Relief Staff",
"Regular Staff",
"Admin"
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""add defined roles for users
Revision ID: 56b71c6b4977
Revises: 797bfedc3a06
Create Date: 2023-02-05 20:15:49.674896
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "56b71c6b4977"
down_revision = "797bfedc3a06"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"users",
"role",
existing_type=postgresql.ENUM(
"Admin", "Regular Staff", "Relief Staff", name="roles"
),
nullable=False,
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"users",
"role",
existing_type=postgresql.ENUM("User", "Admin", name="roles"),
nullable=True,
)
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ def upgrade():
sa.Column("first_name", sa.String(), nullable=False),
sa.Column("last_name", sa.String(), nullable=False),
sa.Column("auth_id", sa.String(), nullable=False),
sa.Column("role", sa.Enum("User", "Admin", name="roles"), nullable=True),
sa.Column(
"role",
sa.Enum("Admin", "Regular Staff", "Relief Staff", name="roles"),
nullable=True,
),
sa.PrimaryKeyConstraint("id"),
)
# ### end Alembic commands ###
Expand Down
2 changes: 1 addition & 1 deletion backend/python/tests/functional/test_user_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"auth_id": "B",
"first_name": "Hello",
"last_name": "World",
"role": "User",
"role": "Relief Staff",
},
]

Expand Down
2 changes: 1 addition & 1 deletion backend/python/tests/functional/test_user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def user_service():
"auth_id": "B",
"first_name": "Hello",
"last_name": "World",
"role": "User",
"role": "Relief Staff",
},
)

Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def register_user(backend_url, body, access_token_field):
assert response.status_code == 200
data = response.json()
assert "role" in data
assert data["role"] == "User"
assert data["role"] == "Relief Staff"
assert "id" in data
assert access_token_field in data
expected = {k: v for k, v in body.items() if k != "password"}
Expand Down
27 changes: 23 additions & 4 deletions e2e-tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,46 @@ def test_users(backend_url, auth_header, lang, api, new_user_email):
body1 = {
"firstName": "Test",
"lastName": "Script",
"role": "User",
"role": "Relief Staff",
"email": new_user_email,
"password": "password",
}
body2 = {
"firstName": "Test2",
"lastName": "Script2",
"role": "User",
"firstName": "Test",
"lastName": "Script",
"email": new_user_email,
"role": "Regular Staff",
}
body3 = {
"firstName": "Test",
"lastName": "Script",
"email": new_user_email,
"role": "Admin",
}
if lang != "ts":
body1 = {inflection.underscore(k): v for k, v in body1.items()}
body2 = {inflection.underscore(k): v for k, v in body2.items()}
body3 = {inflection.underscore(k): v for k, v in body3.items()}

user = create_user(backend_url, auth_header, body1)

# update to Regular Staff
updated_user = update_user(backend_url, auth_header, user["id"], body2)
retrieved_user_by_id = get_user_by_id(backend_url, auth_header, user["id"], lang)
assert updated_user == retrieved_user_by_id
retrieved_user_by_email = get_user_by_email(
backend_url, auth_header, updated_user["email"]
)
assert updated_user == retrieved_user_by_email

# update to Admin
updated_user = update_user(backend_url, auth_header, user["id"], body3)
retrieved_user_by_id = get_user_by_id(backend_url, auth_header, user["id"], lang)
assert updated_user == retrieved_user_by_id
retrieved_user_by_email = get_user_by_email(
backend_url, auth_header, updated_user["email"]
)
assert updated_user == retrieved_user_by_email

assert get_users(backend_url, auth_header)
delete_user(backend_url, auth_header, user["id"], lang)

0 comments on commit cabbad1

Please sign in to comment.