Index: test/unit/RegisterTests.pm =================================================================== --- test/unit/RegisterTests.pm (Revision 7408) +++ test/unit/RegisterTests.pm (Arbeitskopie) @@ -42,7 +42,6 @@ my $peopleWeb = "TemporaryRegisterTestsPeopleWeb"; my $systemWeb = "TemporaryRegisterTestsSystemWeb"; -# SMELL: the sent mails are never checked in the tests my @mails; $TWiki::User::password = "foo"; @@ -126,19 +125,12 @@ # fixture sub registerAccount { my $this = shift; - $this->test_registerVerifyOk(); + my $data = $this->test_registerVerifyOk(); - my $query = new CGI({ - 'code' => [ - $testUserWikiName.".foo" - ], - 'action' => [ - 'verify' - ] - }); + my $query = _buildNextStepsCGI('verify',$testUserWikiName.".foo"); try { - TWiki::UI::Register::finish( $session, $TWiki::cfg{RegistrationApprovals} ); + TWiki::UI::Register::finish( $session, $data, 'verify'); } catch TWiki::OopsException with { my $e = shift; $this->assert_str_equals("attention", $e->{template}); @@ -191,38 +183,11 @@ #Assumes the verification code is foo sub test_registerVerifyOk { my $this = shift; + $TWiki::cfg{Register}{NeedVerification} = 1; - my $query = new CGI ({ - 'TopicName' => [ - 'TWikiRegistration' - ], - 'Twk1Email' => [ - $testUserEmail - ], - 'Twk1WikiName' => [ - $testUserWikiName - ], - 'Twk1Name' => [ - 'Test User' - ], - 'Twk0Comment' => [ - '' - ], - 'Twk1LoginName' => [ - $testUserLoginName - ], - 'Twk1FirstName' => [ - 'Test' - ], - 'Twk1LastName' => [ - 'User' - ], - 'action' => [ - 'register' - ] - }); + $TWiki::cfg{Register}{NeedApproval} = 0; - $query->path_info( "/$peopleWeb/TWikiRegistration" ); + my $query = _buildRegistrationCGI(); $session = new TWiki( $TWiki::cfg{DefaultUserName}, $query); $session->{net}->setMailHandler(\&sentMail); @@ -243,24 +208,17 @@ }; my $code = shift || $testUserWikiName.".foo"; - $query = new CGI ({ - 'code' => [ - $code - ], - 'action' => [ - 'verify' - ] - }); + $query = _buildNextStepsCGI ('verify',$code); $query->path_info( "/$peopleWeb/TWikiRegistration" ); $session = new TWiki( $TWiki::cfg{DefaultUserName},$query); $session->{net}->setMailHandler(\&sentMail); + my $data; try { - TWiki::UI::Register::verifyEmailAddress($session, $TWiki::cfg{RegistrationApprovals}); + $data = TWiki::UI::Register::verifyEmailAddress($session); } catch TWiki::AccessControlException with { my $e = shift; $this->assert(0, $e->stringify); - } catch TWiki::OopsException with { my $e = shift; $this->assert( 0, $e->stringify ); @@ -279,41 +237,230 @@ } $this->assert($done); @mails = (); + return $data; } + +#Register a user and then approve it +sub test_registerApproveOk { + my $this = shift; + + $TWiki::cfg{Register}{NeedVerification} = 0; + $TWiki::cfg{Register}{NeedApproval} = 1; + + my $query = _buildRegistrationCGI(); + + $session = new TWiki( $TWiki::cfg{DefaultUserName}, $query); + $session->{net}->setMailHandler(\&sentMail); + + # fire off TWikiRegistration, expecting a registerapprove oops + try { + TWiki::UI::Register::register_cgi($session); + } catch TWiki::OopsException with { + my $e = shift; + $this->assert_str_equals("attention", $e->{template},$e->stringify()); + $this->assert_str_equals("registerapprove", $e->{def}); + $this->assert_matches(qr/$testUserEmail/, $e->stringify()); + } catch TWiki::AccessControlException with { + my $e = shift; + $this->assert(0, $e->stringify); + } catch Error::Simple with { + $this->assert(0, shift->stringify()); + } otherwise { + $this->assert(0, "expected an oops redirect"); + }; + + # annihilate the mail which should have been sent to the administrator + $this->assert_equals(1, scalar(@mails)); + my $done = ''; + my $code = ''; + foreach my $mail ( @mails ) { + if( ($code) = $mail =~ /Your approval code is '(.*?)'/m ) { + $this->assert(!$done, $done."\n---------\n".$mail); + $done = $mail; + } else { + $this->assert(0, $mail); + } + } + $this->assert($done); + @mails = (); + + # finally, do approval verification with a new query. + $code ||= $testUserWikiName.".foo"; + $query = _buildNextStepsCGI('approve',$code); + $query->path_info( "/$peopleWeb/TWikiRegistration" ); + $session = new TWiki( $TWiki::cfg{DefaultUserName},$query); + $session->{net}->setMailHandler(\&sentMail); + + # check for the appropriate request to approve + try { + TWiki::UI::Register::register_cgi($session); + } catch TWiki::AccessControlException with { + my $e = shift; + $this->assert(0, $e->stringify); + + } catch TWiki::OopsException with { + my $e = shift; + $this->assert_str_equals("attention", $e->{template},$e->stringify()); + $this->assert_str_equals("thanksadmin", $e->{def}); + $this->assert_matches(qr/$testUserEmail/, $e->stringify()); + } catch Error::Simple with { + $this->assert(0, shift->stringify()); + }; + + # kill the mails which should have been sent to user and administrator + $this->assert_equals(2, scalar(@mails)); + $done = ''; + foreach my $mail ( @mails ) { + if( $mail =~ /^Subject:.*Registration for/m ) { + if( $mail =~ /^To: .*\b$testUserEmail\b/m ) { + $this->assert(!$done, $done."\n---------\n".$mail); + $done = $mail; + } else { + $this->assert_matches(qr/To: %WIKIWEBMASTER/, $mail ); + } + } else { + $this->assert(0, $mail); + } + } + $this->assert($done); + @mails = (); + +} + +#Register a user, and then verify it, and then approve it +#Assumes the verification code is foo +sub test_registerVerifyApproveOk { + my $this = shift; + + $TWiki::cfg{Register}{NeedVerification} = 1; + $TWiki::cfg{Register}{NeedApproval} = 1; + + my $query = _buildRegistrationCGI(); + + $session = new TWiki( $TWiki::cfg{DefaultUserName}, $query); + $session->{net}->setMailHandler(\&sentMail); + + # fire off TWikiRegistration + try { + TWiki::UI::Register::register_cgi($session); + } catch TWiki::OopsException with { + my $e = shift; + $this->assert_str_equals("attention", $e->{template},$e->stringify()); + $this->assert_str_equals("confirm", $e->{def}); + $this->assert_matches(qr/$testUserEmail/, $e->stringify()); + } catch TWiki::AccessControlException with { + my $e = shift; + $this->assert(0, $e->stringify); + } catch Error::Simple with { + $this->assert(0, shift->stringify()); + } otherwise { + $this->assert(0, "expected an oops redirect"); + }; + + # annihilate the mail which should have been sent to the user + # asking for verification + $this->assert_equals(1, scalar(@mails)); + my $done = ''; + foreach my $mail ( @mails ) { + if( $mail =~ /Your verification code is /m ) { + $this->assert(!$done, $done."\n---------\n".$mail); + $done = $mail; + } else { + $this->assert(0, $mail); + } + } + $this->assert($done); + @mails = (); + + # do verification with a new query. + my $code = shift || $testUserWikiName.".foo"; + $query = _buildNextStepsCGI('verify',$code); + $query->path_info( "/$peopleWeb/TWikiRegistration" ); + $session = new TWiki( $TWiki::cfg{DefaultUserName},$query); + $session->{net}->setMailHandler(\&sentMail); + + # check for the appropriate response: oops-inform about approval + try { + TWiki::UI::Register::register_cgi($session); + } catch TWiki::AccessControlException with { + my $e = shift; + $this->assert(0, $e->stringify); + + } catch TWiki::OopsException with { + my $e = shift; + $this->assert_str_equals("attention", $e->{template},$e->stringify()); + $this->assert_str_equals("registerapprove", $e->{def}); + $this->assert_matches(qr/$testUserEmail/, $e->stringify()); + } catch Error::Simple with { + $this->assert(0, shift->stringify()); + }; + + # annihilate the mail which should have been sent to the administrator + $this->assert_equals(1, scalar(@mails)); + $done = ''; + foreach my $mail ( @mails ) { + if( ($code) = $mail =~ /Your approval code is '(.*?)'/m ) { + $this->assert(!$done, $done."\n---------\n".$mail); + $done = $mail; + } else { + $this->assert(0, $mail); + } + } + $this->assert($done); + @mails = (); + + # finally, do approval verification with a new query. + $code ||= $testUserWikiName.".foo"; + $query = _buildNextStepsCGI('approve',$code); + $query->path_info( "/$peopleWeb/TWikiRegistration" ); + $session = new TWiki( $TWiki::cfg{DefaultUserName},$query); + $session->{net}->setMailHandler(\&sentMail); + + # check for the appropriate request to approve + try { + TWiki::UI::Register::register_cgi($session); + } catch TWiki::AccessControlException with { + my $e = shift; + $this->assert(0, $e->stringify); + + } catch TWiki::OopsException with { + my $e = shift; + $this->assert_str_equals("attention", $e->{template},$e->stringify()); + $this->assert_str_equals("thanksadmin", $e->{def}); + $this->assert_matches(qr/$testUserEmail/, $e->stringify()); + } catch Error::Simple with { + $this->assert(0, shift->stringify()); + }; + + # kill the mails which should have been sent to user and administrator + $this->assert_equals(2, scalar(@mails)); + $done = ''; + foreach my $mail ( @mails ) { + if( $mail =~ /^Subject:.*Registration for/m ) { + if( $mail =~ /^To: .*\b$testUserEmail\b/m ) { + $this->assert(!$done, $done."\n---------\n".$mail); + $done = $mail; + } else { + $this->assert_matches(qr/To: %WIKIWEBMASTER/, $mail ); + } + } else { + $this->assert(0, $mail); + } + } + $this->assert($done); + @mails = (); + +} + #Register a user, then give a bad verification code. It should barf. sub test_registerBadVerify { my $this = shift; - my $query = new CGI ({ - 'TopicName' => [ - 'TWikiRegistration' - ], - 'Twk1Email' => [ - $testUserEmail - ], - 'Twk1WikiName' => [ - $testUserWikiName - ], - 'Twk1Name' => [ - 'Test User' - ], - 'Twk0Comment' => [ - '' - ], - 'Twk1LoginName' => [ - $testUserLoginName - ], - 'Twk1FirstName' => [ - 'Test' - ], - 'Twk1LastName' => [ - 'User' - ], - 'action' => [ - 'register' - ] - }); - $query->path_info( "/$peopleWeb/TWikiRegistration" ); + + $TWiki::cfg{Register}{NeedVerification} = 1; + $TWiki::cfg{Register}{NeedApproval} = 0; + + my $query = _buildRegistrationCGI(); $session = new TWiki( $TWiki::cfg{DefaultUserName}, $query); $session->{net}->setMailHandler(\&sentMail); try { @@ -334,14 +481,7 @@ }; my $code = $testUserWikiName.'.bad.foo'; - $query = new CGI ({ - 'code' => [ - $code - ], - 'action' => [ - 'verify' - ] - }); + $query = _buildNextStepsCGI('verify',$code); $query->path_info( "/$peopleWeb/TWikiRegistration" ); $session = new TWiki( $TWiki::cfg{DefaultUserName}, $query); $session->{net}->setMailHandler(\&sentMail); @@ -374,38 +514,12 @@ # (SUPER's tear_down will take care for re-installing %TWiki::cfg) sub test_registerNoVerifyOk { my $this = shift; + $TWiki::cfg{Register}{NeedVerification} = 0; - my $query = new CGI ({ - 'TopicName' => [ - 'TWikiRegistration' - ], - 'Twk1Email' => [ - $testUserEmail - ], - 'Twk1WikiName' => [ - $testUserWikiName - ], - 'Twk1Name' => [ - 'Test User' - ], - 'Twk0Comment' => [ - '' - ], - 'Twk1LoginName' => [ - $testUserLoginName - ], - 'Twk1FirstName' => [ - 'Test' - ], - 'Twk1LastName' => [ - 'User' - ], - 'action' => [ - 'register' - ] - }); + $TWiki::cfg{Register}{NeedApproval} = 0; - $query->path_info( "/$peopleWeb/TWikiRegistration" ); + my $query = _buildRegistrationCGI(); + $session = new TWiki( $TWiki::cfg{DefaultUserName}, $query); $session->{net}->setMailHandler(\&sentMail); @@ -634,7 +748,7 @@ $regSave = { doh => "homer", - VerificationCode => $code, + Code => $code, WikiName => $name }; } @@ -642,12 +756,13 @@ =pod Create an incomplete registration, and try to finish it off. Once complete, try again - the second attempt at completion should fail. + =cut sub test_UnregisteredUser { my $this = shift; - TWiki::UI::Register::_putRegDetailsByCode($regSave, $TWiki::cfg{RegistrationApprovals}); + TWiki::UI::Register::_putRegDetailsByCode($regSave, $regSave->{Code}); my $result = TWiki::UI::Register::_getRegDetailsByCode($code, $TWiki::cfg{RegistrationApprovals}); $this->assert_equals("homer", $result->{doh} ); @@ -818,9 +933,41 @@ $this->assert_equals(0, scalar(@mails)); } +# ###################################################################### +# Utilities +# ###################################################################### +# build a full CGI object for the entry via TWikiRegistration +sub _buildRegistrationCGI { + my $query = new CGI ({ + 'TopicName' => ['TWikiRegistration'], + 'Twk1Email' => [$testUserEmail], + 'Twk1WikiName' => [$testUserWikiName], + 'Twk1Name' => ['Test User'], + 'Twk0Comment' => [''], + 'Twk1LoginName' => [$testUserLoginName], + 'Twk1FirstName' => ['Test'], + 'Twk1LastName' => ['User'], + 'action' => ['register'] + }); + $query->path_info( "/$peopleWeb/TWikiRegistration" ); + + return $query; +} + +# build a CGI object for next steps where data are supposed to be filed +sub _buildNextStepsCGI { + my ($action,$code) = @_; + my $query = new CGI({ + 'code' => [$code], + 'action' => [$action] + }); + +} + =pod call this if you want to make spaces and \ns visible + =cut sub visible { return $_[0]; Index: templates/oopsattention.tmpl =================================================================== --- templates/oopsattention.tmpl (Revision 7408) +++ templates/oopsattention.tmpl (Arbeitskopie) @@ -132,6 +132,12 @@ * %_{"You are also listed in the [_1] topic", "%MAINWEB%.%WIKIUSERSTOPIC%"}% * %_{"A confirmation e-mail has been sent to [_1]", "%PARAM1%"}% %TMPL:END% +%TMPL:DEF{"thanksadmin"}% +---+++ %_{"Approval completed"}% + * %_{"The new user's personal TWiki topic [_1] has been created.", "%TOPIC%"}%
+ * %_{"The new user is also listed in the [_1] topic.", "%MAINWEB%.%WIKIUSERSTOPIC%"}% + * %_{"A confirmation e-mail has been sent to both [_1] and [_2]", "%PARAM1%","%WIKIWEBMASTER%"}% +%TMPL:END% %TMPL:DEF{"reset_ok"}% %PARAM1% @@ -154,6 +160,12 @@ %TMPL:END% +%TMPL:DEF{"registerapprove"}% +---+++ %_{"Thank you for registering"}% + +%_{"Your registration has been submitted to [_1] at [_2]. An email will be sent to [_3] as soon as the administrator has approved your registration. Please be patient.", "%WIKIWEBMASTERNAME%", "%WIKIWEBMASTER%", "%PARAM1%"}% + +%TMPL:END% %TMPL:DEF{"no_users_to_reset"}% ---+++ %_{"Password reset failed"}% %_{"No users to reset passwords for."}% Index: lib/TWiki.cfg =================================================================== --- lib/TWiki.cfg (Revision 7408) +++ lib/TWiki.cfg (Arbeitskopie) @@ -286,6 +286,11 @@ $cfg{Register}{NeedVerification} = $TRUE; # **BOOLEAN** +# Whether registrations must be approved by the admins following +# a link sent in an email to the webmaster's email address +$cfg{Register}{NeedApproval} = $FALSE; + +# **BOOLEAN** # Map login name to Wiki name via the mapping in the topic named # in {UsersTopicName}. Set this to $FALSE for .htpasswd # authenticated sites where the user's wiki name is the Index: lib/TWiki/UI/Register.pm =================================================================== --- lib/TWiki/UI/Register.pm (Revision 7408) +++ lib/TWiki/UI/Register.pm (Arbeitskopie) @@ -52,6 +52,8 @@ my $twikiRegistrationAgent = 'TWikiRegistrationAgent'; +# full-blown registration workflow + =pod ---++ StaticMethod register_cgi( $session ) @@ -64,50 +66,52 @@ sub register_cgi { my $session = shift; - my $tempUserDir = $TWiki::cfg{RegistrationApprovals}; - # SMELL hacked name, and stores in binary format! - my $needVerification = $TWiki::cfg{Register}{NeedVerification}; - # NB. No test harness for needVerification = 0. - my $needApproval = 0; + # NB. bulkRegister invoked from ManageCgiScript. - # Register -> Verify -> Approve -> Finish + # Define the workflow: register -> verify -> approve - # NB. bulkRegister invoked from ManageCgiScript. + # The "handler"s collect CGI $data and, on the second and further steps, + # registration data saved to disk. The "nextStep"s evaluate these $data + # and prepare the replies to the web user (via oops redirects), and to the + # registering user/webmaster (via mail). + my @registrationWorkflow = ( + { action => 'register', + handler => \®ister, + nextStep => \&_requireVerification, + }, + { action => 'verify', + handler => \&verifyEmailAddress, + nextStep => \&_requireApproval, + }, + { action => 'approve', + handler => \&approveByAdmin, + nextStep => \&finish, + }, + ); - my $action = $session->{cgiQuery}->param('action') || ''; + # default to first step + my $action = $session->{cgiQuery}->param('action') || ''; + my $thisStepNumber = 0; - if ($action eq 'register') { - registerAndNext($session, $tempUserDir); - } - elsif ($action eq 'verify') { - verifyEmailAddress( $session, $tempUserDir ); - if ($needApproval) { - throw Error::Simple('Approval code has not been written!'); + # find out which step we are actually in + FIND_STEP: + for my $stepNumber (0 .. $#registrationWorkflow) { + if ($registrationWorkflow[$stepNumber]{action} eq $action) { + $thisStepNumber = $stepNumber; + last FIND_STEP; } - finish( $session, $tempUserDir); } - elsif ($action eq 'resetPassword') { - #SMELL - is this still called here, or only by passwd? - resetPassword( $session ); - } - elsif ($action eq 'approve') { - finish($session, $tempUserDir ); - } - else { - registerAndNext($session, $tempUserDir); - } - # Output of register: - # UnsavedUser, accessible by username.$verificationCode + # call the appropriate handler to get the current $data from CGI/file + my $handler = $registrationWorkflow[$thisStepNumber]{handler}; + $action = $registrationWorkflow[$thisStepNumber]{action}; + my $data = &$handler($session); - # Output of reset password: - # unaffected user, accessible by username.$verificationCode - - # Output of verify: - # UnsavedUser, accessible by username.$approvalCode (only sent to administrator) - - # Output of approve: - # RegisteredUser, all related UnsavedUsers deleted + # try next steps, the first "active" one will bail out throwing oops + for my $stepNumber ($thisStepNumber .. $#registrationWorkflow) { + my $nextStep = $registrationWorkflow[$stepNumber]{nextStep}; + &$nextStep($session,$data,$action); + } } =pod @@ -339,28 +343,6 @@ =pod ----++ StaticMethod registerAndNext($session, $tempUserDir) - -This is called when action = register or action = "" - -It calls register and either Verify or Finish. - -Hopefully we will get workflow integrated and rewrite this to be table driven - -=cut - -sub registerAndNext { - my ($session, $tempUserDir) = @_; - register( $session ); - if ($TWiki::cfg{Register}{NeedVerification}) { - _requireVerification($session, $tempUserDir); - } else { - finish($session); - } -} - -=pod - ---++ StaticMethod register($session) This is called through: TWikiRegistration -> RegisterCgiScript -> here @@ -371,37 +353,71 @@ =cut sub register { - my( $session ) = @_; + my ( $session ) = @_; my $query = $session->{cgiQuery}; my $topic = $session->{topicName}; - my $web = $session->{webName}; + my $web = $session->{webName}; - my $data = _getDataFromQuery( $query, $query->param() ); + my $data = _getDataFromQuery( $query, $query->param() ); $data->{webName} = $web; $data->{debug} = 1; _validateRegistration( $session, $data, $query, $topic ); + + return $data; } +# 1 generates an approval password +# 2 calls _putRegDetailsByCode(approval password) +# 3 sends webmaster a 'please approve' email. +# 4 redirects browser to 'registerapprove' +sub _requireApproval { + my ($session, $data) = @_; + + return unless $TWiki::cfg{Register}{NeedApproval}; + + my $query = $session->{cgiQuery}; + my $topic = $session->{topicName}; + + my $code = $data->{WikiName}.'.'.TWiki::User::randomPassword(); + _putRegDetailsByCode( $data, $code ); + + $session->writeLog( 'regapprove', $data->{webName}.'.'.$data->{WikiName}, + $data->{Email}, $data->{WikiName} ); + + my $err = _sendEmail( $session, 'registerapprove', $data ); + + if ( $err ) { + throw TWiki::OopsException( 'attention', + def => 'send_mail_error', + web => $data->{webName}, + topic => $topic, + params => $data->{Email}.' - '.$err); + } + throw TWiki::OopsException( 'attention', + def => 'registerapprove', + web => $data->{webName}, + topic => $topic, + params => $data->{Email} ); +} + # 1 generates a activation password # 2 calls _putRegDetailsByCode(activation password) # 3 sends them a 'registerconfirm' email. -# 4 redirects browser to 'regconfirm' +# 4 redirects browser to 'confirm' sub _requireVerification { - my ($session, $tmpDir) = @_; + my ($session, $data) = @_; - my $query = $session->{cgiQuery}; - my $topic = $session->{topicName}; - my $web = $session->{webName}; + return unless $TWiki::cfg{Register}{NeedVerification}; - my $data = _getDataFromQuery( $query, $query->param() ); - $data->{webName} = $web; + my $query = $session->{cgiQuery}; + my $topic = $session->{topicName}; + my $tmpDir = $TWiki::cfg{RegistrationApprovals}; - $data->{VerificationCode} = - $data->{WikiName}.'.'.TWiki::User::randomPassword(); - _putRegDetailsByCode( $data, $tmpDir ); + my $code = $data->{WikiName}.'.'.TWiki::User::randomPassword(); + _putRegDetailsByCode( $data, $code ); $session->writeLog( 'regstart', $data->{webName}.'.'.$data->{WikiName}, $data->{Email}, $data->{WikiName} ); @@ -646,34 +662,56 @@ =pod +---++ StaticMethod approveByAdmin($session) + +This is called: on receipt of the approval password -> RegisterCgiScript -> here + 1 calls _reloadUserContext(approval password) + 2 throws oops if appropriate + 3 bails out if the user didn't supply an email address + +=cut + +sub approveByAdmin { + my ( $session ) = @_; + + my $code = $session->{cgiQuery}->param('code'); + unless( $code ) { + throw Error::Simple( 'approveByAdmin: no approval code!'); + } + my $data = _reloadUserContext( $code ); + + if (! exists $data->{Email}) { + throw Error::Simple( 'approveByAdmin: no email address!'); + } + + return $data; +} + +=pod + ---++ StaticMethod verifyEmailAddress($session, $tempUserDir) This is called: on receipt of the activation password -> RegisterCgiScript -> here 1 calls _reloadUserContext(activation password) 2 throws oops if appropriate - 3 calls emailRegistrationConfirmations - 4 still calls 'oopssendmailerr' if a problem, but this is not done uniformly + 3 bails out if the user didn't supply an email address =cut sub verifyEmailAddress { - my( $session, $tempUserDir ) = @_; + my( $session ) = @_; my $code = $session->{cgiQuery}->param('code'); unless( $code ) { throw Error::Simple( 'verifyEmailAddress: no verification code!'); } - my $data = _reloadUserContext( $code, $tempUserDir ); + my $data = _reloadUserContext( $code ); if (! exists $data->{Email}) { throw Error::Simple( 'verifyEmailAddress: no email address!'); } - my $topic = $session->{topicName}; - my $web = $session->{webName}; - - # $this->{session}->writeLog('verifyuser', $loginName, $userName); - + return $data; } =pod @@ -695,22 +733,13 @@ =cut sub finish { - my( $session, $tempUserDir) = @_; + my( $session, $data, $action) = @_; my $topic = $session->{topicName}; my $web = $session->{webName}; my $query = $session->{cgiQuery}; - my $code = $query->param('code'); + my $code = $query->param('code'); - my $data; - if ($TWiki::cfg{Register}{NeedVerification}) { - $data = _reloadUserContext( $code, $tempUserDir ); - _deleteUserContext( $code, $tempUserDir ); - } else { - $data = _getDataFromQuery( $query, $query->param() ); - $data->{webName} = $web; - } - if (! exists $data->{WikiName}) { throw Error::Simple( 'no WikiName after reload'); } @@ -731,16 +760,18 @@ params => $data->{WikiName} ); } - # Plugin callback to set cookies. - $session->{plugins}->registrationHandler( $data->{WebName}, - $data->{WikiName}, - $data->{LoginName} ); + # don't change session data if we are an approving admin + if ($action ne 'approve') { + # Plugin callback to set cookies. + $session->{plugins}->registrationHandler( $data->{WebName}, + $data->{WikiName}, + $data->{LoginName} ); - # let the client session know that we're logged in. (This probably - # eliminates the need for the registrationHandler call above, - # but we'll leave them both in here for now.) - $session->{client}->userLoggedIn( $data->{LoginName}, $data->{WikiName} ); - + # let the client session know that we're logged in. (This probably + # eliminates the need for the registrationHandler call above, + # but we'll leave them both in here for now.) + $session->{client}->userLoggedIn( $data->{LoginName}, $data->{WikiName} ); + } # add user to TWikiUsers topic my $user = $session->{users}->createUser( $data->{LoginName}, $data->{WikiName} ); @@ -756,11 +787,14 @@ $data->{Email}, $data->{WikiName} ); } + _deleteUserContext($code); + + my $def = $action eq 'approve' ? 'thanksadmin' : 'thanks'; # and finally display thank you page throw TWiki::OopsException( 'attention', web => $data->{webName}, topic => $data->{WikiName}, - def => 'thanks', + def => $def, params => $data->{Email} ); } @@ -1086,7 +1120,7 @@ $text =~ s/%WIKINAME%/$p->{Name}/geo; $text =~ s/%EMAILADDRESS%/$p->{Email}/go; $text =~ s/%INTRODUCTION%/$p->{Introduction}/go; - $text =~ s/%VERIFICATIONCODE%/$p->{VerificationCode}/go; + $text =~ s/%VERIFICATIONCODE%/$p->{Code}/go; $text =~ s/%PASSWORD%/$p->{PasswordA}/go; $text = $session->handleCommonTags( $text, $p->{webName}, $p->{WikiName} ); return $session->{net}->sendEmail($text); @@ -1096,15 +1130,17 @@ # | Out | none | # dies if fails to store sub _putRegDetailsByCode { - my ($data, $tmpDir) = @_; + my ($data,$code) = @_; - my $file = _verificationCodeFilename( $data->{VerificationCode}, $tmpDir ); + my $tmpDir = $TWiki::cfg{RegistrationApprovals}; + my $file = _verificationCodeFilename( $code, $tmpDir ); unless( -d $tmpDir ) { require File::Path; File::Path::mkpath( $tmpDir ) || throw Error::Simple( $! ); } open( F, ">$file" ) or throw Error::Simple( 'Failed to open file: '.$! ); print F '# Verification code',"\n"; + $data->{Code} = $code; # SMELL: wierd jiggery-pokery required, otherwise Data::Dumper screws # up the form fields when it saves. Perl bug? Probably to do with # chucking around arrays, instead of references to them. @@ -1141,10 +1177,11 @@ # Returns the users data hash if succeeded. # Returns () if not found. sub _reloadUserContext { - my( $code, $tmpDir ) = @_; + my( $code ) = @_; ASSERT($code) if DEBUG; + my $tmpDir = $TWiki::cfg{RegistrationApprovals}; my $verificationFilename = _verificationCodeFilename( $code, $tmpDir ); unless (-f $verificationFilename){ throw TWiki::OopsException( 'attention', @@ -1169,7 +1206,7 @@ my ($code, $tmpDir ) = @_; my ($name) = $code =~ /^([^.]+)\./; my %data = %{ _getRegDetailsByCode( $code, $tmpDir ) }; #SMELL - expensive? - return 'Invalid activation code' unless $code eq $data{VerificationCode}; + return 'Invalid activation code' unless $code eq $data{Code}; return 'Name in activation code does not match' unless $name eq $data{WikiName}; return; @@ -1178,7 +1215,7 @@ #SMELL: 'Context'? sub _deleteUserContext { my $code = shift; - my $tmpDir = TWiki::Sandbox::untaintUnchecked( shift ); + my $tmpDir = TWiki::Sandbox::untaintUnchecked( $TWiki::cfg{RegistrationApprovals} ); $code =~ s/^([^.]+)\.//; my $name = TWiki::Sandbox::untaintUnchecked( $1 );