aboutsummaryrefslogtreecommitdiff
path: root/captain/api.f90
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2022-04-11 16:28:43 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2022-04-11 16:28:43 -0400
commit4392961dd95582b91e173f9ae40ac510b9afe7d4 (patch)
tree253e6d2b7ea70b21074575af94d194ed4ec48571 /captain/api.f90
parent26a936137f67843cb773bc9b9e8c360d5abff65f (diff)
downloadlevitating-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.f90127
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