aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2022-05-09 10:13:32 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2022-05-09 10:13:32 -0400
commit1e7a526f569ebce3687c43a907b45fc2e44fab23 (patch)
tree36d6745cbdc104de10659c779d9d130c8a597149
parentef6e25936d7aaa6fd4650d9ed27bd8b1c6d5c21d (diff)
downloadlevitating-1e7a526f569ebce3687c43a907b45fc2e44fab23.tar.gz
levitating-1e7a526f569ebce3687c43a907b45fc2e44fab23.zip
Authorization now checked via Gemini. Finally implemented a single player page in Gemini.
-rw-r--r--captain/external.f90239
1 files changed, 183 insertions, 56 deletions
diff --git a/captain/external.f90 b/captain/external.f90
index 4c700ae..467f1ca 100644
--- a/captain/external.f90
+++ b/captain/external.f90
@@ -191,6 +191,10 @@ contains
allocate(character(len=64)::res)
res = "None Found"
return
+ else if(req%auth_level < global_permissions%get("access-releases")) then
+ allocate(character(len=64)::res)
+ res = "Not Authorized"
+ return
end if
directories => get_directories_in_directory(local_path)
@@ -258,10 +262,83 @@ contains
end function generate_releases_gemini
+ function generate_one_player_gemini(req) result(res)
+ use captain_db
+ use request_utils, only: get_player_status_utf8, build_link
+ use server_response, only: request
+ use config, only: global_permissions
+ implicit none
+
+ type(request), intent(in)::req
+ character(len=:), pointer::res
+ character(len=PLAYER_NAME_LENGTH)::player_name, instruction_name
+ integer::i, pid, istat, n
+ integer, dimension(8)::values
+ character(len=64)::dateconvert
+ character(len=:), pointer::one_link
+ integer, dimension(:), pointer::instruction_ids
+
+ call req%last_component(player_name)
+ i = index(player_name, '.gmi')
+ player_name = player_name(1:i-1)
+ pid = get_player_id(trim(player_name))
+
+ n = get_instructions_count(player=pid)
+ allocate(character(len=(2*n*PLAYER_NAME_LENGTH + 1024)) :: res)
+
+ res = "Status:"
+ if(is_player_online(pid)) then
+ res = trim(res)//" Online"
+ else
+ res = trim(res)//" Offline"
+ end if
+
+ ! Last checkin
+ call get_last_checkin_time(pid, values)
+ write(dateconvert, '(I4,A1,I0.2,A1,I0.2,3X,I2,A1,I0.2,A1,I0.2)') &
+ values(1), '-', values(2), '-', values(3), &
+ values(5), ':', values(6), ':', values(7)
+
+ res = trim(res)//new_line(' ')//'Last Checkin: '//trim(dateconvert)
+
+ ! List of instructions
+ res = trim(res)//new_line(' ')//new_line(' ')//"### Instructions for "//trim(player_name)
+ instruction_ids => get_instruction_ids(player=pid)
+ if(associated(instruction_ids)) then
+ do i = 1, n
+ call get_instruction_name(instruction_ids(i), instruction_name)
+ one_link => build_link("../instructions/"//trim(instruction_name)//".gmi", trim(instruction_name),&
+ .true., req%token)
+ res = trim(res)//new_line(' ')//one_link
+ deallocate(one_link)
+ end do
+ deallocate(instruction_ids)
+ else
+ res = trim(res)//new_line(' ')//"None Yet"
+ end if
+
+ if(req%auth_level >= global_permissions%get("modify-players")) then
+ ! Token assignment
+ res = trim(res)//new_line(' ')//new_line(' ')//"### Security"
+
+ if(player_has_token_db(trim(player_name))) then
+ res = trim(res)//new_line(' ')//"Player currently has a token assigned."
+ else
+ res = trim(res)//new_line(' ')//"Player is insecure! Please assign a token!"
+ end if
+
+ one_link => build_link(trim(player_name)//"/assign_token.gmi", "Assign Token", .true., req%token)
+
+ res = trim(res)//new_line(' ')//one_link
+ end if
+
+ end function generate_one_player_gemini
+
function generate_players_gemini(req) result(res)
use captain_db
use request_utils, only: get_player_status_utf8, build_link
use server_response, only: request
+ use config, only: global_permissions
implicit none
type(request), intent(in)::req
@@ -309,12 +386,15 @@ contains
deallocate(players)
end if
- player_link => build_link("/players/add.gmi", "Add Player", .true., req%token)
- res = trim(res)//new_line(res(1:1))//new_line(res(1:1))//"## Management"// &
- new_line(res(1:1))//player_link
+ if(req%auth_level >= global_permissions%get("add-players")) then
+ player_link => build_link("/players/add.gmi", "Add Player", .true., req%token)
+
+ res = trim(res)//new_line(res(1:1))//new_line(res(1:1))//"## Management"// &
+ new_line(res(1:1))//player_link
- deallocate(player_link)
+ deallocate(player_link)
+ end if
end function generate_players_gemini
@@ -322,6 +402,7 @@ contains
use captain_db
use server_response
use request_utils, only: get_player_status_utf8, render_jobs_links, build_link
+ use config, only: global_permissions
implicit none
type(request)::req
@@ -376,16 +457,18 @@ contains
i = index(req%location, ".gmi", back=.true.)
- raw_link => build_link(req%location(1:i-1)//".json", "View Raw", .true., req%token)
- res = trim(res)//nl//raw_link
- deallocate(raw_link)
+ if(req%auth_level >= global_permissions%get("view-raw-instructions")) then
+ raw_link => build_link(req%location(1:i-1)//".json", "View Raw", .true., req%token)
+ res = trim(res)//nl//raw_link
+ deallocate(raw_link)
+ end if
if(n_players == 0) then
res = trim(res)//nl//nl//"No players currently can run these instructions"
- else
+ else if(req%auth_level >= global_permissions%get("launch-job")) then
res = trim(res)//nl//nl//"### Launch Now"
do i = 1, n_players
- call get_player_name(players(i), player_name)
+ call get_player_name(players(i), player_name)
player_status = get_player_status_utf8(players(i))
launch_link => build_link(trim(req%location)//"?launch="//trim(player_name), &
@@ -395,6 +478,19 @@ contains
res = trim(res)//nl//launch_link
deallocate(launch_link)
end do
+ else
+ res = trim(res)//nl//nl//"### Assigned Players"
+ do i = 1, n_players
+ call get_player_name(players(i), player_name)
+ player_status = get_player_status_utf8(players(i))
+
+ launch_link => build_link("/players/"//trim(player_name)//".gmi", &
+ trim(player_status)//" "//trim(player_name), &
+ .true., req%token)
+
+ res = trim(res)//nl//launch_link
+ deallocate(launch_link)
+ end do
end if
res = trim(res)//nl//nl//"### Jobs"
@@ -405,39 +501,41 @@ contains
deallocate(job_link_text)
end if
- all_players => get_player_names()
- if(associated(all_players)) then
- res = trim(res)//nl//nl//"### Assign"//nl//"Assign a player to these instructions"
- do i = 1, size(all_players)
- if(n_players > 0) then
- j = get_player_id(all_players(i))
- if(any(j == players)) then
- cycle
+ if(req%auth_level >= global_permissions%get("assign-instructions")) then
+ all_players => get_player_names()
+ if(associated(all_players)) then
+ res = trim(res)//nl//nl//"### Assign"//nl//"Assign a player to these instructions"
+ do i = 1, size(all_players)
+ if(n_players > 0) then
+ j = get_player_id(all_players(i))
+ if(any(j == players)) then
+ cycle
+ end if
end if
- end if
-
- assign_link => build_link(trim(req%location)//"?assign="//trim(all_players(i)), &
- trim(all_players(i)), .true., req%token)
-
- res = trim(res)//nl//assign_link
-
- deallocate(assign_link)
- end do
- deallocate(all_players)
- end if
-
- if(n_players > 0) then
- res = trim(res)//nl//nl//"### Remove"//nl//"Remove a player from these instructions"
- do i = 1, n_players
- call get_player_name(players(i), player_name)
-
- assign_link => build_link(trim(req%location)//"?remove="//trim(player_name), &
- trim(player_name), .true., req%token)
-
- res = trim(res)//nl//assign_link
-
- deallocate(assign_link)
- end do
+
+ assign_link => build_link(trim(req%location)//"?assign="//trim(all_players(i)), &
+ trim(all_players(i)), .true., req%token)
+
+ res = trim(res)//nl//assign_link
+
+ deallocate(assign_link)
+ end do
+ deallocate(all_players)
+ end if
+
+ if(n_players > 0) then
+ res = trim(res)//nl//nl//"### Remove"//nl//"Remove a player from these instructions"
+ do i = 1, n_players
+ call get_player_name(players(i), player_name)
+
+ assign_link => build_link(trim(req%location)//"?remove="//trim(player_name), &
+ trim(player_name), .true., req%token)
+
+ res = trim(res)//nl//assign_link
+
+ deallocate(assign_link)
+ end do
+ end if
end if
end function generate_one_instuction_gemini
@@ -446,6 +544,7 @@ contains
use captain_db
use server_response, only: request
use request_utils, only: build_link
+ use config, only: global_permissions
implicit none
class(request), intent(in)::req
@@ -492,13 +591,15 @@ contains
end if
- instruction_link => build_link("/instructions/scan.gmi", "Scan for Instructions", &
- .true., req%token)
+ if(req%auth_level >= global_permissions%get("scan-instructions")) then
+ instruction_link => build_link("/instructions/scan.gmi", "Scan for Instructions", &
+ .true., req%token)
- res = trim(res)//new_line(res(1:1))//new_line(res(1:1))//"## Management"// &
- new_line(res(1:1))//instruction_link
-
- deallocate(instruction_link)
+ res = trim(res)//new_line(res(1:1))//new_line(res(1:1))//"## Management"// &
+ new_line(res(1:1))//instruction_link
+
+ deallocate(instruction_link)
+ end if
end function generate_instructions_gemini
@@ -559,14 +660,16 @@ contains
class(request), intent(in)::req
logical::is_input_required_request
- character(64)::first
+ character(64)::first, last
call req%path_component(1, first)
+ call req%last_component(last)
is_input_required_request = .false.
if(req%location == "/players/add.gmi" .or. &
req%location == "/login.gmi" .or. &
- trim(first) == "login") &
+ trim(first) == "login" .or. &
+ trim(last) == "assign_token.gmi") &
then
is_input_required_request = .true.
end if
@@ -576,24 +679,28 @@ contains
function external_input_required_gemini(req) result(resp)
use server_response
use gemini_codes
+ use config, only: global_permissions
implicit none
class(request), intent(in)::req
type(response)::resp
- character(64)::first
+ character(64)::first, last
call req%path_component(1, first)
+ call req%last_component(last)
resp%code = GEMINI_CODE_INPUT
- if(req%location == "/players/add.gmi") then
+ if(req%location == "/players/add.gmi" .and. req%auth_level >= global_permissions%get("add-players")) then
call resp%set_message("Enter name of new player to add")
else if(req%location == "/login.gmi") then
call resp%set_message("Enter username:")
else if(trim(first) == "login") then
call resp%set_message("Enter password:")
resp%code = GEMINI_CODE_INPUT_PW
+ else if(trim(last) == "assign_token.gmi") then
+ call resp%set_message("Enter token for player:")
end if
end function external_input_required_gemini
@@ -605,16 +712,18 @@ contains
use m_uuid, only: UUID_LENGTH
use logging
use gemini_codes
+ use config, only: global_permissions
implicit none
class(request), intent(in)::req
type(response)::resp
- character(64)::first, second
+ character(PLAYER_NAME_LENGTH)::first, second, last
character(len=:), pointer::session
call req%path_component(1, first)
+ call req%last_component(last)
- if(req%location == "/players/add.gmi") then
+ if(req%location == "/players/add.gmi" .and. req%auth_level >= global_permissions%get("add-players")) then
call add_player_db(req%query_string)
resp%code = GEMINI_CODE_REDIRECT
call resp%set_gemini_session_url("/players.gmi", req%token)
@@ -652,6 +761,13 @@ contains
call resp%set_url("/loginfailed.gmi")
end if
+ else if(trim(last) == "assign_token.gmi" .and. req%auth_level >= global_permissions%get("modify-players")) then
+
+ call req%path_component(2, second)
+ call update_player_token_db(trim(second), req%query_string)
+ resp%code = GEMINI_CODE_REDIRECT
+ call resp%set_url("../"//trim(second)//".gmi")
+
end if
end function external_input_request_gemini
@@ -707,6 +823,7 @@ contains
use server_response
use logging
use gemini_codes
+ use config, only: global_permissions
implicit none
class(request), intent(inout)::req
@@ -714,7 +831,7 @@ contains
resp%code = GEMINI_CODE_REDIRECT
- if(req%location == "/instructions/scan.gmi") then
+ if(req%location == "/instructions/scan.gmi" .and. req%auth_level >= global_permissions%get("scan-instructions")) then
call scan_instructions_for_db()
call resp%set_url("/instructions.gmi")
@@ -738,6 +855,7 @@ contains
use request_utils, only: get_job_page_title
use utilities, only: build_date
use gemini_codes
+ use captain_db, only: PLAYER_NAME_LENGTH
implicit none
class(request), intent(in)::req
@@ -747,6 +865,8 @@ contains
character(len=:), pointer::contents
character(64)::first, template_name
character(128)::job_page_title
+ character(PLAYER_NAME_LENGTH)::second
+ integer::i
! Open the base template
if(trim(req%location) == "/" .or. trim(req%location) == "/index.gmi") then
@@ -785,8 +905,15 @@ contains
contents => generate_players_gemini(req)
call page%assign('contents', contents)
- else if(req%location(1:9) == '/players/') then
-
+ else if(trim(first) == 'players') then
+ call req%path_component(2, second)
+ i = index(second, ".gmi")
+ if(i > 2) then
+ call page%assign('title', second(1:i-1))
+ end if
+ contents => generate_one_player_gemini(req)
+ call page%assign('contents', contents)
+
else if(trim(req%location) == "/about.gmi") then
call page%assign('title', 'About')