diff options
author | Jeffrey Armstrong <jeff@approximatrix.com> | 2022-04-11 16:28:43 -0400 |
---|---|---|
committer | Jeffrey Armstrong <jeff@approximatrix.com> | 2022-04-11 16:28:43 -0400 |
commit | 4392961dd95582b91e173f9ae40ac510b9afe7d4 (patch) | |
tree | 253e6d2b7ea70b21074575af94d194ed4ec48571 /captain/api.f90 | |
parent | 26a936137f67843cb773bc9b9e8c360d5abff65f (diff) | |
download | levitating-4392961dd95582b91e173f9ae40ac510b9afe7d4.tar.gz levitating-4392961dd95582b91e173f9ae40ac510b9afe7d4.zip |
Added token validation to all api calls, esp. checkins. Changed status reports to use better query structure. Added query derived types to the request derived types directly. Requires testing of actual builds.
Diffstat (limited to 'captain/api.f90')
-rw-r--r-- | captain/api.f90 | 127 |
1 files changed, 73 insertions, 54 deletions
diff --git a/captain/api.f90 b/captain/api.f90 index 665ff8d..c05b0ba 100644 --- a/captain/api.f90 +++ b/captain/api.f90 @@ -59,20 +59,24 @@ contains class(request)::req integer::job_i, task_i - if(associated(req%query_string)) then + character(len=:), pointer::status + + status => req%q%get_value("status") + + if(associated(status)) then job_i = req%path_component_int(5) task_i = req%path_component_int(7) - call write_log("Task Update Is "//trim(req%query_string), LOG_DEBUG) - if(req%query_string == "starting") then + call write_log("Task Update Is "//trim(status), LOG_DEBUG) + if(status == "starting") then call write_log("Inserting task", LOG_DEBUG) call insert_task(job_i, task_i) call update_job_status(job_i, JOB_STATUS_WORKING) - else if(req%query_string == "inprogress") then + else if(status == "inprogress") then call update_task_status(job_i, task_i, JOB_STATUS_WORKING) call update_job_status(job_i, JOB_STATUS_WORKING) - else if(req%query_string == "complete") then + else if(status == "complete") then call update_task_status(job_i, task_i, JOB_STATUS_SUCCESS) - else if(req%query_string == "failed") then + else if(status == "failed") then call update_task_status(job_i, task_i, JOB_STATUS_FAILURE) end if end if @@ -84,7 +88,7 @@ contains use captain_db use special_filenames use logging - use query_utilities + use security, only: validate_query_token implicit none type(request), intent(in)::req @@ -94,73 +98,88 @@ contains integer::job_i, player_i, qs_platform_index character(len=:), pointer::checkin_work_json - type(query)::q ! Complete - "/api/player/{name}/job/{jobid}/complete" ! Failed - "/api/player/{name}/job/{jobid}/failed" ! Task - "/api/player/{name}/job/{jobid}/task/{task num}" if(trim(req%component(2)) == "player" .and. trim(req%component(4)) == "job") then - job_i = req%path_component_int(5) - call write_log("Job "//trim(req%component(5))//" update arrived", LOG_INFO) - write(player, *) job_i - - if(.not. is_final_job_status(job_i)) then - if(trim(req%component(6)) == "complete") then - call update_job_status(job_i, JOB_STATUS_SUCCESS) - else if(trim(req%component(6)) == "failure") then - call update_job_status(job_i, JOB_STATUS_FAILURE) + if(validate_query_token(req%q%get_value("token"), req%component(3))) then + + job_i = req%path_component_int(5) + call write_log("Job "//trim(req%component(5))//" update arrived", LOG_INFO) + + write(player, *) job_i + + if(.not. is_final_job_status(job_i)) then + if(trim(req%component(6)) == "complete") then + call update_job_status(job_i, JOB_STATUS_SUCCESS) + else if(trim(req%component(6)) == "failure") then + call update_job_status(job_i, JOB_STATUS_FAILURE) + end if end if - end if + + if(trim(req%component(6)) == "task") then + call write_log("Task update encountered", LOG_INFO) + call handle_task_request(req) + end if + + resp%code = GEMINI_CODE_SUCCESS + call resp%set_body_contents(RESPONSE_JSON_OKAY) + resp%body_mimetype = "text/plain" + + else - if(trim(req%component(6)) == "task") then - call write_log("Task update encountered", LOG_INFO) - call handle_task_request(req) + resp%code = GEMINI_CODE_BAD_REQUEST + end if - - resp%code = GEMINI_CODE_SUCCESS - call resp%set_body_contents(RESPONSE_JSON_OKAY) - resp%body_mimetype = "text/plain" ! Checkin - /api/player/{name}/checkin.json else if(trim(req%component(2)) == "player" .and. trim(req%component(4)) == "checkin.json") then - ! Check for pending jobs - call req%path_component(3, player) - player_i = get_player_id(player) - - ! If we have a checkin, but the worker should have a job in progress, mark - ! the jobs as failed. - call mark_working_jobs_as_failed(player_i) + + if(validate_query_token(req%q%get_value("token"), req%component(3))) then - ! Acknowledge the checkin in the database - if(associated(req%query_string)) then - call q%init(req%query_string) - if(associated(q%get_value("platform"))) then - call acknowledge_checkin(player_i, q%get_value("platform")) + ! Check for pending jobs + call req%path_component(3, player) + player_i = get_player_id(player) + + ! If we have a checkin, but the worker should have a job in progress, mark + ! the jobs as failed. + call mark_working_jobs_as_failed(player_i) + + ! Acknowledge the checkin in the database + if(associated(req%query_string)) then + if(associated(req%q%get_value("platform"))) then + call acknowledge_checkin(player_i, req%q%get_value("platform")) + else + call acknowledge_checkin(player_i) + end if else call acknowledge_checkin(player_i) end if - call q%destroy() - else - call acknowledge_checkin(player_i) - end if - - job_i = get_pending_job_for_player(player_i) - if(job_i < 0) then - resp%code = GEMINI_CODE_SUCCESS - call resp%set_body_contents(RESPONSE_JSON_IDLE) - else - checkin_work_json => build_job_available_json(job_i) - if(associated(checkin_work_json)) then + + job_i = get_pending_job_for_player(player_i) + if(job_i < 0) then resp%code = GEMINI_CODE_SUCCESS - call write_log("Sending: "//trim(checkin_work_json), LOG_DEBUG) - call resp%set_body_contents(trim(checkin_work_json), "text/gemini") - deallocate(checkin_work_json) + call resp%set_body_contents(RESPONSE_JSON_IDLE) else - resp%code = GEMINI_CODE_PERMFAIL + checkin_work_json => build_job_available_json(job_i) + if(associated(checkin_work_json)) then + resp%code = GEMINI_CODE_SUCCESS + call write_log("Sending: "//trim(checkin_work_json), LOG_DEBUG) + call resp%set_body_contents(trim(checkin_work_json), "text/gemini") + deallocate(checkin_work_json) + else + resp%code = GEMINI_CODE_PERMFAIL + end if end if - end if + else + + resp%code = GEMINI_CODE_BAD_REQUEST + + end if + ! Instruction - /api/instructions/{name} else if(trim(req%component(2)) == "instruction") then |