Skip to content
Draft
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
2 changes: 1 addition & 1 deletion submit-api/src/submit_api/models/staff_user_work.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class StaffUserWork(BaseModel):
lazy='joined',
back_populates='work_assignments')

work = db.relationship('TrackWork', foreign_keys=[work_id], lazy='joined')
work = db.relationship('TrackWork', foreign_keys=[work_id], lazy='joined', back_populates='staff_assignments')

@classmethod
def find_by_staff_user_id(cls, staff_user_id: int):
Expand Down
3 changes: 2 additions & 1 deletion submit-api/src/submit_api/models/track_work.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class TrackWork(BaseModel):
foreign_keys='StaffUserWork.work_id',
lazy='select',
cascade='all, delete',
passive_deletes=True
passive_deletes=True,
back_populates='work'
)

__table_args__ = (
Expand Down
14 changes: 14 additions & 0 deletions submit-api/src/submit_api/resources/submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from submit_api.models import Submission as SubmissionModel
from submit_api.resources.apihelper import Api as ApiHelper
from submit_api.schemas.submission import CreateSubmissionRequestSchema, SubmissionSchema, UpdateSubmissionStatusSchema
from submit_api.services.authorization import has_gis_extended_edit_role
from submit_api.services.package_access_control import PackageAccessControl
from submit_api.services.submission import SubmissionService
from submit_api.utils.util import allowedorigins, cors_preflight
Expand Down Expand Up @@ -226,10 +227,23 @@ class SubmissionUpdateStatus(Resource):
code=HTTPStatus.OK, model=submission_model, description="Submission"
)
@API.response(HTTPStatus.BAD_REQUEST, "Bad Request")
@API.response(HTTPStatus.FORBIDDEN, "Insufficient permissions")
@cross_origin(origins=allowedorigins())
@auth.require
def patch(submission_id):
"""Edit a submission status."""
# Get the submission to check if it's a GIS document
submission = SubmissionModel.find_by_id(submission_id)
if not submission:
abort(HTTPStatus.NOT_FOUND, "Submission not found")

# Check if this is a GIS document and validate GIS role
if (submission.submitted_document and
submission.submitted_document.folder == 'geospatial'):
# For GIS documents, user must have GIS extended edit role or full access
if not has_gis_extended_edit_role():
abort(HTTPStatus.FORBIDDEN, "GIS extended edit role required for GIS documents")

edit_submission_data = UpdateSubmissionStatusSchema().load(API.payload)
status = edit_submission_data.get("status")
edited_submission = SubmissionService.update_submission_status(submission_id, status)
Expand Down
29 changes: 29 additions & 0 deletions submit-api/src/submit_api/services/authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,32 @@ def require_team_lead_access():
if jwt.contains_role([EpicSubmitRole.FULL_ACCESS.value, EpicSubmitRole.W_EXTENDED_EDIT.value]):
return
abort(HTTPStatus.FORBIDDEN)


def has_gis_extended_edit_role(user_roles=None):
"""Check if user has GIS extended edit role.

Args:
user_roles: List of user roles to check. If None, checks current user's roles.

Returns:
bool: True if user has GIS extended edit role or full access
"""
if user_roles is None:
# Check current user's roles via JWT
return jwt.contains_role([EpicSubmitRole.GIS_EXTENDED_EDIT.value, EpicSubmitRole.FULL_ACCESS.value])

# Check provided roles list
return EpicSubmitRole.GIS_EXTENDED_EDIT.value in user_roles or EpicSubmitRole.FULL_ACCESS.value in user_roles


def require_gis_extended_edit_access():
"""Check if current user has GIS extended edit permission.

Raises:
HTTPStatus.FORBIDDEN: If user doesn't have GIS extended edit permission
"""
# Check for full_access or gis_extended_edit role
if jwt.contains_role([EpicSubmitRole.FULL_ACCESS.value, EpicSubmitRole.GIS_EXTENDED_EDIT.value]):
return
abort(HTTPStatus.FORBIDDEN)
26 changes: 26 additions & 0 deletions submit-api/src/submit_api/services/user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@ def get_or_provision_by_auth_guid(cls, _guid, token_info=None):
# Check if user has staff roles in their token
if cls._has_staff_roles(token_info):
user = cls._auto_provision_staff_user(_guid, token_info)
elif user and user.type == UserType.STAFF and not user.staff_user and token_info:
# User exists as STAFF but staff_user record is missing - create it
if cls._has_staff_roles(token_info):
from submit_api.models import db

email = token_info.get('email')
given_name = token_info.get('given_name')
family_name = token_info.get('family_name')

staff_user_data = {
'first_name': given_name,
'last_name': family_name,
'work_email_address': email,
'user_id': user.id
}
StaffUser.create_staff_user(staff_user_data)

# Refresh the user object to load the staff_user relationship
db.session.refresh(user)

current_app.logger.info(f"Created missing staff_user record for: {email} (guid: {_guid})")

if not user:
raise ResourceNotFoundError(f"User with auth guid {_guid} not found")
Expand All @@ -47,6 +68,8 @@ def _has_staff_roles(cls, token_info):
@classmethod
def _auto_provision_staff_user(cls, _guid, token_info):
"""Auto-provision a staff user from token info."""
from submit_api.models import db

email = token_info.get('email')
given_name = token_info.get('given_name')
family_name = token_info.get('family_name')
Expand All @@ -67,6 +90,9 @@ def _auto_provision_staff_user(cls, _guid, token_info):
}
StaffUser.create_staff_user(staff_user_data)

# Refresh the user object to load the staff_user relationship
db.session.refresh(user)

current_app.logger.info(f"Auto-provisioned staff user: {email} (guid: {_guid})")

return user
Expand Down
3 changes: 3 additions & 0 deletions submit-api/src/submit_api/utils/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ class EpicSubmitRole(Enum):
W_EDIT = "w_edit"
W_CREATE = "w_create"
W_EXTENDED_EDIT = "w_extended_edit"

# GIS role
GIS_EXTENDED_EDIT = "gis_extended_edit"
Loading
Loading