From bf3c23ae1f6f75112d86bfac1883a0f356fbb57c Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Sun, 14 Feb 2021 23:33:22 -0700 Subject: [PATCH] cgi: include timed token in project reg/edit forms Include a timed token in both the project registration and project edit forms that has a validity from the time the form is created and lasting for $Girocco::Config::project_edit_timeout seconds. As of yet, nothing interesting happens when a form is submitted but the timed token is no longer valid. Signed-off-by: Kyle J. McKay --- Girocco/Util.pm | 41 ++++++++++++++++++++++++++++++++++++++++- cgi/editproj.cgi | 4 +++- cgi/regproj.cgi | 4 +++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Girocco/Util.pm b/Girocco/Util.pm index 62240ec..0cf475a 100644 --- a/Girocco/Util.pm +++ b/Girocco/Util.pm @@ -6,6 +6,7 @@ use warnings; use Girocco::Config; use Girocco::ConfigUtil; +use Girocco::TimedToken; use Time::Local; use Scalar::Util qw(looks_like_number); use Encode (); @@ -26,7 +27,8 @@ BEGIN { clean_email_multi read_HEAD_symref read_config_file read_config_file_hash is_git_dir git_bool util_path is_shellish read_HEAD_ref git_add_config to_json - json_bool from_json ref_indicator get_token_key); + json_bool from_json ref_indicator get_token_key + get_timed_token get_token_field); } BEGIN {require "Girocco/extra/capture_command.pl"} @@ -1420,4 +1422,41 @@ sub get_token_key { return $1; } +# just like create_timed_token except that +# the first argument is a category name instead of +# the actual HMAC "secret" +# $_[0] -> category name to pass to get_token_key +# $_[1] -> optional instance info to include in "text" +# $_[2] -> duration of validity in seconds (5..2147483647) +# $_[3] -> optional time stamp (secs since unix Epoch) +# if not provided, current time is used +# Returns a base64_url token (no trailing '='s) that is +# valid starting at $_[3] and expires $_[2] seconds after $_[3]. +# Unless get_token_key fails in which case it returns undef. +# +sub get_timed_token { + my ($catg, $extra, $duration, $start) = @_; + my $tk = get_token_key($catg); + defined($tk) && $tk ne "" or return undef; + return create_timed_token($tk, $extra, $duration, $start); +} + +# return a hidden "token" field if the token ($_[0]) +# can be read, otherwise the empty string "". +# $_[0] -> the token category (passed to get_token_key) +# $_[1] -> the optional instance info (passed to create_timed_token) +# $_[2] -> the duration of validity (passed to create_timed_token) +# $_[3] -> optional name of field (defaults to "token") +# returns a "hidden" XHTML input element or the empty string if +# get_timed_token fails. The token starting time will be the +# current time. +# +sub get_token_field { + my ($catg, $extra, $duration, $name) = @_; + defined($name) && $name ne "" or $name = "token"; + my $tt = get_timed_token($catg, $extra, $duration); + defined($tt) && $tt ne "" or return ""; + return ""; +} + 1; diff --git a/cgi/editproj.cgi b/cgi/editproj.cgi index 2080ace..e94c956 100755 --- a/cgi/editproj.cgi +++ b/cgi/editproj.cgi @@ -130,9 +130,11 @@ EOT my $button_label = $proj->{clone_failed} ? 'Restart Mirroring' : 'Update'; my $showstatusopt = $proj->{mirror} && !$proj->{clone_failed} && !$proj->{clone_in_progress}; my $statuschecked = $proj->{statusupdates} ? 'checked="checked"' : ''; +my $tokauth = get_token_field("projedit", $h{name}, $Girocco::Config::project_edit_timeout); +$tokauth and $tokauth = "\n".$tokauth; print < +
$tokauth
Project name:'; } $name = html_esc($name); +my $tokauth = get_token_field("projedit", "", $Girocco::Config::project_edit_timeout); +$tokauth and $tokauth = "\n".$tokauth; print < +$tokauth -- 2.11.4.GIT
Project name: $forkentry.git