aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2022-05-04 12:08:32 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2022-05-04 12:08:32 -0400
commitf3b48d0678fe23c8ff4aed8bfdc370b3b8197b9f (patch)
treebf547f3a6838bb5079c2e5d22fc58310f4c1155d
parentd26549e79053413bf82c510c6fb192289fe7448a (diff)
downloadlevitating-f3b48d0678fe23c8ff4aed8bfdc370b3b8197b9f.tar.gz
levitating-f3b48d0678fe23c8ff4aed8bfdc370b3b8197b9f.zip
Auth levels are now read from a special config file. Both display and operations are now checked for auth level.
-rw-r--r--captain/config.f9092
-rw-r--r--captain/db.f903
-rw-r--r--captain/example/levitating-permissions.conf14
-rw-r--r--captain/example/levitating.conf27
-rw-r--r--captain/http.f901
-rw-r--r--captain/levitating-captain.prj3
-rw-r--r--captain/requtils.f9054
-rw-r--r--captain/response.f9012
-rw-r--r--captain/web.f90226
9 files changed, 321 insertions, 111 deletions
diff --git a/captain/config.f90 b/captain/config.f90
index 509c489..2d67adf 100644
--- a/captain/config.f90
+++ b/captain/config.f90
@@ -71,6 +71,24 @@ implicit none
character(*), parameter::SALT_VARIABLE = "security-salt"
character(1024)::app_salt
+ character(*), parameter::PERMISSIONS_FILE_VARIABLE = "permissions_file"
+ character(1024)::perm_filename
+
+ integer, parameter::MAX_PERMISSIONS = 16
+
+ type::permissions
+ character(len=40), dimension(MAX_PERMISSIONS)::k
+ integer, dimension(MAX_PERMISSIONS)::v
+
+ contains
+
+ procedure :: load => load_permissions
+ procedure :: get => get_permission
+
+ end type permissions
+
+ type(permissions)::global_permissions
+
contains
subroutine get_variable(str, v)
@@ -162,6 +180,9 @@ contains
else if(cvariable == SALT_VARIABLE) then
app_salt = trim(cvalue)
+
+ else if(cvariable == PERMISSIONS_FILE_VARIABLE) then
+ perm_filename = trim(cvalue)
end if
@@ -174,6 +195,7 @@ contains
integer::unit_number, istatus
character(1024)::line, cvalue
character(64)::cvariable
+ integer::i
open(newunit=unit_number, file=trim(filename), status='old', &
action="read", iostat=istatus)
@@ -195,6 +217,16 @@ contains
close(unit_number)
+ if(len_trim(perm_filename) > 0) then
+ if(perm_filename(1:1) /= "/") then
+ i = index(filename, "/", back=.true.)
+ if(i > 1) then
+ perm_filename = filename(1:i)//trim(perm_filename)
+ end if
+ end if
+ call global_permissions%load(perm_filename)
+ end if
+
end subroutine load_configuration
subroutine template_filepath(x, res)
@@ -207,5 +239,65 @@ contains
call combine_paths(template_directory, x, res)
end subroutine template_filepath
+
+ subroutine load_permissions(self, filename)
+ implicit none
+
+ class(permissions), intent(out)::self
+ character(*), intent(in)::filename
+
+ integer::unit_number, istatus
+ character(1024)::line, cvalue
+ character(64)::cvariable
+ integer::i
+
+ self%k = " "
+
+ open(newunit=unit_number, file=trim(filename), status='old', &
+ action="read", iostat=istatus)
+
+ i = 1
+
+ read(unit_number, '(A)', iostat=istatus) line
+ do while(istatus == 0 .and. i <= MAX_PERMISSIONS)
+
+ if(len_trim(line) > 0 .and. line(1:1) /= '#') then
+
+ call get_variable(line, cvariable)
+ call get_value(line, cvalue)
+
+ self%k(i) = cvariable
+ read(cvalue, *, iostat=istatus) self%v(i)
+
+ i = i + 1
+ end if
+
+ read(unit_number, '(A)', iostat=istatus) line
+ end do
+
+ close(unit_number)
+
+ end subroutine load_permissions
+
+ pure function get_permission(self, key)
+ use auth_levels, only: AUTH_ADMIN_USER
+ implicit none
+
+ class(permissions), intent(in)::self
+ character(len=*), intent(in)::key
+ integer::get_permission
+
+ integer::i
+
+ get_permission = AUTH_ADMIN_USER
+
+ do i = 1, MAX_PERMISSIONS
+ if(trim(self%k(i)) == trim(key)) then
+ get_permission = self%v(i)
+ exit
+ end if
+ end do
+
+ end function get_permission
end module config
diff --git a/captain/db.f90 b/captain/db.f90
index 97c397a..44bc473 100644
--- a/captain/db.f90
+++ b/captain/db.f90
@@ -1541,6 +1541,7 @@ contains
end function get_user_auth_db
function get_session_auth_db(session)
+ use auth_levels, only: AUTH_NONE
implicit none
character(len=*), intent(in)::session
@@ -1548,7 +1549,7 @@ contains
type(sqlite3_stmt)::stmt
- get_session_auth_db = -1
+ get_session_auth_db = AUTH_NONE
if(stmt%prepare(db, "SELECT level FROM session_auth WHERE session=? LIMIT 1") == SQLITE_OK) then
if(stmt%bind_text(1, session) == SQLITE_OK) then
diff --git a/captain/example/levitating-permissions.conf b/captain/example/levitating-permissions.conf
new file mode 100644
index 0000000..a487872
--- /dev/null
+++ b/captain/example/levitating-permissions.conf
@@ -0,0 +1,14 @@
+
+access-releases = 0
+access-logs = 0
+
+add-players = 10
+modify-players = 5
+
+scan-instructions = 10
+launch-job = 5
+assign-instructions = 5
+view-raw-instructions = 0
+
+add-groups = 5
+modify-groups = 5
diff --git a/captain/example/levitating.conf b/captain/example/levitating.conf
index c1c22e1..06b89ed 100644
--- a/captain/example/levitating.conf
+++ b/captain/example/levitating.conf
@@ -1,9 +1,9 @@
-template-directory = /home/jeff/Workspace/levitating/captain/templates
+template-directory = /home/jeff/workspace/levitating/captain/templates
-database = /home/jeff/Workspace/levitating/captain/example/store.db
+database = /home/jeff/workspace/levitating/captain/example/store.db
-log-filename = /home/jeff/Workspace/levitating/captain/example/log/levitating.log
+log-filename = /home/jeff/workspace/levitating/captain/example/log/levitating.log
log-level = 10
@@ -11,22 +11,25 @@ project = misc-build
description = A builder for stuff
-public-cert = /home/jeff/Workspace/levitating/captain/example/pub.crt
+public-cert = /home/jeff/workspace/levitating/captain/example/pub.crt
-private-cert = /home/jeff/Workspace/levitating/captain/example/priv.key
+private-cert = /home/jeff/workspace/levitating/captain/example/priv.key
-uploads-directory = /home/jeff/Workspace/levitating/captain/example/uploads
+uploads-directory = /home/jeff/workspace/levitating/captain/example/uploads
-results-directory = /home/jeff/Workspace/levitating/captain/example/results
+results-directory = /home/jeff/workspace/levitating/captain/example/results
-static-directory = /home/jeff/Workspace/levitating/captain/example/static
+static-directory = /home/jeff/workspace/levitating/captain/example/static
-script-directory = /home/jeff/Workspace/levitating/captain/sql
+script-directory = /home/jeff/workspace/levitating/captain/sql
-instructions-directory = /home/jeff/Workspace/levitating/captain/example/instructions
+instructions-directory = /home/jeff/workspace/levitating/captain/example/instructions
-release-directory = /home/jeff/Workspace/levitating/captain/example/releases
+release-directory = /home/jeff/workspace/levitating/captain/example/releases
temp-directory = /tmp/levitating
-security-salt = aBcD____ \ No newline at end of file
+security-salt = aBcD____
+
+# Must be absolute path or relative to this file
+permissions_file = levitating-permissions.conf
diff --git a/captain/http.f90 b/captain/http.f90
index 9e2fca5..8449ba2 100644
--- a/captain/http.f90
+++ b/captain/http.f90
@@ -27,6 +27,7 @@ implicit none
integer, parameter::HTTP_CODE_NOTFOUND = 404
integer, parameter::HTTP_CODE_FAILURE = 500
integer, parameter::HTTP_CODE_REDIRECT = 302
+ integer, parameter::HTTP_CODE_UNAUTHORIZED = 401
contains
diff --git a/captain/levitating-captain.prj b/captain/levitating-captain.prj
index 4af03c5..f949fb2 100644
--- a/captain/levitating-captain.prj
+++ b/captain/levitating-captain.prj
@@ -49,6 +49,9 @@
}],
"Name":"+example",
"Files":[{
+ "filename":"example/levitating-permissions.conf",
+ "enabled":"1"
+ },{
"filename":"example/levitating.conf",
"enabled":"1"
}]
diff --git a/captain/requtils.f90 b/captain/requtils.f90
index 41eacc6..620170a 100644
--- a/captain/requtils.f90
+++ b/captain/requtils.f90
@@ -71,6 +71,24 @@ contains
end if
end function notfound_code
+
+ pure function notpermitted_code(req)
+ use http, only: HTTP_UNAUTHORIZED => HTTP_CODE_UNAUTHORIZED
+ use server_response, only: request, GEMINI_UNAUTHORIZED => GEMINI_CODE_BAD_REQUEST
+ implicit none
+
+ class(request), intent(in)::req
+ integer::notpermitted_code
+
+ if(req%protocol == 'gemini') then
+ ! You might think we'd use Gemini certificates, but fuck certificates...
+ ! Just fail with a bad request.
+ notpermitted_code = GEMINI_UNAUTHORIZED
+ else
+ notpermitted_code = HTTP_UNAUTHORIZED
+ end if
+
+ end function notpermitted_code
subroutine basic_mimetype(actual_filename, mimetype)
use utilities, only: get_one_line_output_shell_command
@@ -239,19 +257,30 @@ contains
call req%path_component(1, category)
call req%path_starting_with_component(2, filename)
- resp%body_filename => get_special_full_filename(trim(category), trim(filename))
-
- inquire(file=resp%body_filename, exist=exists)
- if(.not. exists) then
-
- resp%code = notfound_code(req)
- call write_log("File did not exist: "//resp%body_filename, LOG_NORMAL)
+ if((req%auth_level < global_permissions%get("view-raw-instructions") .and. trim(category) == "instructions") .or. &
+ (req%auth_level < global_permissions%get("access-releases") .and. trim(category) == "releases") .or. &
+ (req%auth_level < global_permissions%get("access-logs") .and. trim(category) == "results")) &
+ then
+ resp%code = notpermitted_code(req)
+
else
+
+ resp%body_filename => get_special_full_filename(trim(category), trim(filename))
+
+ inquire(file=resp%body_filename, exist=exists)
+ if(.not. exists) then
- resp%code = success_code(req)
- call basic_mimetype(resp%body_filename, resp%body_mimetype)
+ resp%code = notfound_code(req)
+ call write_log("File did not exist: "//resp%body_filename, LOG_NORMAL)
+
+ else
+
+ resp%code = success_code(req)
+ call basic_mimetype(resp%body_filename, resp%body_mimetype)
+ end if
+
end if
end function request_static
@@ -652,6 +681,7 @@ contains
use captain_db
use server_response
use remote_launch
+ use config, only: global_permissions
implicit none
type(request), intent(in)::req
@@ -668,15 +698,15 @@ contains
command = req%query_string(1:i-1)
argument = req%query_string(i+1:len_trim(req%query_string))
- if(trim(command) == "launch") then
+ if(trim(command) == "launch" .and. req%auth_level >= global_permissions%get("launch-job")) then
call launch_instructions_on_player(instruction_name, argument)
- else if(trim(command) == "assign") then
+ else if(trim(command) == "assign" .and. req%auth_level >= global_permissions%get("assign-instructions")) then
i = get_instruction_id(trim(instruction_name))
j = get_player_id(trim(argument))
call add_player_for_instruction(i, j)
- else if(trim(command) == "remove") then
+ else if(trim(command) == "remove" .and. req%auth_level >= global_permissions%get("assign-instructions")) then
i = get_instruction_id(trim(instruction_name))
j = get_player_id(trim(argument))
call remove_player_for_instruction(i, j)
diff --git a/captain/response.f90 b/captain/response.f90
index 34c537c..e172cc1 100644
--- a/captain/response.f90
+++ b/captain/response.f90
@@ -73,6 +73,8 @@ implicit none
character(len=:), pointer::token => null()
character(len=4)::method = "GET"
+ integer::auth_level
+
type(query)::q
type(cookies)::c
@@ -111,6 +113,8 @@ contains
subroutine request_init(self, str, server_explicit, protocol_explicit, method, cookiestring)
use logging
use utilities, only: toupper
+ use captain_db, only: get_session_auth_db
+ use auth_levels, only: AUTH_NONE
implicit none
class(request) :: self
@@ -222,6 +226,14 @@ contains
if(.not.associated(self%token) .and. associated(self%c%get_value("token"))) then
self%token => self%c%get_value("token")
end if
+ else
+ call self%c%init()
+ end if
+
+ if(associated(self%token)) then
+ self%auth_level = get_session_auth_db(self%token)
+ else
+ self%auth_level = AUTH_NONE
end if
end subroutine request_init
diff --git a/captain/web.f90 b/captain/web.f90
index b990c1a..9d8fc3c 100644
--- a/captain/web.f90
+++ b/captain/web.f90
@@ -70,6 +70,17 @@ contains
end function request_is_authenticated
+ subroutine echo_error_stdout(error_code)
+ implicit none
+
+ integer, intent(in)::error_code
+
+ Print *, "<html><head><title>Falling...</title></head><body><p>An Error Occurred:"
+ Print *, error_code
+ Print *, "</p></body></html>"
+
+ end subroutine echo_error_stdout
+
subroutine handle_basic_template_components(req, page)
use server_response
use page_template
@@ -151,6 +162,7 @@ contains
use captain_db
use server_response
use request_utils, only: get_player_status_utf8, render_jobs_links, generate_simple_pager
+ use config, only: global_permissions
implicit none
type(request)::req
@@ -219,14 +231,17 @@ contains
res = "<h2>"//trim(instruction_name)//"</h2>"
- one_link => html_link(trim(instruction_name)//".json", &
- "View Raw")
- res = trim(res)//nl//"<p><em>"//one_link//"</em></p>"
- deallocate(one_link)
+ if(req%auth_level >= global_permissions%get("view-raw-instructions")) then
+ one_link => html_link(trim(instruction_name)//".json", &
+ "View Raw")
+ res = trim(res)//nl//"<p><em>"//one_link//"</em></p>"
+ deallocate(one_link)
+ end if
if(n_players == 0) then
res = trim(res)//nl//"<p>No players currently can run these instructions</p>"
- else
+
+ else if(req%auth_level >= global_permissions%get("launch-job")) then
res = trim(res)//nl//"<h3>Launch Now</h3>"//nl//"<ul>"
do i = 1, n_players
@@ -260,39 +275,41 @@ contains
end if
- all_players => get_player_names()
- if(associated(all_players)) then
- res = trim(res)//nl//"<h3>Assign</h3>"//nl//"<p>Assign a player to these instructions</p>"//nl//"<ul>"
- 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//"<h3>Assign</h3>"//nl//"<p>Assign a player to these instructions</p>"//nl//"<ul>"
+ 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
-
- one_link => html_link(req%page//"?assign="//trim(all_players(i)), &
- trim(all_players(i)))
-
- res = trim(res)//nl//"<li>"//one_link//"</li>"
- deallocate(one_link)
- end do
- res = trim(res)//nl//"</ul>"
- deallocate(all_players)
- end if
-
- if(n_players > 0) then
- res = trim(res)//nl//"<h3>Remove</h3>"//nl//"<p>Remove a player from these instructions</p>"//nl//"<ul>"
- do i = 1, n_players
- call get_player_name(players(i), player_name)
-
- one_link => html_link(req%page//"?remove="//trim(player_name), &
- trim(player_name))
-
- res = trim(res)//nl//"<li>"//one_link//"</li>"
- deallocate(one_link)
- end do
- res = trim(res)//nl//"</ul>"
+
+ one_link => html_link(req%page//"?assign="//trim(all_players(i)), &
+ trim(all_players(i)))
+
+ res = trim(res)//nl//"<li>"//one_link//"</li>"
+ deallocate(one_link)
+ end do
+ res = trim(res)//nl//"</ul>"
+ deallocate(all_players)
+ end if
+
+ if(n_players > 0) then
+ res = trim(res)//nl//"<h3>Remove</h3>"//nl//"<p>Remove a player from these instructions</p>"//nl//"<ul>"
+ do i = 1, n_players
+ call get_player_name(players(i), player_name)
+
+ one_link => html_link(req%page//"?remove="//trim(player_name), &
+ trim(player_name))
+
+ res = trim(res)//nl//"<li>"//one_link//"</li>"
+ deallocate(one_link)
+ end do
+ res = trim(res)//nl//"</ul>"
+ end if
end if
end function generate_one_instuction_html
@@ -300,6 +317,7 @@ contains
function generate_instructions_html(req) result(res)
use captain_db
use server_response, only:request
+ use config, only: global_permissions
implicit none
type(request)::req
@@ -340,17 +358,20 @@ contains
end if
- res = trim(res)//new_line(' ')//"<h2>Management</h2>"
-
- scanlink => html_link(req%page//"?scan", "Scan for instructions now")
- res = trim(res)//new_line(' ')//"<p>"//scanlink//"</p>"
- deallocate(scanlink)
+ if(req%auth_level >= global_permissions%get("scan-instructions")) then
+ res = trim(res)//new_line(' ')//"<h2>Management</h2>"
+
+ scanlink => html_link(req%page//"?scan", "Scan for instructions now")
+ res = trim(res)//new_line(' ')//"<p>"//scanlink//"</p>"
+ deallocate(scanlink)
+ end if
end function generate_instructions_html
function generate_groups_html(req) result(res)
use captain_db
use server_response, only:request
+ use config, only: global_permissions
implicit none
type(request)::req
@@ -389,11 +410,13 @@ contains
end if
- res = trim(res)//new_line(' ')//"<h2>Management</h2>"
-
- res = trim(res)//new_line(' ')// &
- '<form action="groups/add.html" method="POST"><label for="name">Name:</label>'// &
- '<input name="name" id="name" /><input type="submit" value="Add"/></form>'
+ if(req%auth_level >= global_permissions%get("add-groups")) then
+ res = trim(res)//new_line(' ')//"<h2>Management</h2>"
+
+ res = trim(res)//new_line(' ')// &
+ '<form action="groups/add.html" method="POST"><label for="name">Name:</label>'// &
+ '<input name="name" id="name" /><input type="submit" value="Add"/></form>'
+ end if
end function generate_groups_html
@@ -404,6 +427,7 @@ contains
use query_utilities
use logging
use remote_launch, only: launch_group
+ use config, only: global_permissions
implicit none
type(request)::req
@@ -437,7 +461,7 @@ contains
call q%init(req%query_string)
qreq => q%get_value("add")
- if(associated(qreq)) then
+ if(associated(qreq) .and. req%auth_level >= global_permissions%get("add-groups")) then
call write_log("ADD: "//trim(qreq))
@@ -454,7 +478,7 @@ contains
qreq => q%get_value("delete")
- if(associated(qreq)) then
+ if(associated(qreq) .and. req%auth_level >= global_permissions%get("modify-groups")) then
i = index(qreq, ',')
player_name = qreq(i+1:len(qreq))
@@ -465,12 +489,12 @@ contains
call remove_entry_from_group_db(id, i, j)
- else if(trim(req%query_string) == "launch") then
+ else if(trim(req%query_string) == "launch" .and. req%auth_level >= global_permissions%get("launch-job")) then
call launch_group(id)
write(launch_msg, '(I4, 1X, A13)') get_group_entries_count_db(id), "jobs launched"
- else if(trim(req%query_string) == "destroy") then
+ else if(trim(req%query_string) == "destroy" .and. req%auth_level >= global_permissions%get("modify-groups")) then
call delete_group_db(id)
@@ -511,15 +535,22 @@ contains
one_link => html_link("../instructions/"//trim(instruction_name)//".html", trim(instruction_name))
play_link => html_link("../players/"//trim(player_name)//".html", trim(player_name))
- delete_link => html_link(trim(group_name)//".html?delete="// &
- trim(instruction_name)//","//trim(player_name), &
- "<em>Remove</em>")
- res = trim(res)//new_line(' ')//"<li>"//one_link//" on "//play_link//" - "//delete_link//"</li>"
+
+ res = trim(res)//new_line(' ')//"<li>"//one_link//" on "//play_link
+
+ if(req%auth_level >= global_permissions%get("modify-groups")) then
+ delete_link => html_link(trim(group_name)//".html?delete="// &
+ trim(instruction_name)//","//trim(player_name), &
+ "<em>Remove</em>")
+ res = trim(res)//" - "//delete_link
+ deallocate(delete_link)
+ end if
+
+ res = trim(res)//"</li>"
deallocate(one_link)
deallocate(play_link)
- deallocate(delete_link)
end do
@@ -527,7 +558,7 @@ contains
end if
- if(n_instructions_total > 0) then
+ if(n_instructions_total > 0 .and. req%auth_level >= global_permissions%get("modify-groups")) then
res = trim(res)//new_line(' ')//"<h3>Add Instructions</h3>"
@@ -559,16 +590,22 @@ contains
end if
end if
- res = trim(res)//new_line(' ')//'<h3>Destroy This Group</h3>'//new_line(' ')// &
- '<p><a href="'//req%page//'?destroy">&#x1f4a3; Destroy</a></p>'//new_line(' ')// &
- '<p><em>This operation will not destroy any instructions</em></p>'
+ if(req%auth_level >= global_permissions%get("modify-groups")) then
+ res = trim(res)//new_line(' ')//'<h3>Destroy This Group</h3>'//new_line(' ')// &
+ '<p><a href="'//req%page//'?destroy">&#x1f4a3; Destroy</a></p>'//new_line(' ')// &
+ '<p><em>This operation will not destroy any instructions</em></p>'
+ end if
end function generate_one_group_html
- function generate_players_html() result(res)
+ function generate_players_html(req) result(res)
use captain_db
use request_utils, only: get_status_utf8
+ 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), dimension(:), pointer::players
@@ -619,9 +656,11 @@ contains
deallocate(players)
end if
- res = trim(res)//new_line(' ')//"<h2>Management</h2>"// &
- new_line(' ')//'<form action="players/add.html" method="POST"><label for="name">Name:</label>'// &
- '<input name="name" id="name" /><input type="submit" value="Add"/></form>'
+ if(req%auth_level >= global_permissions%get("add-players")) then
+ res = trim(res)//new_line(' ')//"<h2>Management</h2>"// &
+ new_line(' ')//'<form action="players/add.html" method="POST"><label for="name">Name:</label>'// &
+ '<input name="name" id="name" /><input type="submit" value="Add"/></form>'
+ end if
end function generate_players_html
@@ -629,6 +668,7 @@ contains
use captain_db
use server_response
use request_utils
+ use config, only: global_permissions
implicit none
type(request), intent(in)::req
@@ -683,24 +723,26 @@ contains
res = trim(res)//"<p>None Yet</p>"
end if
- ! Token assignment
- res = trim(res)//new_line(' ')//"<h3>Security</h3>"//new_line(' ')//"<p>"
-
- if(player_has_token_db(trim(player_name))) then
- res = trim(res)//"Player currently has a token assigned."
- else
- res = trim(res)//"<em>Player is insecure! Please assign a token!</em>"
+ if(req%auth_level >= global_permissions%get("modify-players")) then
+ ! Token assignment
+ res = trim(res)//new_line(' ')//"<h3>Security</h3>"//new_line(' ')//"<p>"
+
+ if(player_has_token_db(trim(player_name))) then
+ res = trim(res)//"Player currently has a token assigned."
+ else
+ res = trim(res)//"<em>Player is insecure! Please assign a token!</em>"
+ end if
+
+ res = trim(res)//"</p>"
+
+ res = trim(res)//new_line(' ')// &
+ '<form action="assign_token.html" method="POST">'//new_line(' ')// &
+ '<label for="token">Token:</label>'// &
+ '<input name="token" id="token" />'//new_line(' ')// &
+ '<input type="hidden" name="player" id="player" value="'//trim(player_name)//'"/>'//new_line(' ')// &
+ '<input type="submit" value="Set"/></form>'
end if
- res = trim(res)//"</p>"
-
- res = trim(res)//new_line(' ')// &
- '<form action="assign_token.html" method="POST">'//new_line(' ')// &
- '<label for="token">Token:</label>'// &
- '<input name="token" id="token" />'//new_line(' ')// &
- '<input type="hidden" name="player" id="player" value="'//trim(player_name)//'"/>'//new_line(' ')// &
- '<input type="submit" value="Set"/></form>'
-
end function generate_one_player_html
function generate_one_job_html(req) result(res)
@@ -827,6 +869,17 @@ contains
res => null()
+ ! Auth check
+ if(req%auth_level < global_permissions%get("access-releases")) then
+ allocate(character(len=64)::res)
+ if(req%auth_level == 0) then
+ res = "Login required."
+ else
+ res = "Unacceptable permissions"
+ end if
+ return
+ end if
+
! Easy safety check - no relative paths
if(index(local_path, '..') > 0) then
allocate(character(len=64)::res)
@@ -1045,7 +1098,7 @@ contains
else if(trim(req%location) == "/players.html") then
call page%assign('title', 'Players')
- contents => generate_players_html()
+ contents => generate_players_html(req)
call page%assign('contents', contents)
else if(req%location(1:9) == '/players/') then
@@ -1155,7 +1208,7 @@ contains
use captain_db, only: add_player_db, add_group_db, update_player_token_db, create_user_session_db, &
validate_user_db
use page_template
- use config, only: template_filepath
+ use config, only: template_filepath, global_permissions
use logging
use server_response, only:request, response
use http, only: HTTP_CODE_FAILURE, HTTP_CODE_SUCCESS
@@ -1187,12 +1240,12 @@ contains
call req%path_component(2, second)
! Add a player
- if(trim(second) == "add.html") then
+ if(trim(second) == "add.html" .and. req%auth_level >= global_permissions%get("add-players")) then
call add_player_db(posted%get_value("name"))
call page%assign('destination', 'players.html')
- else if(trim(second) == "assign_token.html") then
+ else if(trim(second) == "assign_token.html" .and. req%auth_level >= global_permissions%get("modify-players")) then
call update_player_token_db(posted%get_value("player"), posted%get_value("token"))
call page%assign('destination', "players/"//posted%get_value("player")//".html")
@@ -1204,7 +1257,7 @@ contains
call req%path_component(2, second)
! Add a group
- if(trim(second) == "add.html") then
+ if(trim(second) == "add.html" .and. req%auth_level >= global_permissions%get("add-groups")) then
call add_group_db(posted%get_value("name"))
call page%assign('destination', 'groups.html')
@@ -1293,8 +1346,9 @@ contains
end if
call echo_file_stdout(resp%body_filename)
- case(HTTP_CODE_FAILURE)
+ case default
call write_log("Failure reported for location: "//trim(req%location), LOG_NORMAL)
+ call echo_error_stdout(resp%code)
! Need some more...
end select