Skip to content

Commit

Permalink
Item2321: add OPTIONS verb to lightly docco useage
Browse files Browse the repository at this point in the history
          try to tease out the submission validation code, so that I can access it from js when using ajax.
         spearate out content-type encoding and charset

git-svn-id: http://svn.foswiki.org/trunk@10271 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
SvenDowideit authored and SvenDowideit committed Dec 12, 2010
1 parent 0bf1bfd commit 1cea653
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 9 deletions.
51 changes: 46 additions & 5 deletions core/lib/Foswiki/Validation.pm
Expand Up @@ -75,6 +75,32 @@ the form tag.

sub addValidationKey {
my ( $cgis, $context, $strikeone ) = @_;

my $nonce = generateValidationKey($cgis, $context, $strikeone);

# Don't use CGI::hidden; it will inherit the URL param value of
# validation key and override our value :-(
return "<input type='hidden' name='validation_key' value='?$nonce' />";
}

=begin TML
---++ StaticMethod generateValidationKey( $cgis, $context, $strikeone ) -> $nonce
Generate a new validation key. The key will time out after
{Validation}{ValidForTime}.
* =$cgis= - a CGI::Session
* =$context= - the context for the key, usually the URL of the target
page plus the time. This should be unique for each rendered page.
* =$strikeone= - if set, expect the nonce to be combined with the
session secret before it is posted back.
The validation key wcan then be used in a HTML form, or headers for RestPlugin API etc.
TODO: should this be assable from Foswiki::Func so that RestHandlers can use it too?
=cut

sub generateValidationKey {
my ( $cgis, $context, $strikeone ) = @_;
my $actions = $cgis->param('VALID_ACTIONS') || {};
my $nonce = Digest::MD5::md5_hex( $context, $cgis->id() );
my $action = $nonce;
Expand All @@ -96,12 +122,12 @@ sub addValidationKey {
. $timeout . "\n"
if TRACE && !defined $actions->{$action};
$actions->{$action} = $timeout;


#used to store the actions in case there are more than one form..
$cgis->param( 'VALID_ACTIONS', $actions );

# Don't use CGI::hidden; it will inherit the URL param value of
# validation key and override our value :-(
return "<input type='hidden' name='validation_key' value='?$nonce' />";

return $nonce;
}

=begin TML
Expand Down Expand Up @@ -166,10 +192,25 @@ Return false if not.

sub isValidNonce {
my ( $cgis, $nonce ) = @_;
my $actions = $cgis->param('VALID_ACTIONS');
return isValidNonceHash($actions, $nonce)
}


=begin TML
---++ StaticMethod isValidNonceHash( $actions, $key ) -> $boolean
Check that the given validation key is valid for the session.
Return false if not.
=cut

sub isValidNonceHash {
my ( $actions, $nonce ) = @_;
return 1 if ( $Foswiki::cfg{Validation}{Method} eq 'none' );
return 0 unless defined $nonce;
$nonce =~ s/^\?// if ( $Foswiki::cfg{Validation}{Method} ne 'strikeone' );
my $actions = $cgis->param('VALID_ACTIONS');
return 0 unless ref($actions) eq 'HASH';
print STDERR "V: CHECK $nonce -> " . ( $actions->{$nonce} ? 1 : 0 ) . "\n"
if TRACE;
Expand Down
17 changes: 13 additions & 4 deletions core/pub/System/JavascriptFiles/strikeone_src.js
Expand Up @@ -200,21 +200,30 @@ var md5 = {

var StrikeOne = {
/**
* Action on form submission (this is the only function called
* outside this file)
* Action on form submission (called outside this file for HTML Form submits)
*/
submit: function(form) {
// Read the cookie to get the secret
var secret = StrikeOne.readCookie('FOSWIKISTRIKEONE');
//console.debug("Submit "+form.name);
var input = form.validation_key;
if (input && input.value && input.value.charAt(0) == '?') {
input.value = calculateNewKey(input);
}
},
/**
* calculate a new key response to validate the SUBMIIT (called outside this file for non HTML Form submits)
*/
calculateNewKey: function(input) {
// Read the cookie to get the secret
var secret = StrikeOne.readCookie('FOSWIKISTRIKEONE');
if (input && input.charAt(0) == '?') {
// combine the validation key with the secret in a way
// that can't easily be reverse-engineered, but can be
// duplicated on the server (which also knows the secret)
var key = input.value.substring(1);
var key = input.substring(1);
var newkey = md5.hex(key + secret);
input.value = newkey;
return newkey;
//console.debug("Revise "+key+" + "+secret+" -> "+newkey);
}
},
Expand Down

0 comments on commit 1cea653

Please sign in to comment.