"""Schdeule Attachment handlers.""" from abacus_common_logic.constants.error import ERROR_MISSING_JSON_BODY from abacus_common_logic.views.item_view import ItemView from flask import Blueprint, abort, request from marshmallow import ValidationError from owsrequest import flask_request from owsresponse import response from owsresponse.adaptors.flask import flaskify from abacus_schedule.constants import error from abacus_schedule.logic import schedule_attachment as logic from abacus_schedule.models.schedule_attachment import ScheduleAttachment from abacus_schedule.schemas.schedule_attachment import ScheduleAttachmentDetailSchema from abacus_schedule.utils import authorization from abacus_schedule.utils.format_error import validation_error from abacus_schedule.utils.request import validate_pagination_params schedule_attachment_api = Blueprint('schedule_attachment_api', __name__) class ScheduleAttachmentItemView(ItemView): """Handler for GET/DELETE/PUT schedule_attachment.""" model_class = ScheduleAttachment object_detail_schema = ScheduleAttachmentDetailSchema() def get(self, object_id, **kwargs): """Find schedule attachment by its id or return an error.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_FORBIDDEN, message=error.ERROR_MESSAGE_FORBIDDEN_USER, status=403, ) ) obj = self.model_class.get_by_id_or_error(object_id, 404) body = self.object_detail_schema.dump(obj) return flaskify(response.Response(message=body, status=200)) def delete(self, object_id): """Handle schedule_attachment soft deletion.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_FORBIDDEN, message=error.ERROR_MESSAGE_FORBIDDEN_USER, status=403, ) ) obj = self.model_class.get_by_id_or_error(object_id) return flaskify(logic.soft_delete_schedule_attachment(obj)) @schedule_attachment_api.route( '/schedule//schedule-attachments/', methods=['GET'] ) def get_schedule_attachments_by_schedule_id(schedule_id: int): """Get a list of schedule_attachments by schedule id.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: # Currently, we're treating this resource type as all-or-nothing # permissions-wise, so resource id doesn't matter. Ideally, would be # able to tie back to contract -> account and authorize on that. authorized = authorization.pdp_authorize_resource( resource_id=schedule_id, resource_type='abacus_schedule', ) if not authorized: return flaskify( response.create_error_response( code=error.ERROR_CODE_FORBIDDEN, message=error.ERROR_MESSAGE_FORBIDDEN_USER, status=403, ) ) try: request_params = validate_pagination_params(**request.args) return flaskify( logic.get_schedule_attachments_by_schedule_id(schedule_id, **request_params) ) except ValidationError as e: return flaskify(validation_error(e.messages[0])) schedule_attachment_api.add_url_rule( '/schedule-attachment//', methods=['GET', 'DELETE'], view_func=ScheduleAttachmentItemView.as_view('schedule_attachment'), ) @schedule_attachment_api.route( '/schedule///schedule-attachments/', methods=['PUT'], ) def bulk_update_schedule_attachments(schedule_id: int, target_type: str): """Endpoint to add/delete schedule attachments for a specified schedule_id and target_type. Args: schedule_id (int): id of the schedule target_type (str): target type of schedule_attachment """ access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_FORBIDDEN, message=error.ERROR_MESSAGE_FORBIDDEN_USER, status=403, ) ) put_body = request.get_json() if not put_body: abort( code=400, description=ERROR_MISSING_JSON_BODY, ) return flaskify( logic.bulk_update_schedule_attachments(schedule_id, target_type, put_body) )