codestriker-commits Mailing List for Codestriker: collaborative code reviewer
Brought to you by:
sits
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(58) |
Dec
(14) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(12) |
Feb
(53) |
Mar
(2) |
Apr
|
May
(36) |
Jun
(59) |
Jul
(69) |
Aug
(47) |
Sep
(54) |
Oct
(45) |
Nov
|
Dec
|
2006 |
Jan
(20) |
Feb
(3) |
Mar
|
Apr
(6) |
May
(13) |
Jun
(18) |
Jul
(9) |
Aug
(12) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
2007 |
Jan
|
Feb
(1) |
Mar
(4) |
Apr
(1) |
May
(2) |
Jun
(7) |
Jul
(7) |
Aug
(6) |
Sep
(5) |
Oct
(2) |
Nov
(1) |
Dec
|
2008 |
Jan
(7) |
Feb
(13) |
Mar
(9) |
Apr
|
May
|
Jun
(50) |
Jul
(22) |
Aug
(58) |
Sep
(28) |
Oct
|
Nov
|
Dec
|
From: <si...@us...> - 2008-09-27 04:28:19
|
User: sits Date: 08/09/26 21:28:08 Modified: doc codestriker.sgml Log: Add gotcha for using ScmBug with inetd. Index: codestriker.sgml =================================================================== RCS file: /cvsroot/codestriker/codestriker/doc/codestriker.sgml,v retrieving revision 1.73 retrieving revision 1.74 diff -u -r1.73 -r1.74 --- codestriker.sgml 27 Sep 2008 03:28:56 -0000 1.73 +++ codestriker.sgml 27 Sep 2008 04:28:07 -0000 1.74 @@ -1077,6 +1077,14 @@ codestriker and the <varname>$scmbug_lib_dir</varname> variable made to point at this. </para> + <para> + Using ScmBug for creating topics can generate a very large + number of requests to your SCM system. If your SCM system + is running under a Unix system, you might need to increase + the number of allowed requests per-minute in your inetd + configuration, otherwise you might experience hangs while + creating ScmBug topics. + </para> </sect2> </sect1> |
From: <si...@us...> - 2008-09-27 04:27:38
|
User: sits Date: 08/09/26 21:27:28 Modified: lib/Codestriker/TopicListeners Email.pm Log: Only show context line in emails if the context is actually available. Index: Email.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/TopicListeners/Email.pm,v retrieving revision 1.36 retrieving revision 1.37 diff -u -r1.36 -r1.37 --- Email.pm 6 Sep 2008 00:31:50 -0000 1.36 +++ Email.pm 27 Sep 2008 04:27:27 -0000 1.37 @@ -395,10 +395,6 @@ if ($comment->{fileline} != -1) { $body .= " line $comment->{fileline}.\n\n"; - # Only show the context for a comment made against a specific line. - $body .= "Context:\n$EMAIL_HR\n\n"; - my $email_context = $Codestriker::EMAIL_CONTEXT; - # Retrieve the diff hunk for this file and line number. my $delta = Codestriker::Model::Delta->get_delta($comment->{topicid}, @@ -407,6 +403,11 @@ $comment->{filenew}); if (defined $delta) { + # Only show the context for a comment made against a specific line + # in the original review text. + $body .= "Context:\n$EMAIL_HR\n\n"; + my $email_context = $Codestriker::EMAIL_CONTEXT; + my @text = (); my $offset = $delta->retrieve_context($comment->{fileline}, $comment->{filenew}, $email_context, \@text); |
From: <si...@us...> - 2008-09-27 03:42:05
|
User: sits Date: 08/09/26 20:41:50 Modified: template/en/default viewtopiccomments.html.tmpl lib/Codestriker/Action ViewTopicComments.pm . CHANGELOG Log: * Added "Diff" link for each comment on the list comments page so that for those reviews which aren't linked to an SCM, it is still possible to quickly link back to the coloured topic text. Index: viewtopiccomments.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/viewtopiccomments.html.tmpl,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- viewtopiccomments.html.tmpl 27 Sep 2008 03:28:56 -0000 1.32 +++ viewtopiccomments.html.tmpl 27 Sep 2008 03:41:49 -0000 1.33 @@ -116,6 +116,7 @@ <TD> [% IF comment.filename != '' %] <A HREF="[% comment.view_file %]">[% comment.filename %][% IF comment.fileline != -1 %]:[% comment.fileline %]</A>[% ELSE %]</A> (File Level)[% END %] + | <A HREF="[% comment.view_diff %]">Diff</A> [% IF allow_repositories != 0 %] | <A HREF="[% comment.view_parallel %]">Parallel</A> [% END %] [% ELSIF comment.fileline == -1 && comment.filenumber == -1 %] Topic Level Index: ViewTopicComments.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/ViewTopicComments.pm,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- ViewTopicComments.pm 6 Sep 2008 00:31:45 -0000 1.22 +++ ViewTopicComments.pm 27 Sep 2008 03:41:49 -0000 1.23 @@ -98,8 +98,15 @@ filenumber => $comment->{filenumber}, new => $comment->{filenew}, line => $comment->{fileline}, mode => $mode); + my $view_diff_file = + $url_builder->view_url(topicid => $topicid, projectid => $projectid, + fview => $comment->{filenumber}, + filenumber => $comment->{filenumber}, + new => $comment->{filenew}, + line => $comment->{fileline}, mode => $mode); $comment->{view_file} = "javascript: myOpen('$new_file','CVS')"; + $comment->{view_diff} = "javascript: myOpen('$view_diff_file','CVS')"; my $parallel = $new_file; $comment->{view_parallel} = "javascript: myOpen('$parallel','CVS')"; Index: CHANGELOG =================================================================== RCS file: /cvsroot/codestriker/codestriker/CHANGELOG,v retrieving revision 1.269 retrieving revision 1.270 diff -u -r1.269 -r1.270 --- CHANGELOG 25 Sep 2008 09:11:23 -0000 1.269 +++ CHANGELOG 27 Sep 2008 03:41:50 -0000 1.270 @@ -49,7 +49,11 @@ rob...@us.... * ScmBug integration now works correctly when deleted files are - present in a Subversion changeset. + present in a Subversion changeset. + +* Added "Diff" link for each comment on the list comments page so that for + those reviews which aren't linked to an SCM, it is still possible + to quickly link back to the coloured topic text. Version 1.9.6 |
From: <si...@us...> - 2008-09-27 03:29:06
|
User: sits Date: 08/09/26 20:28:56 Modified: template/en/default viewtopicproperties.html.tmpl viewtopicinfo.html.tmpl viewtopicfile.html.tmpl viewtopiccomments.html.tmpl viewtopic.html.tmpl submitnewtopic.html.tmpl submitnewcomment.html.tmpl search.html.tmpl metricsreport.html.tmpl listtopics.html.tmpl listprojects.html.tmpl header.html.tmpl editproject.html.tmpl editcomment.html.tmpl createtopic.html.tmpl createproject.html.tmpl doc codestriker.sgml Log: Remove "Help" links to specific parts of the manual. It was a pain to update these links whenever the manual changed. Just point to the start of the manual for each page instead. Index: viewtopicproperties.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/viewtopicproperties.html.tmpl,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- viewtopicproperties.html.tmpl 29 Aug 2008 10:49:00 -0000 1.30 +++ viewtopicproperties.html.tmpl 27 Sep 2008 03:28:56 -0000 1.31 @@ -4,8 +4,7 @@ properties can be modified on this page. #%] [% PROCESS viewtopicheader.html.tmpl version = version topicview = 0 - topiccomments = 0 topicinfo = 0 topicproperties = 1 closehead = 1 - help = "x639.html" %] + topiccomments = 0 topicinfo = 0 topicproperties = 1 closehead = 1 %] <script type="text/javascript"> <!-- Index: viewtopicinfo.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/viewtopicinfo.html.tmpl,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- viewtopicinfo.html.tmpl 29 Aug 2008 10:49:00 -0000 1.26 +++ viewtopicinfo.html.tmpl 27 Sep 2008 03:28:56 -0000 1.27 @@ -3,8 +3,7 @@ [% USE AutomagicLinks %] [% PROCESS viewtopicheader.html.tmpl version = version topicview = 0 - topicproperties = 0 topiccomments = 0 topicinfo = 1 closehead = 1 - help = "x652.html" %] + topicproperties = 0 topiccomments = 0 topicinfo = 1 closehead = 1 %] [%# Create a form to allow the topic's metrics to be changed #%] [% SET metric_input_exists = 0 %] Index: viewtopicfile.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/viewtopicfile.html.tmpl,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- viewtopicfile.html.tmpl 8 Aug 2008 07:02:09 -0000 1.4 +++ viewtopicfile.html.tmpl 27 Sep 2008 03:28:56 -0000 1.5 @@ -1,6 +1,6 @@ [%# Screen for displaying a complete file from a topic. #%] -[% PROCESS header.html.tmpl version = version displaymenu = 1 help = "x519.html#VIEW-FILE" +[% PROCESS header.html.tmpl version = version displaymenu = 1 closehead = 1 subtitle = "View Topic File" %] [% PROCESS viewdeltas.html.tmpl deltas = deltas %] Index: viewtopiccomments.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/viewtopiccomments.html.tmpl,v retrieving revision 1.31 retrieving revision 1.32 diff -u -r1.31 -r1.32 --- viewtopiccomments.html.tmpl 31 Aug 2008 11:45:04 -0000 1.31 +++ viewtopiccomments.html.tmpl 27 Sep 2008 03:28:56 -0000 1.32 @@ -4,7 +4,7 @@ [% USE FormatWhitespace tabwidth = tabwidth %] [% PROCESS viewtopicheader.html.tmpl version = version - help = "x617.html" topicview = 0 topicproperties = 0 topiccomments = 1 + topicview = 0 topicproperties = 0 topiccomments = 1 topicinfo = 0 closehead = 1 %] <SCRIPT type="text/javascript"> Index: viewtopic.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/viewtopic.html.tmpl,v retrieving revision 1.54 retrieving revision 1.55 diff -u -r1.54 -r1.55 --- viewtopic.html.tmpl 8 Aug 2008 07:02:08 -0000 1.54 +++ viewtopic.html.tmpl 27 Sep 2008 03:28:56 -0000 1.55 @@ -2,7 +2,7 @@ <body onload="view_topic_on_load_handler();"> [% PROCESS viewtopicheader.html.tmpl version = version - help = "x519.html#VIEW-TOPIC" topicview = 1 topicproperties = 0 + topicview = 1 topicproperties = 0 topiccomments = 0 topicinfo = 0 closehead = 0 %] <p> Index: submitnewtopic.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/submitnewtopic.html.tmpl,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- submitnewtopic.html.tmpl 23 Jun 2008 10:12:16 -0000 1.8 +++ submitnewtopic.html.tmpl 27 Sep 2008 03:28:56 -0000 1.9 @@ -1,7 +1,7 @@ [%# Screen for the submit topic confirmation screen. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help="" subtitle = "Topic Created" %] + closehead = 1 subtitle = "Topic Created" %] [%# Display any "feedback" to the user if necessary. #%] [% IF feedback != '' %] Index: submitnewcomment.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/submitnewcomment.html.tmpl,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- submitnewcomment.html.tmpl 23 Jun 2008 10:12:16 -0000 1.9 +++ submitnewcomment.html.tmpl 27 Sep 2008 03:28:56 -0000 1.10 @@ -1,7 +1,7 @@ [%# Screen for the submit comment confirmation screen. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help="" subtitle = "Comment Submitted" %] + closehead = 1 subtitle = "Comment Submitted" %] <PRE>[% comment | html_entity %] </PRE><P><P> Index: search.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/search.html.tmpl,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- search.html.tmpl 31 Aug 2008 12:02:12 -0000 1.38 +++ search.html.tmpl 27 Sep 2008 03:28:56 -0000 1.39 @@ -1,7 +1,7 @@ [%# Screen for search topics. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help = "x671.html" subtitle = "Find Topics" %] + closehead = 1 subtitle = "Find Topics" %] <FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded" ACTION="[% action_url %]"> Index: metricsreport.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/metricsreport.html.tmpl,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- metricsreport.html.tmpl 8 Aug 2008 07:02:08 -0000 1.22 +++ metricsreport.html.tmpl 27 Sep 2008 03:28:56 -0000 1.23 @@ -1,7 +1,7 @@ [%# Screen for the metrics report. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help ="x707.html" subtitle = "Metrics Report" %] + closehead = 1 subtitle = "Metrics Report" %] <!-- "" --> Index: listtopics.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/listtopics.html.tmpl,v retrieving revision 1.45 retrieving revision 1.46 diff -u -r1.45 -r1.46 --- listtopics.html.tmpl 6 Sep 2008 03:31:08 -0000 1.45 +++ listtopics.html.tmpl 27 Sep 2008 03:28:56 -0000 1.46 @@ -1,7 +1,7 @@ [%# Screen for show a list of topics. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help = "x347.html" subtitle = "Topic List" %] + closehead = 1 subtitle = "Topic List" %] [%# Display any "feedback" to the user if necessary. #%] [% IF feedback != '' %] Index: listprojects.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/listprojects.html.tmpl,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- listprojects.html.tmpl 24 Jun 2008 03:26:50 -0000 1.26 +++ listprojects.html.tmpl 27 Sep 2008 03:28:56 -0000 1.27 @@ -1,7 +1,7 @@ [%# Display a list of projects #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help = "x378.html" subtitle="Project List" %] + closehead = 1 subtitle="Project List" %] [%# Display any "feedback" to the user if necessary. #%] [% IF feedback != '' %] Index: header.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/header.html.tmpl,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- header.html.tmpl 8 Sep 2008 06:49:37 -0000 1.18 +++ header.html.tmpl 27 Sep 2008 03:28:56 -0000 1.19 @@ -19,7 +19,7 @@ | <a href="[% create_topic_url | html_entity %]">Create new topic</a> [% IF searchlist_enabled != 0 %] | <a href="[% search_url | html_entity %]">Search</a> [% END %] [% IF login_url != "" %] | <a href="[% login_url %]">Log In</a>[% END %] - [% IF help != "" %] | <a href="[% doc_url | html_entity %]/[% help %]">Help</a>[% END %] + | <a href="[% doc_url | html_entity %]/codestriker.html">Manual</a> </div> [% END %] </div> Index: editproject.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/editproject.html.tmpl,v retrieving revision 1.27 retrieving revision 1.28 diff -u -r1.27 -r1.28 --- editproject.html.tmpl 24 Jun 2008 03:26:50 -0000 1.27 +++ editproject.html.tmpl 27 Sep 2008 03:28:56 -0000 1.28 @@ -1,7 +1,7 @@ [%# Screen for the edit project form. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help = "x378.html" subtitle = "Edit Project" %] + closehead = 1 subtitle = "Edit Project" %] <script language="JavaScript"> Index: editcomment.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/editcomment.html.tmpl,v retrieving revision 1.28 retrieving revision 1.29 diff -u -r1.28 -r1.29 --- editcomment.html.tmpl 29 Aug 2008 10:48:59 -0000 1.28 +++ editcomment.html.tmpl 27 Sep 2008 03:28:56 -0000 1.29 @@ -118,7 +118,7 @@ [%# Screen for the add comment form. #%] -[% PROCESS header.html.tmpl displaymenu = 0 version = version help = "x519.html#ADD-COMMENT" subtitle = "Add Comment" %] +[% PROCESS header.html.tmpl displaymenu = 0 version = version subtitle = "Add Comment" %] <table border="0" cellpadding="5" cellspacing="0" width="100%"> <tr class="tlh"> Index: createtopic.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/createtopic.html.tmpl,v retrieving revision 1.60 retrieving revision 1.61 diff -u -r1.60 -r1.61 --- createtopic.html.tmpl 25 Sep 2008 00:16:10 -0000 1.60 +++ createtopic.html.tmpl 27 Sep 2008 03:28:56 -0000 1.61 @@ -1,7 +1,7 @@ [%# Screen for the create topic form. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help = "x402.html" subtitle = "Create New Topic" %] + closehead = 1 subtitle = "Create New Topic" %] [%# Display any "feedback" to the user if necessary. #%] [% IF feedback != '' %] Index: createproject.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/createproject.html.tmpl,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- createproject.html.tmpl 24 Jun 2008 03:26:50 -0000 1.26 +++ createproject.html.tmpl 27 Sep 2008 03:28:56 -0000 1.27 @@ -1,7 +1,7 @@ [%# Screen for the create project form. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 help = "x378.html" subtitle = "Create new Project" %] + closehead = 1 subtitle = "Create new Project" %] [%# Display any "feedback" to the user if necessary. #%] [% IF feedback != '' %] Index: codestriker.sgml =================================================================== RCS file: /cvsroot/codestriker/codestriker/doc/codestriker.sgml,v retrieving revision 1.72 retrieving revision 1.73 diff -u -r1.72 -r1.73 --- codestriker.sgml 9 Sep 2008 22:45:44 -0000 1.72 +++ codestriker.sgml 27 Sep 2008 03:28:56 -0000 1.73 @@ -1892,10 +1892,7 @@ file (although the patch segments can still be reviewed). If you commit your code first, then let Codestriker make the diff, as explained in the next section, then you can avoid - this limitation. If you really don't want to commit your - code, you will need to modify the diff file to include the - paths on the Index: +++, and --- lines generated by - <command>svn diff</command>. + this limitation. </para> <para> In some development processes, branches are used as the |
From: <si...@us...> - 2008-09-12 00:08:16
|
User: sits Date: 08/09/11 17:08:15 Modified: lib/Codestriker/Action ResetPassword.pm Log: Fixed typo for handlign case where reset password was done on a non-existant account. Index: ResetPassword.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/ResetPassword.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ResetPassword.pm 8 Sep 2008 05:17:19 -0000 1.2 +++ ResetPassword.pm 12 Sep 2008 00:08:15 -0000 1.3 @@ -26,8 +26,8 @@ # Check that the user account exists. if (!Codestriker::Model::User->exists($email)) { my $feedback = "Unknown user $email specified."; - my $login_url = $url_builder->login(email => $email, - feedback => $feedback); + my $login_url = $url_builder->login_url(email => $email, + feedback => $feedback); print $query->redirect(-URI => $login_url); return; } |
From: <si...@us...> - 2008-09-11 23:26:36
|
User: sits Date: 08/09/11 16:26:35 Modified: lib/Codestriker/Http/Method AddTopicMethod.pm Log: For now, disable authentication when creating topics, so that automated scripts still work. Will need to update CodestrikerClient.pm to take an optional username/password. Index: AddTopicMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/AddTopicMethod.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- AddTopicMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 +++ AddTopicMethod.pm 11 Sep 2008 23:26:35 -0000 1.6 @@ -27,6 +27,13 @@ } } +# For now don't require authentication so that automated scripts can still +# create topics. Will need to modify CodestrikerClient.pm so that it can +# take a username/password. +sub requires_authentication { + return 0; +} + sub extract_parameters { my ($self, $http_input) = @_; |
From: <si...@us...> - 2008-09-09 22:45:47
|
User: sits Date: 08/09/09 15:45:44 Modified: lib/Codestriker/Repository Vss.pm ViewCvs.pm Subversion.pm ScmBug.pm Perforce.pm CvsWeb.pm Cvs.pm ClearCaseSnapshot.pm ClearCaseDynamic.pm doc codestriker.sgml . codestriker.conf CHANGELOG Added: lib/Codestriker Repository.pm Log: * Make $file_viewer more flexible so it can handle file mapping URLs which have CGI parameters. Submitted by va...@us.... Also updated Repository objects so that there is a base class can share a lot of code, such as the file mapping code. Index: Vss.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/Vss.pm,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- Vss.pm 6 Sep 2008 00:31:48 -0000 1.23 +++ Vss.pm 9 Sep 2008 22:45:43 -0000 1.24 @@ -14,6 +14,9 @@ use File::Temp qw/ tmpnam tempdir /; use IO::Handle; +use Codestriker::Repository; +@Codestriker::Repository::Vss::ISA = ("Codestriker::Repository"); + # Switch for emitting debug information. my $_DEBUG = 0; @@ -21,7 +24,10 @@ sub new { my ($type, $username, $password, $ssdir) = @_; - my $self = {}; + my $repository_string = + "vss:" . (defined $ssdir && $ssdir ne '' ? "$ssdir;" : '') . + $username . ":" . $password; + my $self = Codestriker::Repository->new($repository_string); $self->{username} = $username; $self->{password} = $password; $self->{ssdir} = $ssdir; @@ -108,21 +114,6 @@ return "vss:"; } -# Return a URL which views the specified file and revision. -sub getViewUrl ($$$) { - my ($self, $filename, $revision) = @_; - - # Lookup the file viewer from the configuration. - my $viewer = $Codestriker::file_viewer->{$self->toString()}; - return (defined $viewer) ? $viewer . "/" . $filename : ""; -} - -# Return a string representation of this repository. -sub toString ($) { - my ($self) = @_; - return "vss:" . $self->{username} . ":" . $self->{password}; -} - # Retrieve the specified VSS diff directly using VSS commands. sub getDiff ($$$$$) { my ($self, $start_tag, $end_tag, $module_name, $fh, $error_fh) = @_; Index: ViewCvs.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/ViewCvs.pm,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- ViewCvs.pm 6 Sep 2008 00:31:48 -0000 1.6 +++ ViewCvs.pm 9 Sep 2008 22:45:43 -0000 1.7 @@ -13,13 +13,15 @@ use LWP::UserAgent; +use Codestriker::Repository; +@Codestriker::Repository::ViewCvs::ISA = ("Codestriker::Repository"); + # Constructor, which takes as a parameter the URL to the viewcvs repository, # and the CVSROOT. sub new ($$) { my ($type, $viewcvs_url, $cvsroot) = @_; - my $self = {}; - $self->{viewcvs_url} = $viewcvs_url; + my $self = Codestriker::Repository->new($viewcvs_url); $self->{cvsroot} = $cvsroot; bless $self, $type; } @@ -31,7 +33,7 @@ # Retrieve the data by doing an HTPP GET to the remote viewcvs server. my $ua = LWP::UserAgent->new; - my $request = $self->{viewcvs_url} . + my $request = $self->{repository_string} . "/${filename}?rev=${revision}&content-type=text/plain"; my $response = $ua->get($request); my $content = Codestriker::decode_topic_text($response->content); @@ -49,17 +51,10 @@ return $self->{cvsroot}; } -# Return a URL which views the specified file. -sub getViewUrl ($$) { - my ($self, $filename) = @_; - - return $self->{viewcvs_url} . "/" . $filename; -} - # Return a string representation of this repository. sub toString ($) { my ($self) = @_; - return $self->{viewcvs_url} . " " . $self->{cvsroot}; + return $self->{repository_string} . " " . $self->{cvsroot}; } # The getDiff operation is not supported. Index: Subversion.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/Subversion.pm,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- Subversion.pm 6 Sep 2008 00:31:48 -0000 1.25 +++ Subversion.pm 9 Sep 2008 22:45:43 -0000 1.26 @@ -13,10 +13,26 @@ use strict; use Fatal qw / open close /; +use Codestriker::Repository; +@Codestriker::Repository::Subversion::ISA = ("Codestriker::Repository"); + # Constructor, which takes as a parameter the repository url. sub new { my ($type, $repository_url, $user, $password) = @_; + # Sanitise the repository URL. + $repository_url = sanitise_url_component($repository_url); + + # Set the repository string. + my $repository_string = $repository_url; + $repository_string .= ";$user" if defined $user; + $repository_string .= ";$password" if defined $password; + if ($repository_string !~ /^svn:/) { + $repository_string = "svn:" . $repository_string; + } + my $self = Codestriker::Repository->new($repository_string); + $self->{repository_url} = $repository_url; + # Determine if there are additional parameters required for user # authentication. my @userCmdLine = (); @@ -26,19 +42,7 @@ push @userCmdLine, '--password'; push @userCmdLine, $password; } - - # Sanitise the repository URL. - $repository_url = sanitise_url_component($repository_url); - - my $self = {}; - $self->{repository_url} = $repository_url; $self->{userCmdLine} = \@userCmdLine; - $self->{repository_string} = $repository_url; - $self->{repository_string} .= ";$user" if defined $user; - $self->{repository_string} .= ";$password" if defined $password; - if ($self->{repository_string} !~ /^svn:/) { - $self->{repository_string} = "svn:" . $self->{repository_string}; - } bless $self, $type; } @@ -92,25 +96,6 @@ return $self->{repository_url}; } -# Return a URL which views the specified file and revision. -sub getViewUrl ($$$) { - my ($self, $filename, $revision) = @_; - - # Lookup the file viewer from the configuration. - my $viewer = $Codestriker::file_viewer->{$self->toString()}; - if (! (defined $viewer)) { - $viewer = $Codestriker::file_viewer->{$self->{repository_string}}; - } - - return (defined $viewer) ? $viewer . "/" . $filename : ""; -} - -# Return a string representation of this repository. -sub toString ($) { - my ($self) = @_; - return $self->{repository_string}; -} - # Given a Subversion URL, determine if it refers to a directory or a file. sub is_file_url { my ($self, $url) = @_; Index: ScmBug.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/ScmBug.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ScmBug.pm 6 Sep 2008 00:31:48 -0000 1.4 +++ ScmBug.pm 9 Sep 2008 22:45:43 -0000 1.5 @@ -11,6 +11,9 @@ use strict; +use Codestriker::Repository; +@Codestriker::Repository::ScmBug::ISA = ("Codestriker::Repository"); + # Optional dependencies for people who don't require ScmBug functionality. eval("use Scmbug::ActivityUtilities"); @@ -19,7 +22,7 @@ sub new { my ($type, $hostname, $port, $repository) = @_; - my $self = {}; + my $self = Codestriker::Repository->new("scmbug: ${hostname}:${port} " . $repository->toString()); $self->{repository} = $repository; $self->{scmbug} = Scmbug::ActivityUtilities->new($hostname, $port); Index: Perforce.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/Perforce.pm,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- Perforce.pm 6 Sep 2008 00:31:48 -0000 1.8 +++ Perforce.pm 9 Sep 2008 22:45:43 -0000 1.9 @@ -11,18 +11,22 @@ use strict; +use Codestriker::Repository; +@Codestriker::Repository::Perforce::ISA = ("Codestriker::Repository"); + # Constructor, which takes as a parameter the password, hostname and port. sub new ($$$$$) { my ($type, $user, $password, $hostname, $port) = @_; - my $self = {}; + my $repository_string = "perforce:${user}" . + (defined $password && $password ne '' ? ":${password}" : '') . + "@" . "${hostname}:${port}"; + my $self = Codestriker::Repository->new($repository_string); + $self->{user} = $user; $self->{password} = $password; $self->{hostname} = $hostname; $self->{port} = $port; - $self->{root} = "perforce:${user}" . - (defined $password && $password ne '' ? ":${password}" : '') . - "@" . "${hostname}:${port}"; bless $self, $type; } @@ -53,22 +57,7 @@ # Retrieve the "root" of this repository. sub getRoot ($) { my ($self) = @_; - return $self->{root}; -} - -# Return a URL which views the specified file and revision. -sub getViewUrl ($$$) { - my ($self, $filename, $revision) = @_; - - # Lookup the file viewer from the configuration. - my $viewer = $Codestriker::file_viewer->{$self->{root}}; - return (defined $viewer) ? $viewer . "/" . $filename : ""; -} - -# Return a string representation of this repository. -sub toString ($) { - my ($self) = @_; - return $self->{root}; + return $self->{repository_string}; } # Given a start tag, end tag and a module name, store the text into Index: CvsWeb.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/CvsWeb.pm,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- CvsWeb.pm 6 Sep 2008 00:31:48 -0000 1.7 +++ CvsWeb.pm 9 Sep 2008 22:45:43 -0000 1.8 @@ -13,13 +13,15 @@ use LWP::UserAgent; +use Codestriker::Repository; +@Codestriker::Repository::CvsWeb::ISA = ("Codestriker::Repository"); + # Constructor, which takes as a parameter the URL to the cvsweb repository, # and the CVSROOT. sub new ($$) { my ($type, $cvsweb_url, $cvsroot) = @_; - my $self = {}; - $self->{cvsweb_url} = $cvsweb_url; + my $self = Codestriker::Repository->new($cvsweb_url); $self->{cvsroot} = $cvsroot; bless $self, $type; } @@ -31,7 +33,7 @@ # Retrieve the data by doing an HTPP GET to the remote viewcvs server. my $ua = LWP::UserAgent->new; - my $request = $self->{cvsweb_url} . "/~checkout~" . + my $request = $self->{repository_string} . "/~checkout~" . "/${filename}?rev=${revision}&content-type=text/plain"; my $response = $ua->get($request); my $content = Codestriker::decode_topic_text($response->content); @@ -48,17 +50,10 @@ return $self->{cvsroot}; } -# Return a URL which views the specified file. -sub getViewUrl ($$) { - my ($self, $filename) = @_; - - return $self->{cvsweb_url} . "/" . $filename; -} - # Return a string representation of this repository. sub toString ($) { my ($self) = @_; - return $self->{cvsweb_url} . " " . $self->{cvsroot}; + return $self->{repository_string} . " " . $self->{cvsroot}; } # The getDiff operation is not supported. Index: Cvs.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/Cvs.pm,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- Cvs.pm 6 Sep 2008 00:31:48 -0000 1.12 +++ Cvs.pm 9 Sep 2008 22:45:43 -0000 1.13 @@ -13,15 +13,17 @@ use FileHandle; use Fatal qw / open close /; +use Codestriker::Repository; +@Codestriker::Repository::Cvs::ISA = ("Codestriker::Repository"); + # Factory method for creating a local CVS repository object. sub build_local { my ($type, $cvsroot, $optional_prefix) = @_; - my $self = {}; + my $self = Codestriker::Repository->new("${optional_prefix}${cvsroot}"); $self->{cvsroot} = $cvsroot; $optional_prefix = "" unless defined $optional_prefix; $self->{optional_prefix} = $optional_prefix; - $self->{url} = "${optional_prefix}${cvsroot}"; bless $self, $type; } @@ -29,15 +31,14 @@ sub build_pserver { my ($type, $optional_args, $username, $password, $hostname, $cvsroot) = @_; - my $self = {}; + my $self = Codestriker::Repository->new(":pserver${optional_args}:${username}:${password}\@" . + "${hostname}:${cvsroot}"); $optional_args = "" unless defined $optional_args; $self->{optional_args} = $optional_args; $self->{username} = $username; $self->{password} = $password; $self->{hostname} = $hostname; $self->{cvsroot} = $cvsroot; - $self->{url} = ":pserver${optional_args}:${username}:${password}\@" . - "${hostname}:${cvsroot}"; bless $self, $type; } @@ -45,13 +46,12 @@ sub build_ext { my ($type, $optional_args, $username, $hostname, $cvsroot) = @_; - my $self = {}; + my $self = Codestriker::Repository->new(":ext${optional_args}:${username}\@${hostname}:${cvsroot}"); $optional_args = "" unless defined $optional_args; $self->{optional_args} = $optional_args; $self->{username} = $username; $self->{hostname} = $hostname; $self->{cvsroot} = $cvsroot; - $self->{url} = ":ext${optional_args}:${username}\@${hostname}:${cvsroot}"; bless $self, $type; } @@ -59,12 +59,11 @@ sub build_sspi { my ($type, $username, $password, $hostname, $cvsroot) = @_; - my $self = {}; + my $self = Codestriker::Repository->new(":sspi:${username}:${password}\@${hostname}:${cvsroot}"); $self->{optional_args} = ""; $self->{username} = $username; $self->{hostname} = $hostname; $self->{cvsroot} = $cvsroot; - $self->{url} = ":sspi:${username}:${password}\@${hostname}:${cvsroot}"; bless $self, $type; } @@ -83,7 +82,7 @@ my @args = (); push @args, '-q'; push @args, '-d'; - push @args, $self->{url}; + push @args, $self->{repository_string}; push @args, 'co'; push @args, '-p'; push @args, '-r'; @@ -108,21 +107,6 @@ return $self->{cvsroot}; } -# Return a URL which views the specified file and revision. -sub getViewUrl ($$$) { - my ($self, $filename, $revision) = @_; - - # Lookup the file viewer from the configuration. - my $viewer = $Codestriker::file_viewer->{$self->{url}}; - return (defined $viewer) ? $viewer . "/" . $filename : ""; -} - -# Return a string representation of this repository. -sub toString ($) { - my ($self) = @_; - return $self->{url}; -} - # Given a start tag, end tag and a module name, store the text into # the specified file handle. If the size of the diff goes beyond the # limit, then return the appropriate error code. @@ -147,7 +131,7 @@ $ENV{'CVS_RSH'} = $Codestriker::ssh if defined $Codestriker::ssh; Codestriker::execute_command($stdout_fh, $stderr_fh, $Codestriker::cvs, - '-q', '-d', $self->{url}, 'rdiff', + '-q', '-d', $self->{repository_string}, 'rdiff', $extra_options, '-u', '-r', $start_tag, '-r', $end_tag, $module_name); return $Codestriker::OK; Index: ClearCaseSnapshot.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/ClearCaseSnapshot.pm,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ClearCaseSnapshot.pm 6 Sep 2008 00:31:48 -0000 1.7 +++ ClearCaseSnapshot.pm 9 Sep 2008 22:45:43 -0000 1.8 @@ -14,13 +14,16 @@ use File::Temp qw/ tempdir /; use File::Spec; +use Codestriker::Repository; +@Codestriker::Repository::ClearCaseSnapshot::ISA = ("Codestriker::Repository"); + # Constructor. # - snapshot_dir: Absolute path to the location that you access the # files in the snapshot view from. NOT the view storage directory. sub new ($$) { my ($type, $snapshot_dir) = @_; - my $self = {}; + my $self = Codestriker::Repository->new("clearcase:$snapshot_dir"); $self->{snapshot_dir} = $snapshot_dir; bless $self, $type; } @@ -102,21 +105,6 @@ return $self->{snapshot_dir}; } -# Return a URL which views the specified file and revision. -sub getViewUrl ($$$) { - my ($self, $filename, $revision) = @_; - - # Lookup the file viewer from the configuration. - my $viewer = $Codestriker::file_viewer->{$self->toString()}; - return (defined $viewer) ? $viewer . "/" . $filename : ""; -} - -# Return a string representation of this repository. -sub toString ($) { - my ($self) = @_; - return "clearcase:" . $self->{snapshot_dir}; -} - # Given a start tag, end tag and a module name, store the text into # the specified file handle. If the size of the diff goes beyond the # limit, then return the appropriate error code. Index: ClearCaseDynamic.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/ClearCaseDynamic.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ClearCaseDynamic.pm 6 Sep 2008 00:31:48 -0000 1.5 +++ ClearCaseDynamic.pm 9 Sep 2008 22:45:43 -0000 1.6 @@ -13,6 +13,9 @@ use strict; use File::Spec; +use Codestriker::Repository; +@Codestriker::Repository::ClearCaseDynamic::ISA = ("Codestriker::Repository"); + # Put this in an eval block so that this becomes an optional dependency for # those people who don't use this module. eval("use ClearCase::CtCmd"); @@ -26,8 +29,7 @@ { my ($type, $url) = @_; - my $self = {}; - + my $self = Codestriker::Repository->new("clearcase:dyn:$url"); $url =~ /([^:]*):(.*)/; $self->{dynamic_view_name} = $1; $self->{vobs_dir} = $2; @@ -107,22 +109,6 @@ return $self->{vobs_dir}; } -# Return a URL which views the specified file and revision. -sub getViewUrl ($$$) { - my ($self, $filename, $revision) = @_; - - # Lookup the file viewer from the configuration. - my $viewer = $Codestriker::file_viewer->{$self->toString()}; - return (defined $viewer) ? $viewer . "/" . $filename : ""; -} - -# Return a string representation of this repository. -sub toString ($) { - my ($self) = @_; - return "clearcase:dyn:" . $self->{dynamic_view_name} . - ":" . $self->{vobs_dir}; -} - # Given a start tag, end tag and a module name, store the text into # the specified file handle. If the size of the diff goes beyond the # limit, then return the appropriate error code. Index: Repository.pm =================================================================== RCS file: Repository.pm diff -N Repository.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Repository.pm 9 Sep 2008 22:45:44 -0000 1.1 @@ -0,0 +1,54 @@ +############################################################################### +# Codestriker: Copyright (c) 2001,2002,2003 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Base repository object. + +package Codestriker::Repository; + +# Create a new repository instance. +sub new { + my ($type, $repository_string) = @_; + + my $self = {}; + $self->{repository_string} = $repository_string; + return bless $self, $type; +} + +# Return a URL which views the specified file and revision. +sub getViewUrl ($$$) { + my ($self, $filename, $revision) = @_; + + # Lookup the file viewer from the configuration. + my $viewer = $Codestriker::file_viewer->{$self->toString()}; + + # Check in case the user has specified it using the repository string + # instead of the display string. + if (! (defined $viewer)) { + $viewer = $Codestriker::file_viewer->{$self->{repository_string}}; + } + + # If there are CGI parameters in the URL then the file name must + # be inserted before them; otherwise we simply append it to the end. + if (defined $viewer) { + if ($viewer =~ /^([^?]+)(\?.*)$/ ) { + $viewer = $1 . $filename . $2; + } + else { + $viewer .= '/' . $filename; + } + } + + return defined $viewer ? $viewer : ""; +} + +# Return a string representation of this repository. +sub toString ($) { + my ($self) = @_; + return $self->{repository_string}; +} + +1; Index: codestriker.sgml =================================================================== RCS file: /cvsroot/codestriker/codestriker/doc/codestriker.sgml,v retrieving revision 1.71 retrieving revision 1.72 diff -u -r1.71 -r1.72 --- codestriker.sgml 27 Aug 2008 09:51:44 -0000 1.71 +++ codestriker.sgml 9 Sep 2008 22:45:44 -0000 1.72 @@ -577,11 +577,16 @@ During a review, it is sometimes beneficial to see the revision history of a file, such as information provided by CVSweb or ViewCVS. You can specify a mapping of repository - names to URLs for this purpose, for example: + names to URLs for this purpose. When viewing reviews, links + from filenames will be mapped to these URLs, to obtain + revision log information for that file. The filename will + be appended to the end of the URL, before any CGI parameters. <programlisting> $file_viewer = { - '/home/sits/cvs' => 'http://localhost/cgi-bin/cvsweb.cgi' + '/home/sits/cvs' => 'http://localhost/cgi-bin/cvsweb.cgi', + 'svn:file:///var/svn/project/trunk' => + 'http://some.whe.re/cgi-bin/viewvc.cgi/trunk/?root=Project&view=markup' }; </programlisting> This indicates that for any review made against the Index: codestriker.conf =================================================================== RCS file: /cvsroot/codestriker/codestriker/codestriker.conf,v retrieving revision 1.107 retrieving revision 1.108 diff -u -r1.107 -r1.108 --- codestriker.conf 8 Sep 2008 10:40:30 -0000 1.107 +++ codestriker.conf 9 Sep 2008 22:45:44 -0000 1.108 @@ -39,7 +39,7 @@ # system metric reports. If this remains commented out, then no # authentication will be required, and users have full access to the # system. -#$admin_users = [ 'dav...@gm...' ]; +$admin_users = [ 'dav...@gm...' ]; #$admin_users = [ 'dav...@gm...', 'si...@us...' ]; # Location of the mailing host. This is used when sending out codestriker @@ -233,9 +233,13 @@ # not required for remote CVSweb and ViewCVS repositories, as they are # viewers themselves. When viewing reviews, links from filenames will be # mapped to these URLs, to obtain revision log information for that file. +# The filename will be appended to the end of the URL, before any CGI +# parameters. $file_viewer = { - '/home/sits/cvs' => 'http://localhost/cgi-bin/cvsweb.cgi' + '/home/sits/cvs' => 'http://localhost/cgi-bin/cvsweb.cgi', + 'svn:file:///var/svn/project/trunk' => + 'http://some.whe.re/cgi-bin/viewvc.cgi/trunk/?root=Project&view=markup' }; # Exclude these file types from review topics. Index: CHANGELOG =================================================================== RCS file: /cvsroot/codestriker/codestriker/CHANGELOG,v retrieving revision 1.266 retrieving revision 1.267 diff -u -r1.266 -r1.267 --- CHANGELOG 8 Sep 2008 10:40:30 -0000 1.266 +++ CHANGELOG 9 Sep 2008 22:45:44 -0000 1.267 @@ -39,7 +39,10 @@ disappear automatically when the cursor is moved off the (?) link. * Fixed a bug where Subversion diffs with binary files that contained - property changes were not handled correctly. + property changes were not handled correctly. + +* Make $file_viewer more flexible so it can handle file mapping URLs + which have CGI parameters. Submitted by va...@us.... Version 1.9.6 |
From: <si...@us...> - 2008-09-09 04:58:42
|
User: sits Date: 08/09/08 21:58:41 Modified: lib/Codestriker/Action ListTopics.pm Log: Handle list topics properly if sstate is not set. Index: ListTopics.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/ListTopics.pm,v retrieving revision 1.39 retrieving revision 1.40 diff -u -r1.39 -r1.40 --- ListTopics.pm 6 Sep 2008 03:31:06 -0000 1.39 +++ ListTopics.pm 9 Sep 2008 04:58:41 -0000 1.40 @@ -305,7 +305,7 @@ } # Default to show open topics if sstate is not defined. - if (!defined($sstate)) { + if (!defined($sstate) || $sstate eq "") { $sstate = 0; } |
From: <si...@us...> - 2008-09-08 10:40:32
|
User: sits Date: 08/09/08 03:40:31 Modified: lib/Codestriker/Http Method.pm Dispatcher.pm . codestriker.conf CHANGELOG Log: Support older-style deployments here no admin users exist. Index: Method.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method.pm,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- Method.pm 8 Sep 2008 10:19:51 -0000 1.8 +++ Method.pm 8 Sep 2008 10:40:30 -0000 1.9 @@ -46,9 +46,11 @@ return undef; } -# Indicates that this method requires authentication. +# Indicates that this method requires authentication. If an admin +# user has been specified in codestriker.conf, then assume +# authentication is required. sub requires_authentication { - return 1; + return defined $Codestriker::admin_users; } # Indicates that this method can only be executed by an admin. Index: Dispatcher.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Dispatcher.pm,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- Dispatcher.pm 8 Sep 2008 10:19:51 -0000 1.15 +++ Dispatcher.pm 8 Sep 2008 10:40:30 -0000 1.16 @@ -150,7 +150,8 @@ } # Check if the method requires admin priviledges. - if ($found_method->requires_admin() && !$user->{admin}) { + if (defined $Codestriker::admin_users && + $found_method->requires_admin() && !$user->{admin}) { $http_output->error("This function requires admin access."); return; } Index: codestriker.conf =================================================================== RCS file: /cvsroot/codestriker/codestriker/codestriker.conf,v retrieving revision 1.106 retrieving revision 1.107 diff -u -r1.106 -r1.107 --- codestriker.conf 6 Sep 2008 11:33:06 -0000 1.106 +++ codestriker.conf 8 Sep 2008 10:40:30 -0000 1.107 @@ -35,12 +35,12 @@ # Email addresses of admin users for this installation. Admin users # have unrestricted access to the system. Non-admin users will not -# be able to create/edit/delete projects. If no admin user is defined -# then no login system will be used, and all users will be effectively -# admin users. -$admin_users = [ 'dav...@gm...' ]; +# be able to create/edit/delete projects or download the full +# system metric reports. If this remains commented out, then no +# authentication will be required, and users have full access to the +# system. +#$admin_users = [ 'dav...@gm...' ]; #$admin_users = [ 'dav...@gm...', 'si...@us...' ]; -#$admin_users = []; # Location of the mailing host. This is used when sending out codestriker # comments. @@ -109,10 +109,6 @@ #$codestriker_css = 'codestriker.css'; #$codestriker_css = 'codestriker-alternative.css'; -# Indicate what style URLs to support. The default is CGI-style URLs. Set -# this value to 0 for "nicer" URLs. -#$cgi_style = 1; - # Valid repositories which may be selected at the create topic screen. # The order shown here is the order presented in the option list. Most # deployments will only require a single repository to be specified. Index: CHANGELOG =================================================================== RCS file: /cvsroot/codestriker/codestriker/CHANGELOG,v retrieving revision 1.265 retrieving revision 1.266 diff -u -r1.265 -r1.266 --- CHANGELOG 2 Sep 2008 06:33:57 -0000 1.265 +++ CHANGELOG 8 Sep 2008 10:40:30 -0000 1.266 @@ -3,6 +3,12 @@ Version 1.9.7 +* Introduced basic user authentication / authorisation into the + system. If the $admin_users configuration variable is specified + in codestriker.conf, this contains a list of "admin" users. + If defined, admin users are the only ones who can + create/edit/delete projects. + * Created another Subversion post-commit script which is an extension of the standard commit-email.pl script which ships with Subversion. The email sent also includes an additional line, which is the URL to |
From: <si...@us...> - 2008-09-08 10:19:54
|
User: sits Date: 08/09/08 03:19:52 Modified: template/en/default newpassword.html.tmpl login.html.tmpl lib/Codestriker/Model User.pm lib/Codestriker/Http/Method ViewTopicTextMethod.pm ViewTopicPropertiesMethod.pm ViewTopicMetricsMethod.pm ViewTopicFileMethod.pm ViewTopicCommentsMethod.pm ViewMetricsMethod.pm UpdateTopicStateMethod.pm UpdateTopicPropertiesMethod.pm UpdateTopicMetricsMethod.pm UpdateProjectMethod.pm UpdatePasswordMethod.pm UpdateCommentMetricsMethod.pm SubmitSearchTopicsMethod.pm StaticResourcesMethod.pm SearchTopicsMethod.pm ResetPasswordMethod.pm NewPasswordMethod.pm LoginMethod.pm ListTopicsMethod.pm ListProjectsMethod.pm EditProjectMethod.pm DownloadTopicTextMethod.pm DownloadMetricsMethod.pm CreateTopicMethod.pm CreateProjectMethod.pm CreateNewUserMethod.pm CreateCommentMethod.pm AuthenticateMethod.pm AddTopicMethod.pm AddProjectMethod.pm AddNewUserMethod.pm AddCommentMethod.pm lib/Codestriker/Http Method.pm Input.pm Dispatcher.pm lib/Codestriker/Action Login.pm Authenticate.pm Log: Proper user authentication is now in the system. Have also introduced the notion of admin authorisation for some of the project-specific actions and metrics download. Index: newpassword.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/newpassword.html.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- newpassword.html.tmpl 8 Sep 2008 05:17:18 -0000 1.2 +++ newpassword.html.tmpl 8 Sep 2008 10:19:50 -0000 1.3 @@ -6,7 +6,7 @@ Please enter your new password: </p> -<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> +<form method="post" enctype="multipart/form-data" action="[% action_url %]"> <input type="hidden" name="action" value="update_password" /> <input type="hidden" name="email" value="[% email %]" /> Index: login.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/login.html.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- login.html.tmpl 8 Sep 2008 05:17:18 -0000 1.2 +++ login.html.tmpl 8 Sep 2008 10:19:50 -0000 1.3 @@ -12,9 +12,11 @@ Please enter your email address and password to continue. </p> -<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> +<form method="post" enctype="multipart/form-data" action="[% action_url %]"> <input type="hidden" name="action" value="authenticate" /> +<input type="hidden" name="redirect" value="[% redirect %]" /> + <table> <tr> <th align="right">E-mail address:</th> Index: User.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Model/User.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- User.pm 8 Sep 2008 06:49:37 -0000 1.5 +++ User.pm 8 Sep 2008 10:19:50 -0000 1.6 @@ -184,8 +184,9 @@ sub _hash_password { my ($password) = @_; - # List of characters that can be used for the salt. - my @salt_characters = ( '.', '/', 'A'..'Z', 'a'..'z', '0' ..'9' ); + # List of characters that can be used for the salt. Exclude '.' for + # now since that can cause issues when outputting URLs ending in a '.'. + my @salt_characters = ( '/', 'A'..'Z', 'a'..'z', '0' ..'9' ); # Generate the salt. Generate an 8 character value in case we are on # a system which uses MD5 digests (48 bit - 6 * 8). Older systems just Index: ViewTopicTextMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ViewTopicTextMethod.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ViewTopicTextMethod.pm 6 Sep 2008 00:31:44 -0000 1.5 +++ ViewTopicTextMethod.pm 8 Sep 2008 10:19:50 -0000 1.6 @@ -17,7 +17,7 @@ ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; confess "Parameter topicid missing" unless defined $args{topicid}; @@ -44,7 +44,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "view") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/text}) { $self->_extract_nice_parameters($http_input, Index: ViewTopicPropertiesMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ViewTopicPropertiesMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ViewTopicPropertiesMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ ViewTopicPropertiesMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::ViewTopicPropertiesMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; die "Parameter topicid missing" unless defined $args{topicid}; @@ -34,7 +34,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "view_topic_properties") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/properties/view}) { $self->_extract_nice_parameters($http_input, Index: ViewTopicMetricsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ViewTopicMetricsMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ViewTopicMetricsMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ ViewTopicMetricsMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::ViewTopicMetricsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; die "Parameter topicid missing" unless defined $args{topicid}; @@ -34,7 +34,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "viewinfo") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/metrics/view}) { $self->_extract_nice_parameters($http_input, Index: ViewTopicFileMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ViewTopicFileMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ViewTopicFileMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ ViewTopicFileMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::ViewTopicFileMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; die "Parameter topicid missing" unless defined $args{topicid}; @@ -39,7 +39,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "view_file") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/file/\d+}) { $self->_extract_nice_parameters($http_input, Index: ViewTopicCommentsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ViewTopicCommentsMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ViewTopicCommentsMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ ViewTopicCommentsMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::ViewTopicCommentsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; die "Parameter topicid missing" unless defined $args{topicid}; @@ -34,7 +34,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "list_comments") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/comments/list}) { $self->_extract_nice_parameters($http_input, Index: ViewMetricsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ViewMetricsMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ViewMetricsMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ ViewMetricsMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::ViewMetricsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "metrics_report") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/metrics/view$}) { $self->_extract_nice_parameters($http_input); Index: UpdateTopicStateMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdateTopicStateMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- UpdateTopicStateMethod.pm 6 Sep 2008 03:31:07 -0000 1.4 +++ UpdateTopicStateMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::UpdateTopicStateMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -33,7 +33,6 @@ my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "change_topics_state") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/topics/update}) { $self->_extract_nice_parameters($http_input); Index: UpdateTopicPropertiesMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdateTopicPropertiesMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- UpdateTopicPropertiesMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ UpdateTopicPropertiesMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::UpdateTopicPropertiesMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -34,7 +34,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "edit_topic_properties") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/properties}) { $self->_extract_nice_parameters($http_input, Index: UpdateTopicMetricsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdateTopicMetricsMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- UpdateTopicMetricsMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ UpdateTopicMetricsMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::UpdateTopicMetricsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -34,7 +34,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "edit_topic_metrics") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/metrics/update}) { $self->_extract_nice_parameters($http_input, Index: UpdateProjectMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdateProjectMethod.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- UpdateProjectMethod.pm 6 Sep 2008 00:31:45 -0000 1.3 +++ UpdateProjectMethod.pm 8 Sep 2008 10:19:50 -0000 1.4 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::UpdateProjectMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, $projectid) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "submit_editproject") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/admin/project/\d+/update$}) { $self->_extract_nice_parameters($http_input, @@ -42,6 +41,10 @@ } } +sub requires_admin { + return 1; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: UpdatePasswordMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdatePasswordMethod.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- UpdatePasswordMethod.pm 8 Sep 2008 05:17:19 -0000 1.3 +++ UpdatePasswordMethod.pm 8 Sep 2008 10:19:50 -0000 1.4 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::UpdatePasswordMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -34,7 +34,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "update_password") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/user/.*/password/update$}) { $self->_extract_nice_parameters($http_input, @@ -45,6 +44,10 @@ } } +sub requires_authentication { + return 0; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: UpdateCommentMetricsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdateCommentMetricsMethod.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- UpdateCommentMetricsMethod.pm 6 Sep 2008 00:31:44 -0000 1.2 +++ UpdateCommentMetricsMethod.pm 8 Sep 2008 10:19:50 -0000 1.3 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::UpdateCommentMetricsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -34,7 +34,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "change_comments_state") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/comments/update}) { $self->_extract_nice_parameters($http_input, Index: SubmitSearchTopicsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/SubmitSearchTopicsMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- SubmitSearchTopicsMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ SubmitSearchTopicsMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::SubmitSearchTopicsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "submit_search") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/topics/submitsearch}) { $self->_extract_nice_parameters($http_input); Index: StaticResourcesMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/StaticResourcesMethod.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- StaticResourcesMethod.pm 6 Sep 2008 00:31:45 -0000 1.3 +++ StaticResourcesMethod.pm 8 Sep 2008 10:19:50 -0000 1.4 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::StaticResourcesMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self) = @_; # Check if the HTML files are accessible via another URL (required for @@ -39,4 +39,8 @@ } } +sub requires_authentication { + return 0; +} + 1; Index: SearchTopicsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/SearchTopicsMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- SearchTopicsMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ SearchTopicsMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::SearchTopicsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "search") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/topics/search}) { $self->_extract_nice_parameters($http_input); Index: ResetPasswordMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ResetPasswordMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ResetPasswordMethod.pm 8 Sep 2008 06:49:38 -0000 1.4 +++ ResetPasswordMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -17,7 +17,7 @@ @Codestriker::Http::Method::ResetPasswordMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -33,7 +33,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "reset_password") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info eq '/users/reset') { $self->_extract_nice_parameters($http_input); @@ -43,6 +42,10 @@ } } +sub requires_authentication { + return 0; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: NewPasswordMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/NewPasswordMethod.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- NewPasswordMethod.pm 7 Sep 2008 12:20:30 -0000 1.1 +++ NewPasswordMethod.pm 8 Sep 2008 10:19:50 -0000 1.2 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::NewPasswordMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -35,7 +35,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "new_password") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/user/.*/password/new/challenge/}) { $self->_extract_nice_parameters($http_input, @@ -47,6 +46,10 @@ } } +sub requires_authentication { + return 0; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: LoginMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/LoginMethod.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LoginMethod.pm 7 Sep 2008 04:49:26 -0000 1.2 +++ LoginMethod.pm 8 Sep 2008 10:19:50 -0000 1.3 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::LoginMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -36,7 +36,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "login") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/login/form}) { $self->_extract_nice_parameters($http_input, @@ -48,6 +47,10 @@ } } +sub requires_authentication { + return 0; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: ListTopicsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ListTopicsMethod.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ListTopicsMethod.pm 6 Sep 2008 00:31:45 -0000 1.5 +++ ListTopicsMethod.pm 8 Sep 2008 10:19:50 -0000 1.6 @@ -16,7 +16,7 @@ ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; my $sstate = defined $args{sstate} ? CGI::escape(join ',', @{$args{sstate}}) : ""; @@ -64,7 +64,6 @@ my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && ($action eq "list_topics" || $action eq "list_topics_rss")) { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/feed/topics/list} || $path_info =~ m{^/topics/list}) { Index: ListProjectsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ListProjectsMethod.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ListProjectsMethod.pm 6 Sep 2008 00:31:44 -0000 1.5 +++ ListProjectsMethod.pm 8 Sep 2008 10:19:50 -0000 1.6 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::ListProjectsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "list_projects") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/admin/projects/list$}) { $self->_extract_nice_parameters($http_input); Index: EditProjectMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/EditProjectMethod.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- EditProjectMethod.pm 6 Sep 2008 00:31:45 -0000 1.3 +++ EditProjectMethod.pm 8 Sep 2008 10:19:50 -0000 1.4 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::EditProjectMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, $projectid) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "edit_project") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/admin/project/\d+/edit$}) { $self->_extract_nice_parameters($http_input, @@ -42,6 +41,10 @@ } } +sub requires_admin { + return 1; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: DownloadTopicTextMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/DownloadTopicTextMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- DownloadTopicTextMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ DownloadTopicTextMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -17,7 +17,7 @@ ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; confess "Parameter topicid missing" unless defined $args{topicid}; @@ -36,7 +36,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "download") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/download}) { $self->_extract_nice_parameters($http_input, Index: DownloadMetricsMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/DownloadMetricsMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- DownloadMetricsMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ DownloadMetricsMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::DownloadMetricsMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "metrics_download") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/metrics/download$}) { $self->_extract_nice_parameters($http_input); @@ -41,6 +40,10 @@ } } +sub requires_admin { + return 1; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: CreateTopicMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/CreateTopicMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- CreateTopicMethod.pm 6 Sep 2008 00:31:45 -0000 1.4 +++ CreateTopicMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::CreateTopicMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, $obsoletes) = @_; if ($self->{cgi_style}) { @@ -33,7 +33,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "create") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/topics/create}) { $self->_extract_nice_parameters($http_input, Index: CreateProjectMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/CreateProjectMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- CreateProjectMethod.pm 6 Sep 2008 00:31:45 -0000 1.4 +++ CreateProjectMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::CreateProjectMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "create_project") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/admin/projects/create$}) { $self->_extract_nice_parameters($http_input); @@ -41,6 +40,10 @@ } } +sub requires_admin { + return 1; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: CreateNewUserMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/CreateNewUserMethod.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- CreateNewUserMethod.pm 8 Sep 2008 05:17:19 -0000 1.1 +++ CreateNewUserMethod.pm 8 Sep 2008 10:19:50 -0000 1.2 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::CreateNewUserMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -34,7 +34,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "create_new_user") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info eq "/users/create") { $self->_extract_nice_parameters($http_input); @@ -44,6 +43,10 @@ } } +sub requires_authentication { + return 0; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: CreateCommentMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/CreateCommentMethod.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- CreateCommentMethod.pm 6 Sep 2008 00:31:45 -0000 1.5 +++ CreateCommentMethod.pm 8 Sep 2008 10:19:50 -0000 1.6 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::CreateCommentMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; confess "Parameter topicid missing" unless defined $args{topicid}; @@ -41,7 +41,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "edit") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/comment/(\d+)\|(\d+)\|(\d+)/create}) { $self->_extract_nice_parameters($http_input, Index: AuthenticateMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/AuthenticateMethod.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- AuthenticateMethod.pm 8 Sep 2008 06:49:38 -0000 1.3 +++ AuthenticateMethod.pm 8 Sep 2008 10:19:50 -0000 1.4 @@ -16,7 +16,7 @@ @Codestriker::Http::Method::AuthenticateMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -32,7 +32,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "authenticate") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/login/authenticate}) { $self->_extract_nice_parameters($http_input); @@ -42,6 +41,10 @@ } } +sub requires_authentication { + return 0; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: AddTopicMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/AddTopicMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- AddTopicMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ AddTopicMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::AddTopicMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; die "Parameter projectid missing" unless defined $args{projectid}; @@ -33,7 +33,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "submit_new_topic") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topics/add}) { $self->_extract_nice_parameters($http_input, Index: AddProjectMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/AddProjectMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- AddProjectMethod.pm 6 Sep 2008 00:31:44 -0000 1.4 +++ AddProjectMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::AddProjectMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "submit_project") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/admin/projects/add}) { $self->_extract_nice_parameters($http_input); @@ -41,6 +40,10 @@ } } +sub requires_admin { + return 1; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: AddNewUserMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/AddNewUserMethod.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- AddNewUserMethod.pm 8 Sep 2008 05:17:19 -0000 1.1 +++ AddNewUserMethod.pm 8 Sep 2008 10:19:50 -0000 1.2 @@ -31,7 +31,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "add_new_user") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info eq "/users/add") { $self->_extract_nice_parameters($http_input); @@ -41,6 +40,10 @@ } } +sub requires_authentication { + return 0; +} + sub execute { my ($self, $http_input, $http_output) = @_; Index: AddCommentMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/AddCommentMethod.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- AddCommentMethod.pm 6 Sep 2008 00:31:45 -0000 1.4 +++ AddCommentMethod.pm 8 Sep 2008 10:19:50 -0000 1.5 @@ -15,7 +15,7 @@ @Codestriker::Http::Method::AddCommentMethod::ISA = ("Codestriker::Http::Method"); # Generate a URL for this method. -sub url() { +sub url { my ($self, %args) = @_; if ($self->{cgi_style}) { @@ -35,7 +35,6 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); if ($self->{cgi_style} && defined $action && $action eq "submit_comment") { - $http_input->extract_cgi_parameters(); return 1; } elsif ($path_info =~ m{^/project/\d+/topic/\d+/comment/(\d+)\|(\d+)\|(\d+)/add}) { $self->_extract_nice_parameters($http_input, Index: Method.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method.pm,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- Method.pm 7 Sep 2008 11:49:45 -0000 1.7 +++ Method.pm 8 Sep 2008 10:19:51 -0000 1.8 @@ -46,6 +46,16 @@ return undef; } +# Indicates that this method requires authentication. +sub requires_authentication { + return 1; +} + +# Indicates that this method can only be executed by an admin. +sub requires_admin { + return 0; +} + # If this query type is recognised, extract the parameters and store them into # $http_input and return true, otherwise return false. sub extract_parameters { Index: Input.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Input.pm,v retrieving revision 1.53 retrieving revision 1.54 diff -u -r1.53 -r1.54 --- Input.pm 8 Sep 2008 05:17:19 -0000 1.53 +++ Input.pm 8 Sep 2008 10:19:51 -0000 1.54 @@ -204,6 +204,7 @@ $self->_set_property_from_cookie('projectid', 0); $self->_set_property_from_cookie('module', ""); $self->_set_property_from_cookie('topicsort', ""); + $self->_set_property_from_cookie('password_hash', ""); $self->_untaint('topic_sort_change', '(title)|(author)|(created)|(state)'); Index: Dispatcher.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Dispatcher.pm,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- Dispatcher.pm 8 Sep 2008 05:17:19 -0000 1.14 +++ Dispatcher.pm 8 Sep 2008 10:19:51 -0000 1.15 @@ -47,7 +47,6 @@ use Codestriker::Http::Method::AddNewUserMethod; # Initialise all of the methods that are known to the system. -# TODO: add configuration to the parameter. sub new { my ($type, $query) = @_; @@ -101,22 +100,63 @@ sub dispatch { my ($self, $http_input, $http_output) = @_; - # TODO: put login in here which redirects to the login form - # if appropriate with the full URL in the redirect parameter. + # Extract all cookie and CGI parameters. + $http_input->extract_cgi_parameters(); + # Determine which method can handle this URL. + my $found_method; foreach my $method ( @{$self->{methods}} ) { if ($method->extract_parameters($http_input)) { - $method->execute($http_input, $http_output); + $found_method = $method; + } + } + + # Set to a default method if none were found. + if (! defined $found_method) { + $found_method = $Codestriker::allow_searchlist ? + $self->{list_topics_method} : $self->{create_topics_method}; + } + + # Check if the method requires authentication. + my $user; + if ($found_method->requires_authentication()) { + my $query = $http_output->get_query(); + my $email = $http_input->get('email'); + my $password_hash = $http_input->get('password_hash'); + + # If the user is not logged in, redirect to the login screen. + my $full_url = $query->url(-path_info => 1, -query => 1); + my $login_url = + Codestriker::Http::Method::LoginMethod->new($query)->url(redirect => $full_url); + if (!defined($email) || $email eq '' || + !defined($password_hash) || $password_hash eq '') { + print $query->redirect(-URI => $login_url); + return; + } + + # If email has been specified, but it doesn't exist, redirect + # to the login screen. + if (!Codestriker::Model::User->exists($email)) { + print $query->redirect(-URI => $login_url); + return; + } + + # Check that the user has supplied the right credentials. + $user = Codestriker::Model::User->new($email); + if ($user->{password_hash} ne $password_hash) { + print $query->redirect(-URI => $login_url); return; } } - # If we have reached here, execute the default method. - if ($Codestriker::allow_searchlist) { - $self->{list_topics_method}->execute($http_input, $http_output); - } else { - $self->{create_topic_method}->execute($http_input, $http_output); + # Check if the method requires admin priviledges. + if ($found_method->requires_admin() && !$user->{admin}) { + $http_output->error("This function requires admin access."); + return; } + + # All checks have completed, execute the method. + $found_method->execute($http_input, $http_output); } 1; Index: Login.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/Login.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Login.pm 8 Sep 2008 05:17:19 -0000 1.2 +++ Login.pm 8 Sep 2008 10:19:51 -0000 1.3 @@ -27,6 +27,7 @@ $vars->{'action_url'} = $url_builder->authenticate_url(); $vars->{'new_user_url'} = $url_builder->create_new_user_url(); $vars->{'reset_password_url'} = $url_builder->reset_password_url(); + $vars->{'redirect'} = $http_input->get('redirect'); $vars->{'feedback'} = $http_input->get('feedback'); my $template = Codestriker::Http::Template->new("login"); Index: Authenticate.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/Authenticate.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Authenticate.pm 8 Sep 2008 07:20:14 -0000 1.2 +++ Authenticate.pm 8 Sep 2008 10:19:52 -0000 1.3 @@ -43,17 +43,19 @@ print $query->redirect(-URI => $url); } else { # Redirect to the specified URL, if present, otherwise go to the default - # URL. Get the current cookie, and set the password hash into it. + # URL. Get the current cookie, and set the email and password hash + # into it. my %cookie_hash = Codestriker::Http::Cookie->get($query); + $cookie_hash{email} = $user->{email}; $cookie_hash{password_hash} = $user->{password_hash}; my $cookie = Codestriker::Http::Cookie->make($query, \%cookie_hash); if (defined $redirect && $redirect ne "") { print $query->redirect(-cookie => $cookie, - -URI => $redirect); + -location => $redirect); } else { print $query->redirect(-cookie => $cookie, - -URI => $query->url()); + -location => $query->url()); } } } |
From: <si...@us...> - 2008-09-08 07:20:16
|
User: sits Date: 08/09/08 00:20:15 Modified: lib/Codestriker/Http Response.pm lib/Codestriker/Action Authenticate.pm bin install.pl Log: Set the password hash into the cookie. Next step will be to enforce login for certain methods. Index: Response.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Response.pm,v retrieving revision 1.53 retrieving revision 1.54 diff -u -r1.53 -r1.54 --- Response.pm 6 Sep 2008 06:03:56 -0000 1.53 +++ Response.pm 8 Sep 2008 07:20:14 -0000 1.54 @@ -52,6 +52,7 @@ my $projectid = ""; my $load_anchor = ""; my $topicsort = ""; + my $password_hash = ""; my $fview = -1; my $reload = $params{reload}; @@ -129,6 +130,13 @@ $topicsort = $params{topicsort}; } + if (! defined $params{password_hash} || $params{password_hash} eq "") { + $password_hash = Codestriker::Http::Cookie->get_property($query, + 'password_hash'); + } else { + $password_hash = $params{password_hash}; + } + $cookie{'email'} = $email if $email ne ""; $cookie{'reviewers'} = $reviewers if $reviewers ne ""; $cookie{'cc'} = $cc if $cc ne ""; @@ -137,6 +145,7 @@ $cookie{'repository'} = $repository if $repository ne ""; $cookie{'projectid'} = $projectid if $projectid ne ""; $cookie{'topicsort'} = $topicsort if $topicsort ne ""; + $cookie{'password_hash'} = $password_hash if $password_hash ne ""; my $cookie_obj = Codestriker::Http::Cookie->make($query, \%cookie); Index: Authenticate.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/Authenticate.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Authenticate.pm 8 Sep 2008 06:49:38 -0000 1.1 +++ Authenticate.pm 8 Sep 2008 07:20:14 -0000 1.2 @@ -24,10 +24,11 @@ my $feedback = ""; # Check if the account for this email address is valid. + my $user; if (!Codestriker::Model::User->exists($email)) { $feedback = "The username or password you entered is not valid."; } else { - my $user = Codestriker::Model::User->new($email); + $user = Codestriker::Model::User->new($email); # Check that the password entered is correct. if (! $user->check_password($password)) { @@ -42,11 +43,17 @@ print $query->redirect(-URI => $url); } else { # Redirect to the specified URL, if present, otherwise go to the default - # URL. + # URL. Get the current cookie, and set the password hash into it. + my %cookie_hash = Codestriker::Http::Cookie->get($query); + $cookie_hash{password_hash} = $user->{password_hash}; + my $cookie = Codestriker::Http::Cookie->make($query, \%cookie_hash); + if (defined $redirect && $redirect ne "") { - print $query->redirect(-URI => $redirect); + print $query->redirect(-cookie => $cookie, + -URI => $redirect); } else { - print $query->redirect(-URI => $query->url()); + print $query->redirect(-cookie => $cookie, + -URI => $query->url()); } } } Index: install.pl =================================================================== RCS file: /cvsroot/codestriker/codestriker/bin/install.pl,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- install.pl 7 Sep 2008 04:49:27 -0000 1.25 +++ install.pl 8 Sep 2008 07:20:15 -0000 1.26 @@ -1080,7 +1080,7 @@ Codestriker::Model::User->create($admin_user, 1); # TODO: consider sending email with password details. $user_added = 1; - print "Done\n"; + print "Done. You will need to use \"Reset Password\" on the login page.\n"; } else { # Existing user, check if they are an admin already. my $user = Codestriker::Model::User->new($admin_user); |
From: <si...@us...> - 2008-09-08 06:49:39
|
User: sits Date: 08/09/07 23:49:38 Modified: template/en/default header.html.tmpl t/Http/Method reset-password.t lib/Codestriker/Model User.pm lib/Codestriker/Http/Method ResetPasswordMethod.pm AuthenticateMethod.pm lib/Codestriker/Http Template.pm lib/Codestriker/Action UpdatePassword.pm Added: lib/Codestriker/Action Authenticate.pm Log: Now have the login screen working, and checking against the password correctly. Now need to enforce the use of a login depending on what is set in codestriker.conf so that older deployments are not affected. Index: header.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/header.html.tmpl,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- header.html.tmpl 23 Jun 2008 10:12:16 -0000 1.17 +++ header.html.tmpl 8 Sep 2008 06:49:37 -0000 1.18 @@ -18,6 +18,7 @@ [% END %] | <a href="[% create_topic_url | html_entity %]">Create new topic</a> [% IF searchlist_enabled != 0 %] | <a href="[% search_url | html_entity %]">Search</a> [% END %] + [% IF login_url != "" %] | <a href="[% login_url %]">Log In</a>[% END %] [% IF help != "" %] | <a href="[% doc_url | html_entity %]/[% help %]">Help</a>[% END %] </div> [% END %] Index: reset-password.t =================================================================== RCS file: /cvsroot/codestriker/codestriker/t/Http/Method/reset-password.t,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- reset-password.t 7 Sep 2008 12:20:30 -0000 1.2 +++ reset-password.t 8 Sep 2008 06:49:37 -0000 1.3 @@ -1,7 +1,7 @@ # Tests for the ResetPassword method. use strict; -use Test::More tests => 3; +use Test::More tests => 2; use lib '../../../lib'; use Test::MockObject; @@ -18,22 +18,10 @@ my $url_nice = Codestriker::Http::Method::ResetPasswordMethod->new($mock_query, 0); is($url_cgi->url(email => 'jo...@bl...'), - $mock_query->url() . '?action=reset_password&email=joe%40bloggs.com', + $mock_query->url() . '?action=reset_password', "Reset password URL CGI syntax"); is($url_nice->url(email => 'jo...@bl...', challenge => 'abcdefg'), - $mock_query->url() . '/user/joe%40bloggs.com/password/reset', + $mock_query->url() . '/users/reset', "Reset password URL nice syntax"); - -# Check that the parameters extracted correctly. -my $mock_http_input = Test::MockObject->new(); -$mock_http_input->{query} = $mock_query; -$mock_http_input->mock('extract_cgi_parameters', sub { return undef; }); -$mock_query->mock('path_info', - sub { - return '/user/joe%40bloggs.com/password/reset'; - }); -$mock_query->mock('param', sub { return undef; }); -$url_nice->extract_parameters($mock_http_input); -is ($mock_http_input->{email}, 'jo...@bl...', "email nice URL parameter extraction"); Index: User.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Model/User.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- User.pm 8 Sep 2008 05:17:18 -0000 1.4 +++ User.pm 8 Sep 2008 06:49:37 -0000 1.5 @@ -70,6 +70,13 @@ return $count; } +# Checks if the specified password matches this user record. +sub check_password { + my ($self, $password) = @_; + + return crypt($password, $self->{password_hash}) eq $self->{password_hash}; +} + # Update an existing user record with a new password. sub update_password { my ($self, $new_password) = @_; Index: ResetPasswordMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ResetPasswordMethod.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ResetPasswordMethod.pm 8 Sep 2008 05:17:19 -0000 1.3 +++ ResetPasswordMethod.pm 8 Sep 2008 06:49:38 -0000 1.4 @@ -10,6 +10,7 @@ package Codestriker::Http::Method::ResetPasswordMethod; use strict; +use Carp; use Codestriker::Http::Method; use Codestriker::Action::ResetPassword; @@ -20,11 +21,9 @@ my ($self, %args) = @_; if ($self->{cgi_style}) { - return $self->{url_prefix} . "?action=reset_password" . - "&email=" . CGI::escape($args{email}); + return $self->{url_prefix} . "?action=reset_password"; } else { - return $self->{url_prefix} . "/user/" . CGI::escape($args{email}) . - "/password/reset"; + return $self->{url_prefix} . "/users/reset"; } } @@ -36,9 +35,8 @@ if ($self->{cgi_style} && defined $action && $action eq "reset_password") { $http_input->extract_cgi_parameters(); return 1; - } elsif ($path_info =~ m{^/user/.*/password/reset$}) { - $self->_extract_nice_parameters($http_input, - user => 'email'); + } elsif ($path_info eq '/users/reset') { + $self->_extract_nice_parameters($http_input); return 1; } else { return 0; Index: AuthenticateMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/AuthenticateMethod.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- AuthenticateMethod.pm 7 Sep 2008 04:49:26 -0000 1.2 +++ AuthenticateMethod.pm 8 Sep 2008 06:49:38 -0000 1.3 @@ -11,6 +11,7 @@ use strict; use Codestriker::Http::Method; +use Codestriker::Action::Authenticate; @Codestriker::Http::Method::AuthenticateMethod::ISA = ("Codestriker::Http::Method"); Index: Template.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Template.pm,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- Template.pm 6 Sep 2008 00:31:47 -0000 1.20 +++ Template.pm 8 Sep 2008 06:49:38 -0000 1.21 @@ -126,6 +126,7 @@ $vars->{'create_topic_url'} = $url_builder->create_topic_url(); $vars->{'search_url'} = $url_builder->search_url(); $vars->{'doc_url'} = $url_builder->doc_url(); + $vars->{'login_url'} = $url_builder->login_url(); my $data = ""; my $rc = $self->{template}->process($self->{name} . "." . $self->{type} . ".tmpl", Index: UpdatePassword.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/UpdatePassword.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- UpdatePassword.pm 8 Sep 2008 05:17:19 -0000 1.1 +++ UpdatePassword.pm 8 Sep 2008 06:49:38 -0000 1.2 @@ -38,7 +38,7 @@ "Your password has not been changed."; } else { $user->update_password($password); - $feedback = "Password has been updated."; + $feedback = "Your password has been updated."; } } Index: Authenticate.pm =================================================================== RCS file: Authenticate.pm diff -N Authenticate.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Authenticate.pm 8 Sep 2008 06:49:38 -0000 1.1 @@ -0,0 +1,54 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Action object for authenticating a user. + +package Codestriker::Action::Authenticate; + +use strict; +use Codestriker::Http::UrlBuilder; +use Codestriker::Model::User; + +sub process { + my ($type, $http_input, $http_response) = @_; + + my $query = $http_response->get_query(); + my $email = $http_input->get('email'); + my $password = $http_input->get('password'); + my $redirect = $http_input->get('redirect'); + + my $feedback = ""; + + # Check if the account for this email address is valid. + if (!Codestriker::Model::User->exists($email)) { + $feedback = "The username or password you entered is not valid."; + } else { + my $user = Codestriker::Model::User->new($email); + + # Check that the password entered is correct. + if (! $user->check_password($password)) { + $feedback = "The username or password you entered is not valid."; + } + } + + # If there is feedback, redirect to the login screen. + my $url_builder = Codestriker::Http::UrlBuilder->new($query); + if ($feedback ne "") { + my $url = $url_builder->login_url(feedback => $feedback); + print $query->redirect(-URI => $url); + } else { + # Redirect to the specified URL, if present, otherwise go to the default + # URL. + if (defined $redirect && $redirect ne "") { + print $query->redirect(-URI => $redirect); + } else { + print $query->redirect(-URI => $query->url()); + } + } +} + +1; |
From: <si...@us...> - 2008-09-08 05:18:06
|
User: sits Date: 08/09/07 22:18:06 Added: template/en/default resetpassword.html.tmpl Log: A whole stack of user functionality now works (registration, forgetting password). Just need to actually implement the log-in feature now. Index: resetpassword.html.tmpl =================================================================== RCS file: resetpassword.html.tmpl diff -N resetpassword.html.tmpl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ resetpassword.html.tmpl 8 Sep 2008 05:18:05 -0000 1.3 @@ -0,0 +1,13 @@ +[%# Screen to show after the submision of a reset password request. #%] + +[% PROCESS header.html.tmpl version = version displaymenu = 1 + closehead = 1 subtitle = "Reset Password" %] +<p> +An email containing instructions for changing your password has been sent +to you. Follow the instructions in that email to change your password. +</p> + +[% PROCESS trailer.html.tmpl %] + +</body> +</html> |
From: <si...@us...> - 2008-09-08 05:17:21
|
User: sits Date: 08/09/07 22:17:19 Modified: template/en/default newpassword.html.tmpl login.html.tmpl lib/Codestriker/Model User.pm lib/Codestriker/Http/Method UpdatePasswordMethod.pm ResetPasswordMethod.pm lib/Codestriker/Http UrlBuilder.pm Input.pm Dispatcher.pm lib/Codestriker/Action ResetPassword.pm NewPassword.pm Login.pm Added: template/en/default createuser.html.tmpl adduser.html.tmpl t/Http/Method create-new-user.t lib/Codestriker/Http/Method CreateNewUserMethod.pm AddNewUserMethod.pm lib/Codestriker/Action UpdatePassword.pm CreateNewUser.pm AddNewUser.pm Log: A whole stack of user functionality now works (registration, forgetting password). Just need to actually implement the log-in feature now. Index: newpassword.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/newpassword.html.tmpl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- newpassword.html.tmpl 7 Sep 2008 12:20:29 -0000 1.1 +++ newpassword.html.tmpl 8 Sep 2008 05:17:18 -0000 1.2 @@ -1,9 +1,9 @@ -[%# Screen for the reset password form. #%] +[%# Screen for the new password form. #%] [% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 subtitle = "Reset Password" %] + closehead = 1 subtitle = "New Password" %] <p> -Please enter your new password. +Please enter your new password: </p> <form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> @@ -24,30 +24,10 @@ </tr> </table> - <input type="submit" name=".submit" value="Reset Password" /> + <input type="submit" name=".submit" value="Submit New Password" /> </form> -<!-- -<hr> - -<p> -If you don't have a Codestriker account, you can create a new account. -</p> - -<hr> - -<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> - <input type="hidden" name="action" value="reset_password"> - <p> - If you have an account, but have forgotten your password, - enter your e-mail address below to generate a new password. - </p> - <input size="40" maxlength="80" name="email"> - <input type="submit" name=".submit2" value="Regenerate Password"> -</form> ---> - [% PROCESS trailer.html.tmpl %] </body> Index: login.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/login.html.tmpl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- login.html.tmpl 7 Sep 2008 04:49:26 -0000 1.1 +++ login.html.tmpl 8 Sep 2008 05:17:18 -0000 1.2 @@ -2,6 +2,12 @@ [% PROCESS header.html.tmpl version = version displaymenu = 1 closehead = 1 subtitle = "Login" %] + +[%# Display any "feedback" to the user if necessary. #%] +[% IF feedback != '' %] + <span class="feedback">[% feedback %]</span> +[% END %] + <p> Please enter your email address and password to continue. </p> @@ -31,25 +37,23 @@ </form> -<!-- <hr> <p> -If you don't have a Codestriker account, you can create a new account. +If you don't have a Codestriker account, you can <a href="[% new_user_url %]">create a new account</a>. </p> <hr> -<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> +<form method="post" enctype="application/x-www-form-urlencoded" action="[% reset_password_url %]"> <input type="hidden" name="action" value="reset_password"> <p> If you have an account, but have forgotten your password, enter your e-mail address below to generate a new password. </p> <input size="40" maxlength="80" name="email"> - <input type="submit" name=".submit2" value="Regenerate Password"> + <input type="submit" name=".submit2" value="Reset Password"> </form> ---> [% PROCESS trailer.html.tmpl %] Index: createuser.html.tmpl =================================================================== RCS file: createuser.html.tmpl diff -N createuser.html.tmpl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ createuser.html.tmpl 8 Sep 2008 05:17:18 -0000 1.1 @@ -0,0 +1,34 @@ +[%# Screen for the create new user form. #%] + +[% PROCESS header.html.tmpl version = version displaymenu = 1 + closehead = 1 subtitle = "Create new Account" %] + +[%# Display any "feedback" to the user if necessary. #%] +[% IF feedback != '' %] + <span class="feedback">[% feedback %]</span> +[% END %] + +<p> +Please enter the email address of the new account. +</p> + +<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> + +<input type="hidden" name="action" value="add_new_user" /> + <table> + <tr> + <th align="right">E-mail address:</th> + <td> + <input size="40" maxlength="80" name="email"> + </td> + </tr> + </table> + + <input type="submit" name=".submit" value="Create new Account" /> + +</form> + +[% PROCESS trailer.html.tmpl %] + +</body> +</html> Index: adduser.html.tmpl =================================================================== RCS file: adduser.html.tmpl diff -N adduser.html.tmpl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ adduser.html.tmpl 8 Sep 2008 05:17:18 -0000 1.1 @@ -0,0 +1,15 @@ +[%# Screen for the add new user confirmation. #%] + +[% PROCESS header.html.tmpl version = version displaymenu = 1 + closehead = 1 subtitle = "New Account" %] + +<p> +An email has been sent containing instructions on completing registration for +this new account. Please follow the instructions in this email to complete +registration. +</p> + +[% PROCESS trailer.html.tmpl %] + +</body> +</html> Index: create-new-user.t =================================================================== RCS file: create-new-user.t diff -N create-new-user.t --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ create-new-user.t 8 Sep 2008 05:17:18 -0000 1.1 @@ -0,0 +1,26 @@ +# Tests for the CreateNewUser method. + +use strict; +use Test::More tests => 2; + +use lib '../../../lib'; +use Test::MockObject; +use Codestriker; +use Codestriker::Http::Method::CreateNewUserMethod; + +# Create a CGI mock object for these tests. +my $mock_query = Test::MockObject->new(); +$mock_query->mock('url', + sub { 'http://localhost.localdomain/codestriker/codestriker.pl' } ); + +# Create two method objects to test each URL scheme. +my $url_cgi = Codestriker::Http::Method::CreateNewUserMethod->new($mock_query, 1); +my $url_nice = Codestriker::Http::Method::CreateNewUserMethod->new($mock_query, 0); + +is($url_cgi->url(), + $mock_query->url() . '?action=create_new_user', + "New user URL CGI syntax"); + +is($url_nice->url(), + $mock_query->url() . '/users/create', + "New user URL nice syntax"); Index: User.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Model/User.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- User.pm 7 Sep 2008 04:49:26 -0000 1.3 +++ User.pm 8 Sep 2008 05:17:18 -0000 1.4 @@ -116,7 +116,7 @@ } # Create a new user into the database with all of the specified properties. -# Return the new password which has been assigned to the user. +# Return the new challenge which has been assigned to the user. sub create { my ($type, $email, $admin) = @_; @@ -148,7 +148,7 @@ # case where a user can update their password via a # challenge/response protocol. sub create_challenge { - my ($self, $email) = @_; + my ($self) = @_; # Obtain a database connection. my $dbh = Codestriker::DB::DBI->get_connection(); @@ -163,7 +163,7 @@ $dbh->prepare_cached('UPDATE usertable ' . 'SET challenge = ? ' . 'WHERE email = ? '); - $challenge_update->execute($self->{email}, $challenge); + $challenge_update->execute($challenge, $self->{email}); }; my $success = $@ ? 0 : 1; Index: UpdatePasswordMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdatePasswordMethod.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- UpdatePasswordMethod.pm 7 Sep 2008 12:20:30 -0000 1.2 +++ UpdatePasswordMethod.pm 8 Sep 2008 05:17:19 -0000 1.3 @@ -11,6 +11,7 @@ use strict; use Codestriker::Http::Method; +use Codestriker::Action::UpdatePassword; @Codestriker::Http::Method::UpdatePasswordMethod::ISA = ("Codestriker::Http::Method"); @@ -47,7 +48,7 @@ sub execute { my ($self, $http_input, $http_output) = @_; -# Codestriker::Action::UpdatePassword->process($http_input, $http_output); + Codestriker::Action::UpdatePassword->process($http_input, $http_output); } 1; Index: ResetPasswordMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ResetPasswordMethod.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ResetPasswordMethod.pm 7 Sep 2008 12:20:30 -0000 1.2 +++ ResetPasswordMethod.pm 8 Sep 2008 05:17:19 -0000 1.3 @@ -11,6 +11,7 @@ use strict; use Codestriker::Http::Method; +use Codestriker::Action::ResetPassword; @Codestriker::Http::Method::ResetPasswordMethod::ISA = ("Codestriker::Http::Method"); @@ -47,7 +48,7 @@ sub execute { my ($self, $http_input, $http_output) = @_; -# Codestriker::Action::UpdatePassword->process($http_input, $http_output); + Codestriker::Action::ResetPassword->process($http_input, $http_output); } 1; Index: CreateNewUserMethod.pm =================================================================== RCS file: CreateNewUserMethod.pm diff -N CreateNewUserMethod.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ CreateNewUserMethod.pm 8 Sep 2008 05:17:19 -0000 1.1 @@ -0,0 +1,53 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Method for creating a new user. + +package Codestriker::Http::Method::CreateNewUserMethod; + +use strict; +use Codestriker::Http::Method; +use Codestriker::Action::CreateNewUser; + +@Codestriker::Http::Method::CreateNewUserMethod::ISA = ("Codestriker::Http::Method"); + +# Generate a URL for this method. +sub url() { + my ($self, %args) = @_; + + if ($self->{cgi_style}) { + return $self->{url_prefix} . "?action=create_new_user" . + (defined $args{feedback} ? "&feedback=" . CGI::escape($args{feedback}) : ""); + } else { + return $self->{url_prefix} . "/users/create" . + (defined $args{feedback} ? "/feedback/" . CGI::escape($args{feedback}) : ""); + } +} + +sub extract_parameters { + my ($self, $http_input) = @_; + + my $action = $http_input->{query}->param('action'); + my $path_info = $http_input->{query}->path_info(); + if ($self->{cgi_style} && defined $action && $action eq "create_new_user") { + $http_input->extract_cgi_parameters(); + return 1; + } elsif ($path_info eq "/users/create") { + $self->_extract_nice_parameters($http_input); + return 1; + } else { + return 0; + } +} + +sub execute { + my ($self, $http_input, $http_output) = @_; + + Codestriker::Action::CreateNewUser->process($http_input, $http_output); +} + +1; Index: AddNewUserMethod.pm =================================================================== RCS file: AddNewUserMethod.pm diff -N AddNewUserMethod.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ AddNewUserMethod.pm 8 Sep 2008 05:17:19 -0000 1.1 @@ -0,0 +1,50 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Method for handling the creation of a new user. + +package Codestriker::Http::Method::AddNewUserMethod; + +use strict; +use Codestriker::Http::Method; + +@Codestriker::Http::Method::AddNewUserMethod::ISA = ("Codestriker::Http::Method"); + +# Generate a URL for this method. +sub url() { + my ($self, %args) = @_; + + if ($self->{cgi_style}) { + return $self->{url_prefix} . "?action=add_new_user"; + } else { + return $self->{url_prefix} . "/users/add"; + } +} + +sub extract_parameters { + my ($self, $http_input) = @_; + + my $action = $http_input->{query}->param('action'); + my $path_info = $http_input->{query}->path_info(); + if ($self->{cgi_style} && defined $action && $action eq "add_new_user") { + $http_input->extract_cgi_parameters(); + return 1; + } elsif ($path_info eq "/users/add") { + $self->_extract_nice_parameters($http_input); + return 1; + } else { + return 0; + } +} + +sub execute { + my ($self, $http_input, $http_output) = @_; + + Codestriker::Action::AddNewUser->process($http_input, $http_output); +} + +1; Index: UrlBuilder.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/UrlBuilder.pm,v retrieving revision 1.52 retrieving revision 1.53 diff -u -r1.52 -r1.53 --- UrlBuilder.pm 7 Sep 2008 12:20:31 -0000 1.52 +++ UrlBuilder.pm 8 Sep 2008 05:17:19 -0000 1.53 @@ -40,6 +40,8 @@ use Codestriker::Http::Method::NewPasswordMethod; use Codestriker::Http::Method::UpdatePasswordMethod; use Codestriker::Http::Method::ResetPasswordMethod; +use Codestriker::Http::Method::CreateNewUserMethod; +use Codestriker::Http::Method::AddNewUserMethod; # Constructor for this class. sub new { @@ -260,5 +262,16 @@ return Codestriker::Http::Method::AuthenticateMethod->new($self->{query})->url(%args); } +# Create the URL for creating a new user. +sub create_new_user_url { + my ($self, %args) = @_; + return Codestriker::Http::Method::CreateNewUserMethod->new($self->{query})->url(%args); +} + +# Create the URL for adding a new user. +sub add_new_user_url { + my ($self, %args) = @_; + return Codestriker::Http::Method::AddNewUserMethod->new($self->{query})->url(%args); +} 1; Index: Input.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Input.pm,v retrieving revision 1.52 retrieving revision 1.53 diff -u -r1.52 -r1.53 --- Input.pm 7 Sep 2008 11:49:45 -0000 1.52 +++ Input.pm 8 Sep 2008 05:17:19 -0000 1.53 @@ -108,6 +108,8 @@ $self->{email_event} = $query->param('email_event'); $self->{redirect} = $query->param('redirect'); $self->{challenge} = $query->param('challenge'); + $self->{password} = $query->param('password'); + $self->{feedback} = $query->param('feedback'); # Set any missing parameters from the cookie. my %cookie = Codestriker::Http::Cookie->get($query); @@ -130,6 +132,7 @@ $self->{obsoletes} = "" if ! defined $self->{obsoletes}; $self->{default_to_head} = 0 if ! defined $self->{default_to_head}; $self->{email_event} = 1 if ! defined $self->{email_event}; + $self->{feedback} = "" if ! defined $self->{feedback}; my @topic_metrics = $query->param('topic_metric'); $self->{topic_metric} = \@topic_metrics; @@ -234,9 +237,6 @@ $self->{cc} = $self->make_canonical_email_list($self->{cc}); $self->{bug_ids} = $self->make_canonical_bug_list($self->{bug_ids}); $self->{comment_cc} = $self->make_canonical_email_list($self->{comment_cc}); - - # Initialise the feedback field to empty. - $self->{feedback} = ""; } # Return the query object associated with this object. @@ -352,14 +352,14 @@ sub _untaint_email($$) { my ($self, $name) = @_; - $self->_untaint($name, '[\s]*[-_\w\.]{1,200}(\@[-_\w\.]{1,200})?[\s]*'); + $self->_untaint($name, '[\s]*[-_\+\w\.]{1,200}(\@[-_\+\w\.]{1,200})?[\s]*'); } # Untaint a list of email addresses. sub _untaint_emails($$) { my ($self, $name) = @_; - $self->_untaint($name, '[\s]*([-_\w\.]{1,200}(\@[-_\w\.]{1,200})?[\s,;]*){1,100}[\s]*'); + $self->_untaint($name, '[\s]*([-_\+\w\.]{1,200}(\@[-_\+\w\.]{1,200})?[\s,;]*){1,100}[\s]*'); } # Untaint a list of bug ids. Index: Dispatcher.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Dispatcher.pm,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- Dispatcher.pm 7 Sep 2008 12:20:31 -0000 1.13 +++ Dispatcher.pm 8 Sep 2008 05:17:19 -0000 1.14 @@ -43,6 +43,8 @@ use Codestriker::Http::Method::NewPasswordMethod; use Codestriker::Http::Method::UpdatePasswordMethod; use Codestriker::Http::Method::ResetPasswordMethod; +use Codestriker::Http::Method::CreateNewUserMethod; +use Codestriker::Http::Method::AddNewUserMethod; # Initialise all of the methods that are known to the system. # TODO: add configuration to the parameter. @@ -87,6 +89,8 @@ push @methods, Codestriker::Http::Method::NewPasswordMethod->new($query); push @methods, Codestriker::Http::Method::UpdatePasswordMethod->new($query); push @methods, Codestriker::Http::Method::ResetPasswordMethod->new($query); + push @methods, Codestriker::Http::Method::AddNewUserMethod->new($query); + push @methods, Codestriker::Http::Method::CreateNewUserMethod->new($query); $self->{methods} = \@methods; return bless $self, $type; Index: ResetPassword.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/ResetPassword.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ResetPassword.pm 7 Sep 2008 11:49:45 -0000 1.1 +++ ResetPassword.pm 8 Sep 2008 05:17:19 -0000 1.2 @@ -5,30 +5,60 @@ # This program is free software; you can redistribute it and modify it under # the terms of the GPL. -# Action object for displaying the reset password page. +# Action object for handling a reset password action. package Codestriker::Action::ResetPassword; use strict; +use Net::SMTP; use Codestriker::Http::UrlBuilder; +use Codestriker::Model::User; +use Codestriker::Action::AddNewUser; -# Create an appropriate form for reseting the password. sub process { my ($type, $http_input, $http_response) = @_; my $query = $http_response->get_query(); + my $url_builder = Codestriker::Http::UrlBuilder->new($query); + + my $email = $http_input->get('email'); + + # Check that the user account exists. + if (!Codestriker::Model::User->exists($email)) { + my $feedback = "Unknown user $email specified."; + my $login_url = $url_builder->login(email => $email, + feedback => $feedback); + print $query->redirect(-URI => $login_url); + return; + } $http_response->generate_header(topic_title=>"Reset Password", reload=>0, cache=>1); - # Target URL to divert the post to. - my $vars = {}; - my $url_builder = Codestriker::Http::UrlBuilder->new($query); - $vars->{'action_url'} = $url_builder->update_password_url(); - $vars->{'challenge'} = $http_input->get('challenge'); - $vars->{'email'} = $http_input->get('email'); + # Create a new challenge for this user. + my $user = Codestriker::Model::User->new($email); + my $challenge = $user->create_challenge(); + + # Now send out an email to the user with the magic URL so that they + # can prove they own this email address. + my $magic_url = $url_builder->new_password_url(email => $email, + challenge => $challenge); + Codestriker::Action::AddNewUser->_send_email($email, + "Reset Password for Codestriker Account", + <<"END_EMAIL_TEXT" +You have (or someone impersonating you has) requested to change your +Codestriker password. To complete the change, visit the following link: + +$magic_url + +If you are not the person who made this request, or you wish to cancel +this request, simply ignore and delete this email. +END_EMAIL_TEXT +); + # Show the post reset-password screen. my $template = Codestriker::Http::Template->new("resetpassword"); + my $vars = {}; $template->process($vars); $http_response->generate_footer(); Index: NewPassword.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/NewPassword.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- NewPassword.pm 7 Sep 2008 12:20:31 -0000 1.1 +++ NewPassword.pm 8 Sep 2008 05:17:19 -0000 1.2 @@ -17,6 +17,8 @@ my ($type, $http_input, $http_response) = @_; my $query = $http_response->get_query(); + my $email = $http_input->get('email'); + my $challenge = $http_input->get('challenge'); $http_response->generate_header(topic_title=>"New Password", reload=>0, cache=>1); @@ -24,9 +26,9 @@ # Target URL to divert the post to. my $vars = {}; my $url_builder = Codestriker::Http::UrlBuilder->new($query); - $vars->{'action_url'} = $url_builder->update_password_url(); - $vars->{'challenge'} = $http_input->get('challenge'); - $vars->{'email'} = $http_input->get('email'); + $vars->{'action_url'} = $url_builder->update_password_url(email => $email); + $vars->{'email'} = $email; + $vars->{'challenge'} = $challenge; my $template = Codestriker::Http::Template->new("newpassword"); $template->process($vars); Index: Login.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/Login.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Login.pm 7 Sep 2008 04:49:27 -0000 1.1 +++ Login.pm 8 Sep 2008 05:17:19 -0000 1.2 @@ -25,6 +25,9 @@ my $vars = {}; my $url_builder = Codestriker::Http::UrlBuilder->new($query); $vars->{'action_url'} = $url_builder->authenticate_url(); + $vars->{'new_user_url'} = $url_builder->create_new_user_url(); + $vars->{'reset_password_url'} = $url_builder->reset_password_url(); + $vars->{'feedback'} = $http_input->get('feedback'); my $template = Codestriker::Http::Template->new("login"); $template->process($vars); Index: UpdatePassword.pm =================================================================== RCS file: UpdatePassword.pm diff -N UpdatePassword.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ UpdatePassword.pm 8 Sep 2008 05:17:19 -0000 1.1 @@ -0,0 +1,51 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Action object for updating the password for a user account. + +package Codestriker::Action::UpdatePassword; + +use strict; +use Codestriker::Http::UrlBuilder; +use Codestriker::Model::User; + +# Try to update the user's password assuming the challenge/response +# is correct, then redirect to the login screen with the appropriate +# feedback. +sub process { + my ($type, $http_input, $http_response) = @_; + + my $query = $http_response->get_query(); + my $email = $http_input->get('email'); + my $challenge = $http_input->get('challenge'); + my $password = $http_input->get('password'); + + my $feedback = ""; + + # Check if the account for this email address is valid. + if (!Codestriker::Model::User->exists($email)) { + $feedback = "Unknown user $email specified."; + } else { + my $user = Codestriker::Model::User->new($email); + + # Check that the challenge specified is correct. + if ($user->{challenge} ne $challenge) { + $feedback = "Challenge specified is incorrect. " . + "Your password has not been changed."; + } else { + $user->update_password($password); + $feedback = "Password has been updated."; + } + } + + # Redirect to the login screen with the appropriate feedback. + my $url_builder = Codestriker::Http::UrlBuilder->new($query); + my $url = $url_builder->login_url(feedback => $feedback); + print $query->redirect(-URI => $url); +} + +1; Index: CreateNewUser.pm =================================================================== RCS file: CreateNewUser.pm diff -N CreateNewUser.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ CreateNewUser.pm 8 Sep 2008 05:17:19 -0000 1.1 @@ -0,0 +1,36 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Action object for displaying the create new user page. + +package Codestriker::Action::CreateNewUser; + +use strict; +use Codestriker::Http::UrlBuilder; + +# Create an appropriate form for creating a new user. +sub process { + my ($type, $http_input, $http_response) = @_; + + my $query = $http_response->get_query(); + + $http_response->generate_header(topic_title=>"Create User", + reload=>0, cache=>1); + + # Target URL to divert the post to. + my $vars = {}; + my $url_builder = Codestriker::Http::UrlBuilder->new($query); + $vars->{'action_url'} = $url_builder->add_new_user_url(); + $vars->{'feedback'} = $http_input->get('feedback'); + + my $template = Codestriker::Http::Template->new("createuser"); + $template->process($vars); + + $http_response->generate_footer(); +} + +1; Index: AddNewUser.pm =================================================================== RCS file: AddNewUser.pm diff -N AddNewUser.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ AddNewUser.pm 8 Sep 2008 05:17:19 -0000 1.1 @@ -0,0 +1,123 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Action object for handling the creation of a new user account. + +package Codestriker::Action::AddNewUser; + +use strict; +use Net::SMTP; +use Codestriker::Http::UrlBuilder; +use Codestriker::Model::User; + +sub process { + my ($type, $http_input, $http_response) = @_; + + my $query = $http_response->get_query(); + my $url_builder = Codestriker::Http::UrlBuilder->new($query); + + my $email = $http_input->get('email'); + + # Check that the user account doesn't already exist. + if (Codestriker::Model::User->exists($email)) { + my $feedback = "User account $email already exists."; + my $url = $url_builder->create_new_user_url(email => $email, + feedback => $feedback); + print $query->redirect(-URI => $url); + return; + } + + $http_response->generate_header(topic_title=>"Add Account", + reload=>0, cache=>1); + + # Add the new user to the system. + Codestriker::Action::AddNewUser->add_new_user($email, 0, $url_builder); + + # Now indicate that the operation has succeeded. + my $template = Codestriker::Http::Template->new("adduser"); + my $vars = {}; + $template->process($vars); + + $http_response->generate_footer(); +} + +# Add a new user to the system, and send out a challenge/response +# to the specified email address. This method assumes the email +# address does not already exist. +sub add_new_user { + my ($type, $email, $admin, $url_builder) = @_; + + # Add the new user to the system. + Codestriker::Model::User->create($email, $admin); + + # Set a new challenge for this user. + my $user = Codestriker::Model::User->new($email); + my $challenge = $user->create_challenge(); + + # Now send them an email so that they can respond to the + # challenge, and prove they own the specified email address. + my $magic_url = $url_builder->new_password_url(email => $email, + challenge => $challenge); + Codestriker::Action::AddNewUser->_send_email($email, + "New Codestriker Account", + <<"END_EMAIL_TEXT" +You have (or someone impersonating you has) requested a Codestriker +account with this email address: $email. To complete registration, +visit the following link: + +$magic_url + +If you are not the person who made this request, or you wish to cancel +this request, simply ignore and delete this email. +END_EMAIL_TEXT +); + +} + +# Send an email to the end-user with new/update account information. +sub _send_email { + my ($type, $email, $subject, $body) = @_; + + # Send out an email to the user containing the magic URL so that they + # can prove they own this email address. + my $smtp = Net::SMTP->new($Codestriker::mailhost); + defined $smtp || die "Unable to connect to mail server: $!"; + + # Perform SMTP authentication if required. + if (defined $Codestriker::mailuser && $Codestriker::mailuser ne "" && + defined $Codestriker::mailpasswd) { + eval 'use Authen::SASL'; + die "Unable to load Authen::SASL module: $@\n" if $@; + $smtp->auth($Codestriker::mailuser, $Codestriker::mailpasswd); + } + + # Set the from/to addresses. + $smtp->mail("codestriker"); + $smtp->ok() || die "Couldn't set sender to \"codestriker\": $!, " . + $smtp->message(); + $smtp->recipient($email); + $smtp->ok() || die "Couldn't set recipient to \"$email\" $!, " . + $smtp->message(); + + # Set the email text. + $smtp->data(); + $smtp->datasend("From: codestriker\n"); + $smtp->datasend("To: $email\n"); + $smtp->datasend("Subject: $subject\n"); + + # Insert the email body. + $smtp->datasend("\n"); + $smtp->datasend($body); + + # Now send the email. + $smtp->dataend(); + $smtp->ok() || die "Couldn't send email $!, " . $smtp->message(); + $smtp->quit(); + $smtp->ok() || die "Couldn't send email $!, " . $smtp->message(); +} + +1; |
From: <si...@us...> - 2008-09-07 12:20:34
|
User: sits Date: 08/09/07 05:20:32 Modified: t/Http/Method reset-password.t lib/Codestriker/Http/Method UpdatePasswordMethod.pm ResetPasswordMethod.pm lib/Codestriker/Http UrlBuilder.pm Dispatcher.pm Added: template/en/default newpassword.html.tmpl t/Http/Method new-password.t lib/Codestriker/Http/Method NewPasswordMethod.pm lib/Codestriker/Action NewPassword.pm Removed: template/en/default resetpassword.html.tmpl Log: More password methods added in. Index: newpassword.html.tmpl =================================================================== RCS file: newpassword.html.tmpl diff -N newpassword.html.tmpl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ newpassword.html.tmpl 7 Sep 2008 12:20:29 -0000 1.1 @@ -0,0 +1,54 @@ +[%# Screen for the reset password form. #%] + +[% PROCESS header.html.tmpl version = version displaymenu = 1 + closehead = 1 subtitle = "Reset Password" %] +<p> +Please enter your new password. +</p> + +<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> + +<input type="hidden" name="action" value="update_password" /> +<input type="hidden" name="email" value="[% email %]" /> +<input type="hidden" name="challenge" value="[% challenge %]" /> + + <table> + <tr> + <th align="right">New password:</th> + <td> + <input type="password" size="40" name="password"> + </td> + </tr> + <tr> + <th> </th><td> </td> + </tr> + </table> + + <input type="submit" name=".submit" value="Reset Password" /> + +</form> + +<!-- +<hr> + +<p> +If you don't have a Codestriker account, you can create a new account. +</p> + +<hr> + +<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> + <input type="hidden" name="action" value="reset_password"> + <p> + If you have an account, but have forgotten your password, + enter your e-mail address below to generate a new password. + </p> + <input size="40" maxlength="80" name="email"> + <input type="submit" name=".submit2" value="Regenerate Password"> +</form> +--> + +[% PROCESS trailer.html.tmpl %] + +</body> +</html> Index: resetpassword.html.tmpl =================================================================== RCS file: resetpassword.html.tmpl diff -N resetpassword.html.tmpl --- resetpassword.html.tmpl 7 Sep 2008 11:49:42 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,54 +0,0 @@ -[%# Screen for the reset password form. #%] - -[% PROCESS header.html.tmpl version = version displaymenu = 1 - closehead = 1 subtitle = "Reset Password" %] -<p> -Please enter your new password. -</p> - -<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> - -<input type="hidden" name="action" value="update_password" /> -<input type="hidden" name="email" value="[% email %]" /> -<input type="hidden" name="challenge" value="[% challenge %]" /> - - <table> - <tr> - <th align="right">New password:</th> - <td> - <input type="password" size="40" name="password"> - </td> - </tr> - <tr> - <th> </th><td> </td> - </tr> - </table> - - <input type="submit" name=".submit" value="Reset Password" /> - -</form> - -<!-- -<hr> - -<p> -If you don't have a Codestriker account, you can create a new account. -</p> - -<hr> - -<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> - <input type="hidden" name="action" value="reset_password"> - <p> - If you have an account, but have forgotten your password, - enter your e-mail address below to generate a new password. - </p> - <input size="40" maxlength="80" name="email"> - <input type="submit" name=".submit2" value="Regenerate Password"> -</form> ---> - -[% PROCESS trailer.html.tmpl %] - -</body> -</html> Index: reset-password.t =================================================================== RCS file: /cvsroot/codestriker/codestriker/t/Http/Method/reset-password.t,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- reset-password.t 7 Sep 2008 11:49:45 -0000 1.1 +++ reset-password.t 7 Sep 2008 12:20:30 -0000 1.2 @@ -1,7 +1,7 @@ # Tests for the ResetPassword method. use strict; -use Test::More tests => 4; +use Test::More tests => 3; use lib '../../../lib'; use Test::MockObject; @@ -17,14 +17,13 @@ my $url_cgi = Codestriker::Http::Method::ResetPasswordMethod->new($mock_query, 1); my $url_nice = Codestriker::Http::Method::ResetPasswordMethod->new($mock_query, 0); -is($url_cgi->url(email => 'jo...@bl...', - challenge => 'abcdefg'), - $mock_query->url() . '?action=reset_password&email=joe%40bloggs.com&challenge=abcdefg', +is($url_cgi->url(email => 'jo...@bl...'), + $mock_query->url() . '?action=reset_password&email=joe%40bloggs.com', "Reset password URL CGI syntax"); is($url_nice->url(email => 'jo...@bl...', challenge => 'abcdefg'), - $mock_query->url() . '/user/joe%40bloggs.com/password/reset/challenge/abcdefg', + $mock_query->url() . '/user/joe%40bloggs.com/password/reset', "Reset password URL nice syntax"); # Check that the parameters extracted correctly. @@ -33,9 +32,8 @@ $mock_http_input->mock('extract_cgi_parameters', sub { return undef; }); $mock_query->mock('path_info', sub { - return '/user/joe%40bloggs.com/password/reset/challenge/abcdefg'; + return '/user/joe%40bloggs.com/password/reset'; }); $mock_query->mock('param', sub { return undef; }); $url_nice->extract_parameters($mock_http_input); is ($mock_http_input->{email}, 'jo...@bl...', "email nice URL parameter extraction"); -is ($mock_http_input->{challenge}, 'abcdefg', "challenge nice URL parameter extraction"); Index: new-password.t =================================================================== RCS file: new-password.t diff -N new-password.t --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ new-password.t 7 Sep 2008 12:20:30 -0000 1.1 @@ -0,0 +1,41 @@ +# Tests for the NewPassword method. + +use strict; +use Test::More tests => 4; + +use lib '../../../lib'; +use Test::MockObject; +use Codestriker; +use Codestriker::Http::Method::NewPasswordMethod; + +# Create a CGI mock object for these tests. +my $mock_query = Test::MockObject->new(); +$mock_query->mock('url', + sub { 'http://localhost.localdomain/codestriker/codestriker.pl' } ); + +# Create two method objects to test each URL scheme. +my $url_cgi = Codestriker::Http::Method::NewPasswordMethod->new($mock_query, 1); +my $url_nice = Codestriker::Http::Method::NewPasswordMethod->new($mock_query, 0); + +is($url_cgi->url(email => 'jo...@bl...', + challenge => 'abcdefg'), + $mock_query->url() . '?action=new_password&email=joe%40bloggs.com&challenge=abcdefg', + "New password URL CGI syntax"); + +is($url_nice->url(email => 'jo...@bl...', + challenge => 'abcdefg'), + $mock_query->url() . '/user/joe%40bloggs.com/password/new/challenge/abcdefg', + "New password URL nice syntax"); + +# Check that the parameters extracted correctly. +my $mock_http_input = Test::MockObject->new(); +$mock_http_input->{query} = $mock_query; +$mock_http_input->mock('extract_cgi_parameters', sub { return undef; }); +$mock_query->mock('path_info', + sub { + return '/user/joe%40bloggs.com/password/new/challenge/abcdefg'; + }); +$mock_query->mock('param', sub { return undef; }); +$url_nice->extract_parameters($mock_http_input); +is ($mock_http_input->{email}, 'jo...@bl...', "email nice URL parameter extraction"); +is ($mock_http_input->{challenge}, 'abcdefg', "challenge nice URL parameter extraction"); Index: UpdatePasswordMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdatePasswordMethod.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- UpdatePasswordMethod.pm 7 Sep 2008 11:49:45 -0000 1.1 +++ UpdatePasswordMethod.pm 7 Sep 2008 12:20:30 -0000 1.2 @@ -11,7 +11,6 @@ use strict; use Codestriker::Http::Method; -use Codestriker::Action::Login; @Codestriker::Http::Method::UpdatePasswordMethod::ISA = ("Codestriker::Http::Method"); @@ -48,7 +47,7 @@ sub execute { my ($self, $http_input, $http_output) = @_; - Codestriker::Action::ResetPasswordAction->process($http_input, $http_output); +# Codestriker::Action::UpdatePassword->process($http_input, $http_output); } 1; Index: ResetPasswordMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/ResetPasswordMethod.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ResetPasswordMethod.pm 7 Sep 2008 11:49:45 -0000 1.1 +++ ResetPasswordMethod.pm 7 Sep 2008 12:20:30 -0000 1.2 @@ -5,13 +5,12 @@ # This program is free software; you can redistribute it and modify it under # the terms of the GPL. -# Method for going to the reset password form. +# Method for resetting a password. package Codestriker::Http::Method::ResetPasswordMethod; use strict; use Codestriker::Http::Method; -use Codestriker::Action::ResetPassword; @Codestriker::Http::Method::ResetPasswordMethod::ISA = ("Codestriker::Http::Method"); @@ -21,11 +20,10 @@ if ($self->{cgi_style}) { return $self->{url_prefix} . "?action=reset_password" . - "&email=" . CGI::escape($args{email}) . - "&challenge=" . CGI::escape($args{challenge}); + "&email=" . CGI::escape($args{email}); } else { return $self->{url_prefix} . "/user/" . CGI::escape($args{email}) . - "/password/reset/challenge/" . CGI::escape($args{challenge}); + "/password/reset"; } } @@ -37,10 +35,9 @@ if ($self->{cgi_style} && defined $action && $action eq "reset_password") { $http_input->extract_cgi_parameters(); return 1; - } elsif ($path_info =~ m{^/user/.*/password/reset/challenge/}) { + } elsif ($path_info =~ m{^/user/.*/password/reset$}) { $self->_extract_nice_parameters($http_input, - user => 'email', - challenge => 'challenge'); + user => 'email'); return 1; } else { return 0; @@ -50,7 +47,7 @@ sub execute { my ($self, $http_input, $http_output) = @_; - Codestriker::Action::ResetPassword->process($http_input, $http_output); +# Codestriker::Action::UpdatePassword->process($http_input, $http_output); } 1; Index: NewPasswordMethod.pm =================================================================== RCS file: NewPasswordMethod.pm diff -N NewPasswordMethod.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ NewPasswordMethod.pm 7 Sep 2008 12:20:30 -0000 1.1 @@ -0,0 +1,56 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Method for going to the reset password form. + +package Codestriker::Http::Method::NewPasswordMethod; + +use strict; +use Codestriker::Http::Method; +use Codestriker::Action::NewPassword; + +@Codestriker::Http::Method::NewPasswordMethod::ISA = ("Codestriker::Http::Method"); + +# Generate a URL for this method. +sub url() { + my ($self, %args) = @_; + + if ($self->{cgi_style}) { + return $self->{url_prefix} . "?action=new_password" . + "&email=" . CGI::escape($args{email}) . + "&challenge=" . CGI::escape($args{challenge}); + } else { + return $self->{url_prefix} . "/user/" . CGI::escape($args{email}) . + "/password/new/challenge/" . CGI::escape($args{challenge}); + } +} + +sub extract_parameters { + my ($self, $http_input) = @_; + + my $action = $http_input->{query}->param('action'); + my $path_info = $http_input->{query}->path_info(); + if ($self->{cgi_style} && defined $action && $action eq "new_password") { + $http_input->extract_cgi_parameters(); + return 1; + } elsif ($path_info =~ m{^/user/.*/password/new/challenge/}) { + $self->_extract_nice_parameters($http_input, + user => 'email', + challenge => 'challenge'); + return 1; + } else { + return 0; + } +} + +sub execute { + my ($self, $http_input, $http_output) = @_; + + Codestriker::Action::NewPassword->process($http_input, $http_output); +} + +1; Index: UrlBuilder.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/UrlBuilder.pm,v retrieving revision 1.51 retrieving revision 1.52 diff -u -r1.51 -r1.52 --- UrlBuilder.pm 7 Sep 2008 11:49:45 -0000 1.51 +++ UrlBuilder.pm 7 Sep 2008 12:20:31 -0000 1.52 @@ -37,8 +37,9 @@ use Codestriker::Http::Method::UpdateTopicStateMethod; use Codestriker::Http::Method::LoginMethod; use Codestriker::Http::Method::AuthenticateMethod; -use Codestriker::Http::Method::ResetPasswordMethod; +use Codestriker::Http::Method::NewPasswordMethod; use Codestriker::Http::Method::UpdatePasswordMethod; +use Codestriker::Http::Method::ResetPasswordMethod; # Constructor for this class. sub new { @@ -235,10 +236,10 @@ return Codestriker::Http::Method::LoginMethod->new($self->{query})->url(%args); } -# Create the URL for resetting a password. -sub reset_password_url { +# Create the URL for setting a new password. +sub new_password_url { my ($self, %args) = @_; - return Codestriker::Http::Method::ResetPasswordMethod->new($self->{query})->url(%args); + return Codestriker::Http::Method::NewPasswordMethod->new($self->{query})->url(%args); } # Create the URL for updating a password. @@ -247,6 +248,12 @@ return Codestriker::Http::Method::UpdatePasswordMethod->new($self->{query})->url(%args); } +# Create the URL for resetting a password. +sub reset_password_url { + my ($self, %args) = @_; + return Codestriker::Http::Method::ResetPasswordMethod->new($self->{query})->url(%args); +} + # Create the URL for authenticating. sub authenticate_url { my ($self, %args) = @_; Index: Dispatcher.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Dispatcher.pm,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- Dispatcher.pm 7 Sep 2008 11:49:45 -0000 1.12 +++ Dispatcher.pm 7 Sep 2008 12:20:31 -0000 1.13 @@ -40,8 +40,9 @@ use Codestriker::Http::Method::AddProjectMethod; use Codestriker::Http::Method::LoginMethod; use Codestriker::Http::Method::AuthenticateMethod; -use Codestriker::Http::Method::ResetPasswordMethod; +use Codestriker::Http::Method::NewPasswordMethod; use Codestriker::Http::Method::UpdatePasswordMethod; +use Codestriker::Http::Method::ResetPasswordMethod; # Initialise all of the methods that are known to the system. # TODO: add configuration to the parameter. @@ -83,8 +84,9 @@ push @methods, Codestriker::Http::Method::AddProjectMethod->new($query); push @methods, Codestriker::Http::Method::LoginMethod->new($query); push @methods, Codestriker::Http::Method::AuthenticateMethod->new($query); - push @methods, Codestriker::Http::Method::ResetPasswordMethod->new($query); + push @methods, Codestriker::Http::Method::NewPasswordMethod->new($query); push @methods, Codestriker::Http::Method::UpdatePasswordMethod->new($query); + push @methods, Codestriker::Http::Method::ResetPasswordMethod->new($query); $self->{methods} = \@methods; return bless $self, $type; Index: NewPassword.pm =================================================================== RCS file: NewPassword.pm diff -N NewPassword.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ NewPassword.pm 7 Sep 2008 12:20:31 -0000 1.1 @@ -0,0 +1,37 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Action object for displaying the new password page. + +package Codestriker::Action::NewPassword; + +use strict; +use Codestriker::Http::UrlBuilder; + +# Create an appropriate form for entering a new password. +sub process { + my ($type, $http_input, $http_response) = @_; + + my $query = $http_response->get_query(); + + $http_response->generate_header(topic_title=>"New Password", + reload=>0, cache=>1); + + # Target URL to divert the post to. + my $vars = {}; + my $url_builder = Codestriker::Http::UrlBuilder->new($query); + $vars->{'action_url'} = $url_builder->update_password_url(); + $vars->{'challenge'} = $http_input->get('challenge'); + $vars->{'email'} = $http_input->get('email'); + + my $template = Codestriker::Http::Template->new("newpassword"); + $template->process($vars); + + $http_response->generate_footer(); +} + +1; |
From: <si...@us...> - 2008-09-07 11:49:47
|
User: sits Date: 08/09/07 04:49:45 Modified: lib/Codestriker/Http UrlBuilder.pm Method.pm Input.pm Dispatcher.pm Added: template/en/default resetpassword.html.tmpl t/Http/Method update-password.t reset-password.t lib/Codestriker/Http/Method UpdatePasswordMethod.pm ResetPasswordMethod.pm lib/Codestriker/Action ResetPassword.pm Log: Added in support for the ResetPassword and UpdatePassword methods. Index: resetpassword.html.tmpl =================================================================== RCS file: resetpassword.html.tmpl diff -N resetpassword.html.tmpl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ resetpassword.html.tmpl 7 Sep 2008 11:49:42 -0000 1.1 @@ -0,0 +1,54 @@ +[%# Screen for the reset password form. #%] + +[% PROCESS header.html.tmpl version = version displaymenu = 1 + closehead = 1 subtitle = "Reset Password" %] +<p> +Please enter your new password. +</p> + +<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> + +<input type="hidden" name="action" value="update_password" /> +<input type="hidden" name="email" value="[% email %]" /> +<input type="hidden" name="challenge" value="[% challenge %]" /> + + <table> + <tr> + <th align="right">New password:</th> + <td> + <input type="password" size="40" name="password"> + </td> + </tr> + <tr> + <th> </th><td> </td> + </tr> + </table> + + <input type="submit" name=".submit" value="Reset Password" /> + +</form> + +<!-- +<hr> + +<p> +If you don't have a Codestriker account, you can create a new account. +</p> + +<hr> + +<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> + <input type="hidden" name="action" value="reset_password"> + <p> + If you have an account, but have forgotten your password, + enter your e-mail address below to generate a new password. + </p> + <input size="40" maxlength="80" name="email"> + <input type="submit" name=".submit2" value="Regenerate Password"> +</form> +--> + +[% PROCESS trailer.html.tmpl %] + +</body> +</html> Index: update-password.t =================================================================== RCS file: update-password.t diff -N update-password.t --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ update-password.t 7 Sep 2008 11:49:45 -0000 1.1 @@ -0,0 +1,39 @@ +# Tests for the UpdatePassword method. + +use strict; +use Test::More tests => 3; + +use lib '../../../lib'; +use Test::MockObject; +use Codestriker; +use Codestriker::Http::Method::UpdatePasswordMethod; + +# Create a CGI mock object for these tests. +my $mock_query = Test::MockObject->new(); +$mock_query->mock('url', + sub { 'http://localhost.localdomain/codestriker/codestriker.pl' } ); + +# Create two method objects to test each URL scheme. +my $url_cgi = Codestriker::Http::Method::UpdatePasswordMethod->new($mock_query, 1); +my $url_nice = Codestriker::Http::Method::UpdatePasswordMethod->new($mock_query, 0); + +is($url_cgi->url(email => 'jo...@bl...'), + $mock_query->url() . '?action=update_password&email=joe%40bloggs.com', + "Update password URL CGI syntax"); + +is($url_nice->url(email => 'jo...@bl...', + challenge => 'abcdefg'), + $mock_query->url() . '/user/joe%40bloggs.com/password/update', + "Update password URL nice syntax"); + +# Check that the parameters extracted correctly. +my $mock_http_input = Test::MockObject->new(); +$mock_http_input->{query} = $mock_query; +$mock_http_input->mock('extract_cgi_parameters', sub { return undef; }); +$mock_query->mock('path_info', + sub { + return '/user/joe%40bloggs.com/password/update'; + }); +$mock_query->mock('param', sub { return undef; }); +$url_nice->extract_parameters($mock_http_input); +is ($mock_http_input->{email}, 'jo...@bl...', "email nice URL parameter extraction"); Index: reset-password.t =================================================================== RCS file: reset-password.t diff -N reset-password.t --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ reset-password.t 7 Sep 2008 11:49:45 -0000 1.1 @@ -0,0 +1,41 @@ +# Tests for the ResetPassword method. + +use strict; +use Test::More tests => 4; + +use lib '../../../lib'; +use Test::MockObject; +use Codestriker; +use Codestriker::Http::Method::ResetPasswordMethod; + +# Create a CGI mock object for these tests. +my $mock_query = Test::MockObject->new(); +$mock_query->mock('url', + sub { 'http://localhost.localdomain/codestriker/codestriker.pl' } ); + +# Create two method objects to test each URL scheme. +my $url_cgi = Codestriker::Http::Method::ResetPasswordMethod->new($mock_query, 1); +my $url_nice = Codestriker::Http::Method::ResetPasswordMethod->new($mock_query, 0); + +is($url_cgi->url(email => 'jo...@bl...', + challenge => 'abcdefg'), + $mock_query->url() . '?action=reset_password&email=joe%40bloggs.com&challenge=abcdefg', + "Reset password URL CGI syntax"); + +is($url_nice->url(email => 'jo...@bl...', + challenge => 'abcdefg'), + $mock_query->url() . '/user/joe%40bloggs.com/password/reset/challenge/abcdefg', + "Reset password URL nice syntax"); + +# Check that the parameters extracted correctly. +my $mock_http_input = Test::MockObject->new(); +$mock_http_input->{query} = $mock_query; +$mock_http_input->mock('extract_cgi_parameters', sub { return undef; }); +$mock_query->mock('path_info', + sub { + return '/user/joe%40bloggs.com/password/reset/challenge/abcdefg'; + }); +$mock_query->mock('param', sub { return undef; }); +$url_nice->extract_parameters($mock_http_input); +is ($mock_http_input->{email}, 'jo...@bl...', "email nice URL parameter extraction"); +is ($mock_http_input->{challenge}, 'abcdefg', "challenge nice URL parameter extraction"); Index: UpdatePasswordMethod.pm =================================================================== RCS file: UpdatePasswordMethod.pm diff -N UpdatePasswordMethod.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ UpdatePasswordMethod.pm 7 Sep 2008 11:49:45 -0000 1.1 @@ -0,0 +1,54 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Method for updating a password. + +package Codestriker::Http::Method::UpdatePasswordMethod; + +use strict; +use Codestriker::Http::Method; +use Codestriker::Action::Login; + +@Codestriker::Http::Method::UpdatePasswordMethod::ISA = ("Codestriker::Http::Method"); + +# Generate a URL for this method. +sub url() { + my ($self, %args) = @_; + + if ($self->{cgi_style}) { + return $self->{url_prefix} . "?action=update_password" . + "&email=" . CGI::escape($args{email}); + } else { + return $self->{url_prefix} . "/user/" . CGI::escape($args{email}) . + "/password/update"; + } +} + +sub extract_parameters { + my ($self, $http_input) = @_; + + my $action = $http_input->{query}->param('action'); + my $path_info = $http_input->{query}->path_info(); + if ($self->{cgi_style} && defined $action && $action eq "update_password") { + $http_input->extract_cgi_parameters(); + return 1; + } elsif ($path_info =~ m{^/user/.*/password/update$}) { + $self->_extract_nice_parameters($http_input, + user => 'email'); + return 1; + } else { + return 0; + } +} + +sub execute { + my ($self, $http_input, $http_output) = @_; + + Codestriker::Action::ResetPasswordAction->process($http_input, $http_output); +} + +1; Index: ResetPasswordMethod.pm =================================================================== RCS file: ResetPasswordMethod.pm diff -N ResetPasswordMethod.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ResetPasswordMethod.pm 7 Sep 2008 11:49:45 -0000 1.1 @@ -0,0 +1,56 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Method for going to the reset password form. + +package Codestriker::Http::Method::ResetPasswordMethod; + +use strict; +use Codestriker::Http::Method; +use Codestriker::Action::ResetPassword; + +@Codestriker::Http::Method::ResetPasswordMethod::ISA = ("Codestriker::Http::Method"); + +# Generate a URL for this method. +sub url() { + my ($self, %args) = @_; + + if ($self->{cgi_style}) { + return $self->{url_prefix} . "?action=reset_password" . + "&email=" . CGI::escape($args{email}) . + "&challenge=" . CGI::escape($args{challenge}); + } else { + return $self->{url_prefix} . "/user/" . CGI::escape($args{email}) . + "/password/reset/challenge/" . CGI::escape($args{challenge}); + } +} + +sub extract_parameters { + my ($self, $http_input) = @_; + + my $action = $http_input->{query}->param('action'); + my $path_info = $http_input->{query}->path_info(); + if ($self->{cgi_style} && defined $action && $action eq "reset_password") { + $http_input->extract_cgi_parameters(); + return 1; + } elsif ($path_info =~ m{^/user/.*/password/reset/challenge/}) { + $self->_extract_nice_parameters($http_input, + user => 'email', + challenge => 'challenge'); + return 1; + } else { + return 0; + } +} + +sub execute { + my ($self, $http_input, $http_output) = @_; + + Codestriker::Action::ResetPassword->process($http_input, $http_output); +} + +1; Index: UrlBuilder.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/UrlBuilder.pm,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- UrlBuilder.pm 7 Sep 2008 04:49:26 -0000 1.50 +++ UrlBuilder.pm 7 Sep 2008 11:49:45 -0000 1.51 @@ -37,6 +37,8 @@ use Codestriker::Http::Method::UpdateTopicStateMethod; use Codestriker::Http::Method::LoginMethod; use Codestriker::Http::Method::AuthenticateMethod; +use Codestriker::Http::Method::ResetPasswordMethod; +use Codestriker::Http::Method::UpdatePasswordMethod; # Constructor for this class. sub new { @@ -233,6 +235,18 @@ return Codestriker::Http::Method::LoginMethod->new($self->{query})->url(%args); } +# Create the URL for resetting a password. +sub reset_password_url { + my ($self, %args) = @_; + return Codestriker::Http::Method::ResetPasswordMethod->new($self->{query})->url(%args); +} + +# Create the URL for updating a password. +sub update_password_url { + my ($self, %args) = @_; + return Codestriker::Http::Method::UpdatePasswordMethod->new($self->{query})->url(%args); +} + # Create the URL for authenticating. sub authenticate_url { my ($self, %args) = @_; Index: Method.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method.pm,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Method.pm 6 Sep 2008 06:03:56 -0000 1.6 +++ Method.pm 7 Sep 2008 11:49:45 -0000 1.7 @@ -24,7 +24,7 @@ if (defined $cgi_style) { $self->{cgi_style} = $cgi_style; } else { - $self->{cgi_style} = $query->url() =~ /codestriker.pl$/ ? 1 : 0; + $self->{cgi_style} = $query->url() =~ /codestriker.pl/ ? 1 : 0; } # Determine what prefix is required when using relative URLs. Index: Input.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Input.pm,v retrieving revision 1.51 retrieving revision 1.52 diff -u -r1.51 -r1.52 --- Input.pm 6 Sep 2008 00:31:47 -0000 1.51 +++ Input.pm 7 Sep 2008 11:49:45 -0000 1.52 @@ -106,6 +106,8 @@ $self->{selected_comments} = \@selected_comments; $self->{default_to_head} = $query->param('default_to_head'); $self->{email_event} = $query->param('email_event'); + $self->{redirect} = $query->param('redirect'); + $self->{challenge} = $query->param('challenge'); # Set any missing parameters from the cookie. my %cookie = Codestriker::Http::Cookie->get($query); Index: Dispatcher.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Dispatcher.pm,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- Dispatcher.pm 7 Sep 2008 04:49:26 -0000 1.11 +++ Dispatcher.pm 7 Sep 2008 11:49:45 -0000 1.12 @@ -40,6 +40,8 @@ use Codestriker::Http::Method::AddProjectMethod; use Codestriker::Http::Method::LoginMethod; use Codestriker::Http::Method::AuthenticateMethod; +use Codestriker::Http::Method::ResetPasswordMethod; +use Codestriker::Http::Method::UpdatePasswordMethod; # Initialise all of the methods that are known to the system. # TODO: add configuration to the parameter. @@ -81,6 +83,8 @@ push @methods, Codestriker::Http::Method::AddProjectMethod->new($query); push @methods, Codestriker::Http::Method::LoginMethod->new($query); push @methods, Codestriker::Http::Method::AuthenticateMethod->new($query); + push @methods, Codestriker::Http::Method::ResetPasswordMethod->new($query); + push @methods, Codestriker::Http::Method::UpdatePasswordMethod->new($query); $self->{methods} = \@methods; return bless $self, $type; Index: ResetPassword.pm =================================================================== RCS file: ResetPassword.pm diff -N ResetPassword.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ResetPassword.pm 7 Sep 2008 11:49:45 -0000 1.1 @@ -0,0 +1,37 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Action object for displaying the reset password page. + +package Codestriker::Action::ResetPassword; + +use strict; +use Codestriker::Http::UrlBuilder; + +# Create an appropriate form for reseting the password. +sub process { + my ($type, $http_input, $http_response) = @_; + + my $query = $http_response->get_query(); + + $http_response->generate_header(topic_title=>"Reset Password", + reload=>0, cache=>1); + + # Target URL to divert the post to. + my $vars = {}; + my $url_builder = Codestriker::Http::UrlBuilder->new($query); + $vars->{'action_url'} = $url_builder->update_password_url(); + $vars->{'challenge'} = $http_input->get('challenge'); + $vars->{'email'} = $http_input->get('email'); + + my $template = Codestriker::Http::Template->new("resetpassword"); + $template->process($vars); + + $http_response->generate_footer(); +} + +1; |
From: <si...@us...> - 2008-09-07 04:49:28
|
User: sits Date: 08/09/06 21:49:27 Modified: lib/Codestriker/Model User.pm lib/Codestriker/Http/Method LoginMethod.pm AuthenticateMethod.pm lib/Codestriker/Http UrlBuilder.pm Dispatcher.pm bin install.pl Added: template/en/default login.html.tmpl lib/Codestriker/Action Login.pm Log: Now have the example login page in the system. Index: login.html.tmpl =================================================================== RCS file: login.html.tmpl diff -N login.html.tmpl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ login.html.tmpl 7 Sep 2008 04:49:26 -0000 1.1 @@ -0,0 +1,57 @@ +[%# Screen for login form. #%] + +[% PROCESS header.html.tmpl version = version displaymenu = 1 + closehead = 1 subtitle = "Login" %] +<p> +Please enter your email address and password to continue. +</p> + +<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> + +<input type="hidden" name="action" value="authenticate" /> + <table> + <tr> + <th align="right">E-mail address:</th> + <td> + <input size="40" maxlength="80" name="email"> + </td> + </tr> + <tr> + <th align="right">Password:</th> + <td> + <input type="password" size="40" name="password"> + </td> + </tr> + <tr> + <th> </th><td> </td> + </tr> + </table> + + <input type="submit" name=".submit" value="Log in" /> + +</form> + +<!-- +<hr> + +<p> +If you don't have a Codestriker account, you can create a new account. +</p> + +<hr> + +<form method="post" enctype="application/x-www-form-urlencoded" action="[% action_url %]"> + <input type="hidden" name="action" value="reset_password"> + <p> + If you have an account, but have forgotten your password, + enter your e-mail address below to generate a new password. + </p> + <input size="40" maxlength="80" name="email"> + <input type="submit" name=".submit2" value="Regenerate Password"> +</form> +--> + +[% PROCESS trailer.html.tmpl %] + +</body> +</html> Index: User.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Model/User.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- User.pm 6 Sep 2008 11:33:06 -0000 1.2 +++ User.pm 7 Sep 2008 04:49:26 -0000 1.3 @@ -24,15 +24,16 @@ my $dbh = Codestriker::DB::DBI->get_connection(); eval { my $select_user = - $dbh->prepare_cached('SELECT password_hash, admin ' . + $dbh->prepare_cached('SELECT password_hash, challenge, admin ' . 'FROM usertable ' . 'WHERE email = ?'); $select_user->execute($email); - my ($password_hash, $admin) = $select_user->fetchrow_array(); + my ($password_hash, $challenge, $admin) = $select_user->fetchrow_array(); $select_user->finish(); $self->{password_hash} = $password_hash; + $self->{challenge} = $challenge; $self->{admin} = $admin; }; my $success = $@ ? 0 : 1; @@ -45,11 +46,41 @@ return $self; } +# Determine if the specific user already exists. +sub exists { + my ($type, $email) = @_; + + # Obtain a database connection. + my $dbh = Codestriker::DB::DBI->get_connection(); + + my $count = 0; + eval { + my $select_email = + $dbh->prepare_cached('SELECT COUNT(*) FROM usertable ' . + 'WHERE email = ?'); + $select_email->execute($email); + ($count) = $select_email->fetchrow_array(); + $select_email->finish(); + }; + my $success = $@ ? 0 : 1; + + Codestriker::DB::DBI->release_connection($dbh, $success); + die $dbh->errstr unless $success; + + return $count; +} + # Update an existing user record with a new password. sub update_password { my ($self, $new_password) = @_; - my $password_hash = _hash_password($new_password); + $self->update_password_hash(_hash_password($new_password)); +} + +# Update an existing user record with a new password_hash. +sub update_password_hash { + my ($self, $password_hash) = @_; + my $dbh = Codestriker::DB::DBI->get_connection(); eval { my $update_user = @@ -113,28 +144,33 @@ return $new_password; } -# Determine if the specific user already exists. -sub exists { - my ($type, $email) = @_; +# Create a challenge key into the user table for supporting the +# case where a user can update their password via a +# challenge/response protocol. +sub create_challenge { + my ($self, $email) = @_; # Obtain a database connection. my $dbh = Codestriker::DB::DBI->get_connection(); - my $count = 0; + # Create a random challenge for the user. + my $new_password = _create_random_password(); + my $challenge = _hash_password($new_password); + + # Set this challenge into the user record. eval { - my $select_email = - $dbh->prepare_cached('SELECT COUNT(*) FROM usertable ' . - 'WHERE email = ?'); - $select_email->execute($email); - ($count) = $select_email->fetchrow_array(); - $select_email->finish(); + my $challenge_update = + $dbh->prepare_cached('UPDATE usertable ' . + 'SET challenge = ? ' . + 'WHERE email = ? '); + $challenge_update->execute($self->{email}, $challenge); }; my $success = $@ ? 0 : 1; Codestriker::DB::DBI->release_connection($dbh, $success); die $dbh->errstr unless $success; - return $count; + return $challenge; } # Method for producing a hash from a password. Index: LoginMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/LoginMethod.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- LoginMethod.pm 7 Sep 2008 03:44:15 -0000 1.1 +++ LoginMethod.pm 7 Sep 2008 04:49:26 -0000 1.2 @@ -11,6 +11,7 @@ use strict; use Codestriker::Http::Method; +use Codestriker::Action::Login; @Codestriker::Http::Method::LoginMethod::ISA = ("Codestriker::Http::Method"); @@ -50,7 +51,7 @@ sub execute { my ($self, $http_input, $http_output) = @_; - Codestriker::Action::LoginAction->process($http_input, $http_output); + Codestriker::Action::Login->process($http_input, $http_output); } 1; Index: AuthenticateMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/AuthenticateMethod.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- AuthenticateMethod.pm 7 Sep 2008 03:44:15 -0000 1.1 +++ AuthenticateMethod.pm 7 Sep 2008 04:49:26 -0000 1.2 @@ -44,7 +44,7 @@ sub execute { my ($self, $http_input, $http_output) = @_; - Codestriker::Action::AuthenticateAction->process($http_input, $http_output); + Codestriker::Action::Authenticate->process($http_input, $http_output); } 1; Index: UrlBuilder.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/UrlBuilder.pm,v retrieving revision 1.49 retrieving revision 1.50 diff -u -r1.49 -r1.50 --- UrlBuilder.pm 6 Sep 2008 06:03:56 -0000 1.49 +++ UrlBuilder.pm 7 Sep 2008 04:49:26 -0000 1.50 @@ -35,6 +35,8 @@ use Codestriker::Http::Method::UpdateTopicMetricsMethod; use Codestriker::Http::Method::UpdateCommentMetricsMethod; use Codestriker::Http::Method::UpdateTopicStateMethod; +use Codestriker::Http::Method::LoginMethod; +use Codestriker::Http::Method::AuthenticateMethod; # Constructor for this class. sub new { @@ -225,4 +227,17 @@ return Codestriker::Http::Method::DownloadMetricsMethod->new($self->{query})->url(); } +# Create the URL for going to the login page. +sub login_url { + my ($self, %args) = @_; + return Codestriker::Http::Method::LoginMethod->new($self->{query})->url(%args); +} + +# Create the URL for authenticating. +sub authenticate_url { + my ($self, %args) = @_; + return Codestriker::Http::Method::AuthenticateMethod->new($self->{query})->url(%args); +} + + 1; Index: Dispatcher.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Dispatcher.pm,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- Dispatcher.pm 6 Sep 2008 00:31:47 -0000 1.10 +++ Dispatcher.pm 7 Sep 2008 04:49:26 -0000 1.11 @@ -38,6 +38,8 @@ use Codestriker::Http::Method::ViewMetricsMethod; use Codestriker::Http::Method::UpdateTopicStateMethod; use Codestriker::Http::Method::AddProjectMethod; +use Codestriker::Http::Method::LoginMethod; +use Codestriker::Http::Method::AuthenticateMethod; # Initialise all of the methods that are known to the system. # TODO: add configuration to the parameter. @@ -77,6 +79,8 @@ push @methods, Codestriker::Http::Method::ViewMetricsMethod->new($query); push @methods, Codestriker::Http::Method::UpdateTopicStateMethod->new($query); push @methods, Codestriker::Http::Method::AddProjectMethod->new($query); + push @methods, Codestriker::Http::Method::LoginMethod->new($query); + push @methods, Codestriker::Http::Method::AuthenticateMethod->new($query); $self->{methods} = \@methods; return bless $self, $type; @@ -87,6 +91,9 @@ sub dispatch { my ($self, $http_input, $http_output) = @_; + # TODO: put login in here which redirects to the login form + # if appropriate with the full URL in the redirect parameter. + foreach my $method ( @{$self->{methods}} ) { if ($method->extract_parameters($http_input)) { $method->execute($http_input, $http_output); Index: Login.pm =================================================================== RCS file: Login.pm diff -N Login.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Login.pm 7 Sep 2008 04:49:27 -0000 1.1 @@ -0,0 +1,35 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Action object for displaying the login page. + +package Codestriker::Action::Login; + +use strict; +use Codestriker::Http::UrlBuilder; + +# Create an appropriate form for logging in. +sub process { + my ($type, $http_input, $http_response) = @_; + + my $query = $http_response->get_query(); + + $http_response->generate_header(topic_title=>"Login", + reload=>0, cache=>1); + + # Target URL to divert the post to. + my $vars = {}; + my $url_builder = Codestriker::Http::UrlBuilder->new($query); + $vars->{'action_url'} = $url_builder->authenticate_url(); + + my $template = Codestriker::Http::Template->new("login"); + $template->process($vars); + + $http_response->generate_footer(); +} + +1; Index: install.pl =================================================================== RCS file: /cvsroot/codestriker/codestriker/bin/install.pl,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- install.pl 6 Sep 2008 11:33:06 -0000 1.24 +++ install.pl 7 Sep 2008 04:49:27 -0000 1.25 @@ -579,6 +579,7 @@ table(name => "usertable", columns => [col(name=>"email", type=>$VARCHAR, length=>200, pk=>1), col(name=>"password_hash", type=>$VARCHAR, length=>128), + col(name=>"challenge", type=>$VARCHAR, length=>128, mandatory=>0), col(name=>"admin", type=>$INT16) ], indexes => []); @@ -1071,12 +1072,14 @@ # Now create any admin users, if necessary. $dbh->{PrintError} = 1; +my $user_added = 0; if (defined $Codestriker::admin_users) { foreach my $admin_user (@{ $Codestriker::admin_users }) { if (!Codestriker::Model::User->exists($admin_user)) { print "Creating admin user $admin_user...\n"; Codestriker::Model::User->create($admin_user, 1); # TODO: consider sending email with password details. + $user_added = 1; print "Done\n"; } else { # Existing user, check if they are an admin already. @@ -1084,11 +1087,13 @@ if (! $user->{admin}) { print "Upgrading non-admin user $admin_user to admin...\n"; $user->update_admin(1); + $user_added = 1; print "Done\n"; } } } } +$database->commit() if $user_added; # Now generate the contents of the codestriker.pl file, with the appropriate # configuration details set (basically, the location of the lib dir). |
From: <si...@us...> - 2008-09-07 03:44:17
|
User: sits Date: 08/09/06 20:44:15 Added: t/Http/Method login.t authenticate.t lib/Codestriker/Http/Method LoginMethod.pm AuthenticateMethod.pm Log: New methods for handling the login form, and actual authentication. Index: login.t =================================================================== RCS file: login.t diff -N login.t --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ login.t 7 Sep 2008 03:44:15 -0000 1.1 @@ -0,0 +1,41 @@ +# Tests for the Login method. + +use strict; +use Test::More tests => 4; + +use lib '../../../lib'; +use Test::MockObject; +use Codestriker; +use Codestriker::Http::Method::LoginMethod; + +# Create a CGI mock object for these tests. +my $mock_query = Test::MockObject->new(); +$mock_query->mock('url', + sub { 'http://localhost.localdomain/codestriker/codestriker.pl' } ); + +# Create two method objects to test each URL scheme. +my $url_cgi = Codestriker::Http::Method::LoginMethod->new($mock_query, 1); +my $url_nice = Codestriker::Http::Method::LoginMethod->new($mock_query, 0); + +is($url_cgi->url(feedback => 'Incorrect password', + redirect => 'http://zot.com/zot.pl?action=blah¶m=10'), + $mock_query->url() . '?action=login&redirect=http%3A%2F%2Fzot.com%2Fzot.pl%3Faction%3Dblah%26param%3D10&feedback=Incorrect%20password', + "Login URL CGI syntax"); + +is($url_nice->url(feedback => 'Incorrect password', + redirect => 'http://zot.com/zot.pl?action=blah¶m=10'), + $mock_query->url() . '/login/form/redirect/http%3A%2F%2Fzot.com%2Fzot.pl%3Faction%3Dblah%26param%3D10/feedback/Incorrect%20password', + "Login URL nice syntax"); + +# Check that the parameters extracted correctly. +my $mock_http_input = Test::MockObject->new(); +$mock_http_input->{query} = $mock_query; +$mock_http_input->mock('extract_cgi_parameters', sub { return undef; }); +$mock_query->mock('path_info', + sub { + return '/login/form/redirect/http%3A%2F%2Fzot.com%2Fzot.pl%3Faction%3Dblah%26param%3D10/feedback/Incorrect%20password'; + }); +$mock_query->mock('param', sub { return undef; }); +$url_nice->extract_parameters($mock_http_input); +is ($mock_http_input->{redirect}, 'http://zot.com/zot.pl?action=blah¶m=10', "redirect nice URL parameter extraction"); +is ($mock_http_input->{feedback}, 'Incorrect password', "feedback nice URL parameter extraction"); Index: authenticate.t =================================================================== RCS file: authenticate.t diff -N authenticate.t --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ authenticate.t 7 Sep 2008 03:44:15 -0000 1.1 @@ -0,0 +1,23 @@ +# Tests for the Authenticate method. + +use strict; +use Test::More tests => 2; + +use lib '../../../lib'; +use Test::MockObject; +use Codestriker; +use Codestriker::Http::Method::AuthenticateMethod; + +# Create a CGI mock object for these tests. +my $mock_query = Test::MockObject->new(); +$mock_query->mock('url', + sub { 'http://localhost.localdomain/codestriker/codestriker.pl' } ); + +# Create two method objects to test each URL scheme. +my $url_cgi = Codestriker::Http::Method::AuthenticateMethod->new($mock_query, 1); +my $url_nice = Codestriker::Http::Method::AuthenticateMethod->new($mock_query, 0); + +is($url_cgi->url(), $mock_query->url() . '?action=authenticate', + "Authenticate URL CGI syntax"); +is($url_nice->url(), $mock_query->url() . '/login/authenticate', + "Authenticate URL nice syntax"); Index: LoginMethod.pm =================================================================== RCS file: LoginMethod.pm diff -N LoginMethod.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ LoginMethod.pm 7 Sep 2008 03:44:15 -0000 1.1 @@ -0,0 +1,56 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Method for going to the login form. + +package Codestriker::Http::Method::LoginMethod; + +use strict; +use Codestriker::Http::Method; + +@Codestriker::Http::Method::LoginMethod::ISA = ("Codestriker::Http::Method"); + +# Generate a URL for this method. +sub url() { + my ($self, %args) = @_; + + if ($self->{cgi_style}) { + return $self->{url_prefix} . "?action=login" . + (defined $args{redirect} ? "&redirect=" . CGI::escape($args{redirect}) : "") . + (defined $args{feedback} ? "&feedback=" . CGI::escape($args{feedback}) : ""); + } else { + return $self->{url_prefix} . "/login/form" . + (defined $args{redirect} ? "/redirect/" . CGI::escape($args{redirect}) : "") . + (defined $args{feedback} ? "/feedback/" . CGI::escape($args{feedback}) : ""); + } +} + +sub extract_parameters { + my ($self, $http_input) = @_; + + my $action = $http_input->{query}->param('action'); + my $path_info = $http_input->{query}->path_info(); + if ($self->{cgi_style} && defined $action && $action eq "login") { + $http_input->extract_cgi_parameters(); + return 1; + } elsif ($path_info =~ m{^/login/form}) { + $self->_extract_nice_parameters($http_input, + redirect => 'redirect', + feedback => 'feedback'); + return 1; + } else { + return 0; + } +} + +sub execute { + my ($self, $http_input, $http_output) = @_; + + Codestriker::Action::LoginAction->process($http_input, $http_output); +} + +1; Index: AuthenticateMethod.pm =================================================================== RCS file: AuthenticateMethod.pm diff -N AuthenticateMethod.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ AuthenticateMethod.pm 7 Sep 2008 03:44:15 -0000 1.1 @@ -0,0 +1,50 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Method for authenticating a user. + +package Codestriker::Http::Method::AuthenticateMethod; + +use strict; +use Codestriker::Http::Method; + +@Codestriker::Http::Method::AuthenticateMethod::ISA = ("Codestriker::Http::Method"); + +# Generate a URL for this method. +sub url() { + my ($self, %args) = @_; + + if ($self->{cgi_style}) { + return $self->{url_prefix} . "?action=authenticate"; + } else { + return $self->{url_prefix} . "/login/authenticate"; + } +} + +sub extract_parameters { + my ($self, $http_input) = @_; + + my $action = $http_input->{query}->param('action'); + my $path_info = $http_input->{query}->path_info(); + if ($self->{cgi_style} && defined $action && $action eq "authenticate") { + $http_input->extract_cgi_parameters(); + return 1; + } elsif ($path_info =~ m{^/login/authenticate}) { + $self->_extract_nice_parameters($http_input); + return 1; + } else { + return 0; + } +} + +sub execute { + my ($self, $http_input, $http_output) = @_; + + Codestriker::Action::AuthenticateAction->process($http_input, $http_output); +} + +1; |
From: <si...@us...> - 2008-09-06 11:33:07
|
User: sits Date: 08/09/06 04:33:06 Modified: lib/Codestriker/Model User.pm bin install.pl . codestriker.conf Log: Also handle situation here an "admin upgrade" occurs for an existing user. Index: User.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Model/User.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- User.pm 6 Sep 2008 11:12:31 -0000 1.1 +++ User.pm 6 Sep 2008 11:33:06 -0000 1.2 @@ -45,6 +45,44 @@ return $self; } +# Update an existing user record with a new password. +sub update_password { + my ($self, $new_password) = @_; + + my $password_hash = _hash_password($new_password); + my $dbh = Codestriker::DB::DBI->get_connection(); + eval { + my $update_user = + $dbh->prepare_cached('UPDATE usertable SET password_hash = ? ' . + 'WHERE email = ?'); + $update_user->execute($password_hash, $self->{email}); + }; + my $success = $@ ? 0 : 1; + + Codestriker::DB::DBI->release_connection($dbh, $success); + die $dbh->errstr unless $success; + + $self->{password_hash} = $password_hash; +} + +# Update an existing user record with new admin status. +sub update_admin { + my ($self, $new_admin) = @_; + + my $dbh = Codestriker::DB::DBI->get_connection(); + eval { + my $update_user = + $dbh->prepare_cached('UPDATE usertable SET admin = ? ' . + 'WHERE email = ?'); + $update_user->execute($new_admin, $self->{email}); + }; + my $success = $@ ? 0 : 1; + + Codestriker::DB::DBI->release_connection($dbh, $success); + die $dbh->errstr unless $success; + + $self->{admin} = $new_admin; +} # Create a new user into the database with all of the specified properties. # Return the new password which has been assigned to the user. Index: install.pl =================================================================== RCS file: /cvsroot/codestriker/codestriker/bin/install.pl,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- install.pl 6 Sep 2008 11:12:31 -0000 1.23 +++ install.pl 6 Sep 2008 11:33:06 -0000 1.24 @@ -55,6 +55,7 @@ eval("use Codestriker::FileParser::UnknownFormat"); eval("use Codestriker::Model::File"); eval("use Codestriker::Model::User"); +use Codestriker::Model::User; # Set this variables, to avoid compilation warnings below. $Codestriker::COMMENT_SUBMITTED = 0; @@ -1077,6 +1078,14 @@ Codestriker::Model::User->create($admin_user, 1); # TODO: consider sending email with password details. print "Done\n"; + } else { + # Existing user, check if they are an admin already. + my $user = Codestriker::Model::User->new($admin_user); + if (! $user->{admin}) { + print "Upgrading non-admin user $admin_user to admin...\n"; + $user->update_admin(1); + print "Done\n"; + } } } } Index: codestriker.conf =================================================================== RCS file: /cvsroot/codestriker/codestriker/codestriker.conf,v retrieving revision 1.105 retrieving revision 1.106 diff -u -r1.105 -r1.106 --- codestriker.conf 6 Sep 2008 11:12:31 -0000 1.105 +++ codestriker.conf 6 Sep 2008 11:33:06 -0000 1.106 @@ -38,9 +38,9 @@ # be able to create/edit/delete projects. If no admin user is defined # then no login system will be used, and all users will be effectively # admin users. -#$admin_users = [ 'dav...@gm...' ]; +$admin_users = [ 'dav...@gm...' ]; #$admin_users = [ 'dav...@gm...', 'si...@us...' ]; -$admin_users = []; +#$admin_users = []; # Location of the mailing host. This is used when sending out codestriker # comments. |
From: <si...@us...> - 2008-09-06 11:12:33
|
User: sits Date: 08/09/06 04:12:31 Modified: bin install.pl . codestriker.conf Added: lib/Codestriker/Model User.pm Log: Initial implementation of the user model object. Also added in a configuration variable $admn_users into codestriker.conf to specify which users are admin. These will be created automatically when install.pl is run. Index: User.pm =================================================================== RCS file: User.pm diff -N User.pm --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ User.pm 6 Sep 2008 11:12:31 -0000 1.1 @@ -0,0 +1,131 @@ +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# Model object for handling user data. + +package Codestriker::Model::User; + +use strict; + +use Codestriker::DB::DBI; + +# Create a User object from an existing record in the database. +sub new { + my ($class, $email) = @_; + my $self = {}; + + $self->{email} = $email; + + # Retrieve the specific user record. + my $dbh = Codestriker::DB::DBI->get_connection(); + eval { + my $select_user = + $dbh->prepare_cached('SELECT password_hash, admin ' . + 'FROM usertable ' . + 'WHERE email = ?'); + $select_user->execute($email); + + my ($password_hash, $admin) = $select_user->fetchrow_array(); + $select_user->finish(); + + $self->{password_hash} = $password_hash; + $self->{admin} = $admin; + }; + my $success = $@ ? 0 : 1; + + Codestriker::DB::DBI->release_connection($dbh, $success); + die $dbh->errstr unless $success; + + # Return the user record found. + bless $self, $class; + return $self; +} + + +# Create a new user into the database with all of the specified properties. +# Return the new password which has been assigned to the user. +sub create { + my ($type, $email, $admin) = @_; + + # Obtain a database connection. + my $dbh = Codestriker::DB::DBI->get_connection(); + + # Create a random password for the new user. + my $new_password = _create_random_password(); + my $password_hash = _hash_password($new_password); + + # Insert the row into the database. + eval { + my $insert_user = + $dbh->prepare_cached('INSERT INTO usertable (email, password_hash, admin) ' . + 'VALUES (?, ?, ?)'); + + $insert_user->execute($email, $password_hash, $admin); + }; + my $success = $@ ? 0 : 1; + + Codestriker::DB::DBI->release_connection($dbh, $success); + die $dbh->errstr unless $success; + + # Return the password that was created. + return $new_password; +} + +# Determine if the specific user already exists. +sub exists { + my ($type, $email) = @_; + + # Obtain a database connection. + my $dbh = Codestriker::DB::DBI->get_connection(); + + my $count = 0; + eval { + my $select_email = + $dbh->prepare_cached('SELECT COUNT(*) FROM usertable ' . + 'WHERE email = ?'); + $select_email->execute($email); + ($count) = $select_email->fetchrow_array(); + $select_email->finish(); + }; + my $success = $@ ? 0 : 1; + + Codestriker::DB::DBI->release_connection($dbh, $success); + die $dbh->errstr unless $success; + + return $count; +} + +# Method for producing a hash from a password. +sub _hash_password { + my ($password) = @_; + + # List of characters that can be used for the salt. + my @salt_characters = ( '.', '/', 'A'..'Z', 'a'..'z', '0' ..'9' ); + + # Generate the salt. Generate an 8 character value in case we are on + # a system which uses MD5 digests (48 bit - 6 * 8). Older systems just + # use the first two characters. + my $salt = ''; + for (my $i = 0; $i < 8; $i++) { + $salt .= $salt_characters[rand(64)]; + } + + # Crypt the password. + my $cryptedpassword = crypt($password, $salt); + + # Return the crypted password. + return $cryptedpassword; + } + +# Method for creating a random password consisting of alphanumeric +# characters. +sub _create_random_password { + my @password_characters = ( 'A'..'Z', 'a'..'z', '0' ..'9' ); + return join("", map{ $password_characters[rand 62] } (1..8)); +} + +1; Index: install.pl =================================================================== RCS file: /cvsroot/codestriker/codestriker/bin/install.pl,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- install.pl 6 Sep 2008 00:31:50 -0000 1.22 +++ install.pl 6 Sep 2008 11:12:31 -0000 1.23 @@ -54,6 +54,7 @@ eval("use Codestriker::FileParser::Parser"); eval("use Codestriker::FileParser::UnknownFormat"); eval("use Codestriker::Model::File"); +eval("use Codestriker::Model::User"); # Set this variables, to avoid compilation warnings below. $Codestriker::COMMENT_SUBMITTED = 0; @@ -572,6 +573,15 @@ indexes => [dbindex(name=>"project_name_idx", column_names=>["name"])]); +# This table records all users which are present in the system. +my $user_table = + table(name => "usertable", + columns => [col(name=>"email", type=>$VARCHAR, length=>200, pk=>1), + col(name=>"password_hash", type=>$VARCHAR, length=>128), + col(name=>"admin", type=>$INT16) + ], + indexes => []); + # Add all of the Codestriker tables into an array. my @tables = (); push @tables, $topic_table; @@ -589,6 +599,7 @@ push @tables, $topicfile_table; push @tables, $delta_table; push @tables, $project_table; +push @tables, $user_table; # Move a table into table_old, create the table with the new definitions, # and create the indexes. @@ -1057,7 +1068,18 @@ print "Failed because of $@\n"; } +# Now create any admin users, if necessary. $dbh->{PrintError} = 1; +if (defined $Codestriker::admin_users) { + foreach my $admin_user (@{ $Codestriker::admin_users }) { + if (!Codestriker::Model::User->exists($admin_user)) { + print "Creating admin user $admin_user...\n"; + Codestriker::Model::User->create($admin_user, 1); + # TODO: consider sending email with password details. + print "Done\n"; + } + } +} # Now generate the contents of the codestriker.pl file, with the appropriate # configuration details set (basically, the location of the lib dir). Index: codestriker.conf =================================================================== RCS file: /cvsroot/codestriker/codestriker/codestriker.conf,v retrieving revision 1.104 retrieving revision 1.105 diff -u -r1.104 -r1.105 --- codestriker.conf 6 Sep 2008 03:31:05 -0000 1.104 +++ codestriker.conf 6 Sep 2008 11:12:31 -0000 1.105 @@ -33,6 +33,15 @@ #$dbpasswd = 'manager'; $dbpasswd = 'cspasswd'; +# Email addresses of admin users for this installation. Admin users +# have unrestricted access to the system. Non-admin users will not +# be able to create/edit/delete projects. If no admin user is defined +# then no login system will be used, and all users will be effectively +# admin users. +#$admin_users = [ 'dav...@gm...' ]; +#$admin_users = [ 'dav...@gm...', 'si...@us...' ]; +$admin_users = []; + # Location of the mailing host. This is used when sending out codestriker # comments. $mailhost = 'localhost'; |
From: <si...@us...> - 2008-09-06 06:03:58
|
User: sits Date: 08/09/05 23:03:57 Modified: template/en/default createtopic.html.tmpl t/Http/Method update-topic-states.t lib/Codestriker/Http UrlBuilder.pm Response.pm Method.pm lib/Codestriker/Action CreateTopic.pm Log: Changes so that create topic now works under the nice URL structure. Index: createtopic.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/createtopic.html.tmpl,v retrieving revision 1.58 retrieving revision 1.59 diff -u -r1.58 -r1.59 --- createtopic.html.tmpl 31 Aug 2008 12:02:12 -0000 1.58 +++ createtopic.html.tmpl 6 Sep 2008 06:03:56 -0000 1.59 @@ -20,7 +20,8 @@ <p> [% END %] -<FORM METHOD="post" ENCTYPE="multipart/form-data" ACCEPT-CHARSET="UTF-8" ACTION="[% action_url %]"> +<FORM NAME="createtopicform" METHOD="post" ENCTYPE="multipart/form-data" ACCEPT-CHARSET="UTF-8" action="[% action_url %]" + ONSUBMIT="document.createtopicform.action = '[% action_url %]/project/' + document.createtopicform.elements['projectid'].options[document.createtopicform.elements['projectid'].selectedIndex].value + '/topics/add';"> <INPUT TYPE="hidden" NAME="action" VALUE="submit_new_topic" /> <INPUT TYPE="hidden" NAME="obsoletes" VALUE="[% obsoletes %]" /> Index: update-topic-states.t =================================================================== RCS file: /cvsroot/codestriker/codestriker/t/Http/Method/update-topic-states.t,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- update-topic-states.t 6 Sep 2008 03:31:07 -0000 1.3 +++ update-topic-states.t 6 Sep 2008 06:03:56 -0000 1.4 @@ -1,7 +1,7 @@ # Tests for the UpdateTopicStates method. use strict; -use Test::More tests => 3; +use Test::More tests => 2; use lib '../../../lib'; use Test::MockObject; @@ -35,5 +35,3 @@ }); $mock_query->mock('param', sub { return undef; }); $url_nice->extract_parameters($mock_http_input); - - Index: UrlBuilder.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/UrlBuilder.pm,v retrieving revision 1.48 retrieving revision 1.49 diff -u -r1.48 -r1.49 --- UrlBuilder.pm 6 Sep 2008 03:31:07 -0000 1.48 +++ UrlBuilder.pm 6 Sep 2008 06:03:56 -0000 1.49 @@ -42,7 +42,6 @@ my $self = {}; $self->{query} = $query; - $self->{cgi_style} = defined $Codestriker::cgi_style ? $Codestriker::cgi_style : 1; # Determine what prefix is required when using relative URLs. # Unfortunately, Netcsape 4.x does things differently to everyone Index: Response.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Response.pm,v retrieving revision 1.52 retrieving revision 1.53 diff -u -r1.52 -r1.53 --- Response.pm 6 Sep 2008 00:31:47 -0000 1.52 +++ Response.pm 6 Sep 2008 06:03:56 -0000 1.53 @@ -223,10 +223,10 @@ } else { # Use the default CSS file. $codestriker_css = $query->url(); - if (! defined $Codestriker::cgi_style || $Codestriker::cgi_style) { + if ($query->url() =~ /codestriker.pl$/) { $codestriker_css =~ s#/[^/]+?/codestriker\.pl#/codestrikerhtml/codestriker.css#; } else { - $codestriker_css = $query->url() . "/html/codestriker.css"; + $codestriker_css = $query->url() . "html/codestriker.css"; } } Index: Method.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Method.pm 6 Sep 2008 00:31:47 -0000 1.5 +++ Method.pm 6 Sep 2008 06:03:56 -0000 1.6 @@ -22,9 +22,9 @@ # Determine what style URLs are being used. if (defined $cgi_style) { - $self->{cgoi_style} = $cgi_style; + $self->{cgi_style} = $cgi_style; } else { - $self->{cgi_style} = $query =~ /codestriker.pl$/ ? 1 : 0; + $self->{cgi_style} = $query->url() =~ /codestriker.pl$/ ? 1 : 0; } # Determine what prefix is required when using relative URLs. Index: CreateTopic.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/CreateTopic.pm,v retrieving revision 1.35 retrieving revision 1.36 diff -u -r1.35 -r1.36 --- CreateTopic.pm 6 Sep 2008 00:31:45 -0000 1.35 +++ CreateTopic.pm 6 Sep 2008 06:03:56 -0000 1.36 @@ -42,8 +42,8 @@ $vars->{'doc_url'} = $url_builder->doc_url(); $vars->{'search_url'} = $url_builder->search_url(); - # TODO: fix this once create topic is only done within context of a project. - $vars->{'action_url'} = $url_builder->add_topic_url(projectid => 0); + # Set this as the base URL for the form to use. + $vars->{'action_url'} = $query->url(); # Retrieve the email, reviewers, cc, repository and projectid from # the cookie. |
From: <si...@us...> - 2008-09-06 03:31:09
|
User: sits Date: 08/09/05 20:31:08 Modified: . codestriker.conf bin codestriker.pl.base lib/Codestriker/Action ListTopics.pm lib/Codestriker/Http UrlBuilder.pm lib/Codestriker/Http/Method UpdateTopicStateMethod.pm t/Http/Method update-topic-states.t template/en/default listtopics.html.tmpl Log: Got the update multiple topic states action working again. Index: codestriker.conf =================================================================== RCS file: /cvsroot/codestriker/codestriker/codestriker.conf,v retrieving revision 1.103 retrieving revision 1.104 diff -u -r1.103 -r1.104 --- codestriker.conf 6 Sep 2008 00:31:51 -0000 1.103 +++ codestriker.conf 6 Sep 2008 03:31:05 -0000 1.104 @@ -102,7 +102,7 @@ # Indicate what style URLs to support. The default is CGI-style URLs. Set # this value to 0 for "nicer" URLs. -#$cgi_style = 0; +#$cgi_style = 1; # Valid repositories which may be selected at the create topic screen. # The order shown here is the order presented in the option list. Most Index: codestriker.pl.base =================================================================== RCS file: /cvsroot/codestriker/codestriker/bin/codestriker.pl.base,v retrieving revision 1.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- codestriker.pl.base 6 Sep 2008 00:31:50 -0000 1.29 +++ codestriker.pl.base 6 Sep 2008 03:31:06 -0000 1.30 @@ -1,141 +1,140 @@ - [% hash_ex_line %] +[% hash_ex_line %] - [% scary_warning %] +[% scary_warning %] - ############################################################################### - # Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. - # si...@us... - # - # This program is free software; you can redistribute it and modify it under - # the terms of the GPL. - - # This is the top level package which receives all HTTP requests, and - # delegates it to the appropriate Action module. - - require 5.008_0; - - # Set this to the location of the Codestriker libraries on your system. - # Ideally, this should be done in the apache configs, but trying to do this - # in an easy way for Apache1/Apache2 with/without mod_perl with/without taint - # checking turned out to be a major headache. For mod_perl, setting this - # ensures the first time Codestriker is loaded, it can be compiled properly, - # even if @INC is blatted later. Also note all the use declarations below - # effectively "pre-load" all of the Codestriker modules in the system, as the - # modules below load all of their supporting modules. That is why the - # template plugins are "pre-loaded" here. - [% scmbug_lib %] - [% codestriker_lib %] - - use strict; - - use CGI qw/:standard :html3/; - use CGI::Carp 'fatalsToBrowser'; - - use Codestriker; - use Codestriker::Http::Input; - use Codestriker::Http::Response; - use Codestriker::Http::Dispatcher; - use Codestriker::Action::CreateTopic; - use Codestriker::Action::EditComment; - use Codestriker::Action::Search; - use Codestriker::Action::ListTopics; - use Codestriker::Action::DownloadTopic; - use Codestriker::Action::ListProjects; - use Codestriker::Action::EditProject; - use Codestriker::Action::CreateProject; - use Codestriker::Action::MetricsReport; - use Codestriker::Action::SubmitEditTopicProperties; - use Codestriker::Action::SubmitEditTopicMetrics; - use Codestriker::Action::SubmitEditTopicsState; - use Codestriker::Action::SubmitEditCommentsState; - use Codestriker::Action::SubmitEditProject; - use Codestriker::Action::SubmitNewProject; - use Codestriker::Action::SubmitNewTopic; - use Codestriker::Action::SubmitNewComment; - use Codestriker::Action::SubmitSearch; - use Codestriker::Action::ViewTopicFile; - use Codestriker::Action::ViewTopicInfo; - use Codestriker::Action::ViewTopic; - use Codestriker::Action::ViewTopicProperties; - use Codestriker::Action::ViewTopicComments; - [% IF has_rss %]use Codestriker::Action::ListTopicsRSS; [% END %] - - use Codestriker::Template::Plugin::AutomagicLinks; - use Codestriker::Template::Plugin::JavascriptEscape; - use Codestriker::Template::Plugin::StringObfuscator; - use Codestriker::Template::Plugin::FormatWhitespace; - - # Set the temp file location, if one has been specified. - if (defined $Codestriker::tmpdir && $Codestriker::tmpdir ne '') { - $CGITempFile::TMPDIRECTORY = $Codestriker::tmpdir; - } - - # Set the PATH to something sane if we aren't running under windows. - # For a lot of annoying reasons, we can't run Codestriker in - # tainted mode under Win32. - if (Codestriker::is_windows()) { - $ENV{'PATH'} = ''; - } else { - $ENV{'PATH'} = '/bin:/usr/bin'; - } - - # Prototypes of subroutines used in this module. - sub main(); - - main; - - sub main() { - # Initialise Codestriker, load up the configuration file. - Codestriker->initialise([% codestriker_conf %]); - - [% IF has_rss %] - # Only generated if install.pl found a good version of XML::RSS. - $Codestriker::rss_enabled = 1; - [% ELSE %] - # valid XML::RSS not found - $Codestriker::rss_enabled = 0; - [% END %] - - # If allow_delete is defined, but topic state 'Delete' is not, add it - # in. This accounts for older configuration files. - if (defined $Codestriker::allow_delete && $Codestriker::allow_delete && - (! grep /^Deleted$/, @Codestriker::topic_states)) { - push @Codestriker::topic_states, 'Deleted'; - } - - # Check if the old $allow_comment_email configuration option has been - # specified in the config file, rather than the new $email_send_options - # setting. - if (defined $Codestriker::allow_comment_email && - ! defined $Codestriker::email_send_options) { - $Codestriker::email_send_options = - { - comments_sent_to_topic_author => $Codestriker::allow_comment_email, - comments_sent_to_commenter => $Codestriker::allow_comment_email, - topic_state_change_sent_to_reviewers => 0 - }; - } - - # Limit the size of the posts that can be done. - $CGI::POST_MAX=$Codestriker::DIFF_SIZE_LIMIT; - - # Load the CGI object, and prepare the HTTP response. - my $query = new CGI; - my $http_response = Codestriker::Http::Response->new($query); - - # TODO: need to put in mapping here from new URL scheme to old - # scheme. - - # Process the HTTP input to ensure it is consistent. - my $http_input = Codestriker::Http::Input->new($query, $http_response); - - my $dispatcher = Codestriker::Http::Dispatcher->new($query); - $dispatcher->dispatch($http_input, $http_response); - - #[% IF has_rss %] - # only generated if checksetup.pl found a good version of XML::RSS. - # } elsif ($action eq "list_topics_rss") { - # Codestriker::Action::ListTopicsRSS->process($http_input, - # $http_response); - #[% END %] - } +############################################################################### +# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved. +# si...@us... +# +# This program is free software; you can redistribute it and modify it under +# the terms of the GPL. + +# This is the top level package which receives all HTTP requests, and +# delegates it to the appropriate Action module. + +require 5.008_0; + +# Set this to the location of the Codestriker libraries on your system. +# Ideally, this should be done in the apache configs, but trying to do this +# in an easy way for Apache1/Apache2 with/without mod_perl with/without taint +# checking turned out to be a major headache. For mod_perl, setting this +# ensures the first time Codestriker is loaded, it can be compiled properly, +# even if @INC is blatted later. Also note all the use declarations below +# effectively "pre-load" all of the Codestriker modules in the system, as the +# modules below load all of their supporting modules. That is why the +# template plugins are "pre-loaded" here. +[% scmbug_lib %] +[% codestriker_lib %] + +use strict; + +use CGI qw/:standard :html3/; +use CGI::Carp 'fatalsToBrowser'; + +use Codestriker; +use Codestriker::Http::Input; +use Codestriker::Http::Response; +use Codestriker::Http::Dispatcher; +use Codestriker::Action::CreateTopic; +use Codestriker::Action::EditComment; +use Codestriker::Action::Search; +use Codestriker::Action::ListTopics; +use Codestriker::Action::DownloadTopic; +use Codestriker::Action::ListProjects; +use Codestriker::Action::EditProject; +use Codestriker::Action::CreateProject; +use Codestriker::Action::MetricsReport; +use Codestriker::Action::SubmitEditTopicProperties; +use Codestriker::Action::SubmitEditTopicMetrics; +use Codestriker::Action::SubmitEditTopicsState; +use Codestriker::Action::SubmitEditCommentsState; +use Codestriker::Action::SubmitEditProject; +use Codestriker::Action::SubmitNewProject; +use Codestriker::Action::SubmitNewTopic; +use Codestriker::Action::SubmitNewComment; +use Codestriker::Action::SubmitSearch; +use Codestriker::Action::ViewTopicFile; +use Codestriker::Action::ViewTopicInfo; +use Codestriker::Action::ViewTopic; +use Codestriker::Action::ViewTopicProperties; +use Codestriker::Action::ViewTopicComments; +[% IF has_rss %]use Codestriker::Action::ListTopicsRSS; [% END %] + +use Codestriker::Template::Plugin::AutomagicLinks; +use Codestriker::Template::Plugin::JavascriptEscape; +use Codestriker::Template::Plugin::StringObfuscator; +use Codestriker::Template::Plugin::FormatWhitespace; + +# Set the temp file location, if one has been specified. +if (defined $Codestriker::tmpdir && $Codestriker::tmpdir ne '') { + $CGITempFile::TMPDIRECTORY = $Codestriker::tmpdir; +} + +# Set the PATH to something sane if we aren't running under windows. +# For a lot of annoying reasons, we can't run Codestriker in +# tainted mode under Win32. +if (Codestriker::is_windows()) { + $ENV{'PATH'} = ''; +} else { + $ENV{'PATH'} = '/bin:/usr/bin'; +} + +# Prototypes of subroutines used in this module. +sub main(); + +main; + +sub main() { + # Initialise Codestriker, load up the configuration file. + Codestriker->initialise([% codestriker_conf %]); + + [% IF has_rss %] + # Only generated if install.pl found a good version of XML::RSS. + $Codestriker::rss_enabled = 1; + [% ELSE %] + # valid XML::RSS not found + $Codestriker::rss_enabled = 0; + [% END %] + + # If allow_delete is defined, but topic state 'Delete' is not, add it + # in. This accounts for older configuration files. + if (defined $Codestriker::allow_delete && $Codestriker::allow_delete && + (! grep /^Deleted$/, @Codestriker::topic_states)) { + push @Codestriker::topic_states, 'Deleted'; + } + + # Check if the old $allow_comment_email configuration option has been + # specified in the config file, rather than the new $email_send_options + # setting. + if (defined $Codestriker::allow_comment_email && + ! defined $Codestriker::email_send_options) { + $Codestriker::email_send_options = + { + comments_sent_to_topic_author => $Codestriker::allow_comment_email, + comments_sent_to_commenter => $Codestriker::allow_comment_email, + topic_state_change_sent_to_reviewers => 0 + }; + } + + # Limit the size of the posts that can be done. + $CGI::POST_MAX=$Codestriker::DIFF_SIZE_LIMIT; + + # Load the CGI object, and prepare the HTTP response. + my $query = new CGI; + my $http_response = Codestriker::Http::Response->new($query); + + # TODO: need to put in mapping here from new URL scheme to old + # scheme. + + # Process the HTTP input to ensure it is consistent. + my $http_input = Codestriker::Http::Input->new($query, $http_response); + + my $dispatcher = Codestriker::Http::Dispatcher->new($query); + $dispatcher->dispatch($http_input, $http_response); + + # only generated if checksetup.pl found a good version of XML::RSS. + # } elsif ($action eq "list_topics_rss") { + # Codestriker::Action::ListTopicsRSS->process($http_input, + # $http_response); + # +} Index: ListTopics.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Action/ListTopics.pm,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- ListTopics.pm 6 Sep 2008 00:31:45 -0000 1.38 +++ ListTopics.pm 6 Sep 2008 03:31:06 -0000 1.39 @@ -52,11 +52,12 @@ $sort_order) = get_topic_list_query_params($http_input); # Query the model for the specified data. - my @topics = Codestriker::Model::Topic->query($sauthor, $sreviewer, $scc, $sbugid, - $sstate, $sproject, $stext, - $stitle, $sdescription, - $scomments, $sbody, $sfilename, - $sort_order); + my @topics = + Codestriker::Model::Topic->query($sauthor, $sreviewer, $scc, $sbugid, + $sstate, $sproject, $stext, + $stitle, $sdescription, + $scomments, $sbody, $sfilename, + $sort_order); # Display the data, with each topic title linked to the view topic screen. # If only a single project id is being searched over, set that id in the @@ -236,6 +237,7 @@ $vars->{'list_projects_url'} = $url_builder->list_projects_url(); $vars->{'view_metrics_url'} = $url_builder->metric_report_url(); + $vars->{'action_url'} = $url_builder->update_topic_states_url(); my $template = Codestriker::Http::Template->new("listtopics"); $template->process($vars); Index: UrlBuilder.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/UrlBuilder.pm,v retrieving revision 1.47 retrieving revision 1.48 diff -u -r1.47 -r1.48 --- UrlBuilder.pm 6 Sep 2008 00:31:47 -0000 1.47 +++ UrlBuilder.pm 6 Sep 2008 03:31:07 -0000 1.48 @@ -34,6 +34,7 @@ use Codestriker::Http::Method::UpdateTopicPropertiesMethod; use Codestriker::Http::Method::UpdateTopicMetricsMethod; use Codestriker::Http::Method::UpdateCommentMetricsMethod; +use Codestriker::Http::Method::UpdateTopicStateMethod; # Constructor for this class. sub new { @@ -203,6 +204,12 @@ return Codestriker::Http::Method::UpdateTopicMetricsMethod->new($self->{query})->url(%args); } +# Create the URL for updating a number of topic states. +sub update_topic_states_url { + my ($self, %args) = @_; + return Codestriker::Http::Method::UpdateTopicStateMethod->new($self->{query})->url(%args); +} + # Create the URL for adding new comments. sub add_comment_url { my ($self, %args) = @_; Index: UpdateTopicStateMethod.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Method/UpdateTopicStateMethod.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- UpdateTopicStateMethod.pm 6 Sep 2008 00:31:45 -0000 1.3 +++ UpdateTopicStateMethod.pm 6 Sep 2008 03:31:07 -0000 1.4 @@ -22,8 +22,7 @@ if ($self->{cgi_style}) { return $self->{url_prefix} . "?action=change_topics_state"; } else { - confess "Parameter projectid missing" unless defined $args{projectid}; - return $self->{url_prefix} . "/project/$args{projectid}/topic/update"; + return $self->{url_prefix} . "/topics/update"; } } @@ -32,12 +31,12 @@ my $action = $http_input->{query}->param('action'); my $path_info = $http_input->{query}->path_info(); - if ($self->{cgi_style} && defined $action && $action eq "change_topics_state") { + if ($self->{cgi_style} && defined $action && + $action eq "change_topics_state") { $http_input->extract_cgi_parameters(); return 1; - } elsif ($path_info =~ m{^/project/\d+/topic/update}) { - $self->_extract_nice_parameters($http_input, - project => 'projectid'); + } elsif ($path_info =~ m{^/topics/update}) { + $self->_extract_nice_parameters($http_input); return 1; } else { return 0; Index: update-topic-states.t =================================================================== RCS file: /cvsroot/codestriker/codestriker/t/Http/Method/update-topic-states.t,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- update-topic-states.t 31 Aug 2008 12:30:05 -0000 1.2 +++ update-topic-states.t 6 Sep 2008 03:31:07 -0000 1.3 @@ -22,7 +22,7 @@ "Update topic state URL CGI syntax"); is($url_nice->url(projectid => 10), - $mock_query->url() . '/project/10/topic/update', + $mock_query->url() . '/topics/update', "Update topic state URL nice syntax"); # Check that the parameters extracted correctly. @@ -31,10 +31,9 @@ $mock_http_input->mock('extract_cgi_parameters', sub { return undef; }); $mock_query->mock('path_info', sub { - return '/project/10/topic/update'; + return '/topics/update'; }); $mock_query->mock('param', sub { return undef; }); $url_nice->extract_parameters($mock_http_input); -is ($mock_http_input->{projectid}, "10", "project nice URL parameter extraction"); - \ No newline at end of file + Index: listtopics.html.tmpl =================================================================== RCS file: /cvsroot/codestriker/codestriker/template/en/default/listtopics.html.tmpl,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- listtopics.html.tmpl 24 Jun 2008 03:26:50 -0000 1.44 +++ listtopics.html.tmpl 6 Sep 2008 03:31:08 -0000 1.45 @@ -10,7 +10,7 @@ [% END %] [%# Display the heading and create the table #%] -<FORM METHOD="post" ENCTYPE="multipart/form-data"> +<FORM METHOD="post" ENCTYPE="multipart/form-data" ACTION="[% action_url %]"> <input TYPE="hidden" NAME="action" VALUE="change_topics_state" /> [%# Store the search parameters as hidden variables #%] |
From: <si...@us...> - 2008-09-06 00:31:54
|
User: sits Date: 08/09/05 17:31:51 Modified: lib/Codestriker/FileParser PerforceDiff.pm PatchUnidiff.pm ClearCaseSerialDiff.pm SubversionDiff.pm Parser.pm BasicDiffUtils.pm PerforceDescribe.pm UnidiffUtils.pm UnknownFormat.pm CvsUnidiff.pm PatchBasicDiff.pm VssDiff.pm lib/Codestriker/Http/Method AddProjectMethod.pm SearchTopicsMethod.pm ViewTopicCommentsMethod.pm DownloadTopicTextMethod.pm AddTopicMethod.pm UpdateTopicMetricsMethod.pm ViewTopicMetricsMethod.pm UpdateTopicPropertiesMethod.pm ViewTopicFileMethod.pm ViewTopicTextMethod.pm UpdateCommentMetricsMethod.pm SubmitSearchTopicsMethod.pm DownloadMetricsMethod.pm ViewMetricsMethod.pm ViewTopicPropertiesMethod.pm ListProjectsMethod.pm EditProjectMethod.pm CreateCommentMethod.pm ListTopicsMethod.pm StaticResourcesMethod.pm CreateTopicMethod.pm UpdateTopicStateMethod.pm AddCommentMethod.pm CreateProjectMethod.pm UpdateProjectMethod.pm lib/Codestriker/Action MetricsReport.pm ViewTopicComments.pm SubmitNewComment.pm ListTopicsRSS.pm SubmitSearch.pm CreateProject.pm SubmitEditCommentsState.pm SubmitEditTopicMetrics.pm ListTopics.pm EditProject.pm ViewTopicInfo.pm ViewTopic.pm CreateTopic.pm ListProjects.pm SubmitEditTopicsState.pm SubmitEditTopicProperties.pm DownloadTopic.pm SubmitEditProject.pm ViewTopicFile.pm SubmitNewTopic.pm ViewTopicProperties.pm Search.pm EditComment.pm SubmitNewProject.pm lib/Codestriker/Http NonHighlightedLxrLineFilter.pm UrlBuilder.pm LineFilter.pm Response.pm Cookie.pm Template.pm LxrLineFilter.pm Dispatcher.pm TabToNbspLineFilter.pm HighlightLineFilter.pm Input.pm HtmlEntityLineFilter.pm DeltaRenderer.pm HighlightedLxrLineFilter.pm Method.pm lib/Codestriker/Repository RepositoryFactory.pm CvsWeb.pm ScmBug.pm ClearCaseSnapshot.pm Perforce.pm Subversion.pm ViewCvs.pm ClearCaseDynamic.pm Cvs.pm Vss.pm lib/Codestriker/DB SQLite.pm PostgreSQL.pm Column.pm DBI.pm MySQL.pm ODBC.pm Oracle.pm Database.pm Table.pm lib/Codestriker/Model Delta.pm MetricStats.pm Metrics.pm File.pm Topic.pm Project.pm Comment.pm lib Codestriker.pm lib/Codestriker/BugDB FlysprayConnection.pm BugzillaConnection.pm BugDBConnectionFactory.pm TestDirectorConnection.pm bin codestriker.pl.base install.pl lib/Codestriker/TopicListeners HistoryRecorder.pm Manager.pm Email.pm BugTracking.pm TopicListener.pm . codestriker.conf Log: Whitespace changes primarily - reverting bck to emacs's cperl-mode, and replaced all tabs with spaces. Index: PerforceDiff.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/FileParser/PerforceDiff.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- PerforceDiff.pm 22 May 2005 22:26:04 -0000 1.2 +++ PerforceDiff.pm 6 Sep 2008 00:31:44 -0000 1.3 @@ -29,7 +29,7 @@ # Skip initial whitespace. my $line = <$fh>; while (defined($line) && $line =~ /^\s*$/) { - $line = <$fh>; + $line = <$fh>; } # Array of results found. @@ -41,67 +41,65 @@ # Now read the actual diff chunks. while (defined($line)) { - if ($line =~ /^==== (.*)\#(\d+) \- .* ==== \((.*)\)$/) { - my $filename = $1; - my $revision = $2; - my $file_type = $3; - - if ($file_type eq "ubinary" || $file_type eq "xbinary" || - $file_type eq "binary") { - # Binary file, skip the next line and add the record in. - $line = <$fh>; - my $chunk = {}; - $chunk->{filename} = $filename; - $chunk->{revision} = $revision; - $chunk->{old_linenumber} = -1; - $chunk->{new_linenumber} = -1; - $chunk->{binary} = 1; - $chunk->{text} = ""; - $chunk->{description} = ""; - $chunk->{repmatch} = $repmatch; - push @result, $chunk; - } - elsif ($file_type eq "text") { - # Note there may be an optional '---' and '+++' lines - # before the chunk. - my $lastpos = tell $fh; - if (<$fh> !~ /^\-\-\-/ || <$fh> !~ /^\+\+\+/) { - # Move the file pointer back. - seek $fh, $lastpos, 0; - } - - my @file_diffs = Codestriker::FileParser::UnidiffUtils-> - read_unidiff_text($fh, $filename, $revision, $repmatch); - push @result, @file_diffs; - } - else { - # Got knows what this is, can't parse it. - return (); - } - } elsif ($line =~ /^==== (.*)\#(\d+) \-/) { - my $filename = $1; - my $revision = $2; - - # Now read the entire diff chunk (it may be empty if the - # user hasn't actually modified the file). Note there - # may be an optional '---' and '+++' lines before the - # chunk. - my $lastpos = tell $fh; - if (<$fh> !~ /^\-\-\-/ || <$fh> !~ /^\+\+\+/) { - # Move the file pointer back. - seek $fh, $lastpos, 0; - } - - my @file_diffs = Codestriker::FileParser::UnidiffUtils-> - read_unidiff_text($fh, $filename, $revision, $repmatch); - push @result, @file_diffs; - } else { - # Can't parse this file. - return (); - } - - # Now read the next chunk. - $line = <$fh> if defined $line; + if ($line =~ /^==== (.*)\#(\d+) \- .* ==== \((.*)\)$/) { + my $filename = $1; + my $revision = $2; + my $file_type = $3; + + if ($file_type eq "ubinary" || $file_type eq "xbinary" || + $file_type eq "binary") { + # Binary file, skip the next line and add the record in. + $line = <$fh>; + my $chunk = {}; + $chunk->{filename} = $filename; + $chunk->{revision} = $revision; + $chunk->{old_linenumber} = -1; + $chunk->{new_linenumber} = -1; + $chunk->{binary} = 1; + $chunk->{text} = ""; + $chunk->{description} = ""; + $chunk->{repmatch} = $repmatch; + push @result, $chunk; + } elsif ($file_type eq "text") { + # Note there may be an optional '---' and '+++' lines + # before the chunk. + my $lastpos = tell $fh; + if (<$fh> !~ /^\-\-\-/ || <$fh> !~ /^\+\+\+/) { + # Move the file pointer back. + seek $fh, $lastpos, 0; + } + + my @file_diffs = Codestriker::FileParser::UnidiffUtils-> + read_unidiff_text($fh, $filename, $revision, $repmatch); + push @result, @file_diffs; + } else { + # Got knows what this is, can't parse it. + return (); + } + } elsif ($line =~ /^==== (.*)\#(\d+) \-/) { + my $filename = $1; + my $revision = $2; + + # Now read the entire diff chunk (it may be empty if the + # user hasn't actually modified the file). Note there + # may be an optional '---' and '+++' lines before the + # chunk. + my $lastpos = tell $fh; + if (<$fh> !~ /^\-\-\-/ || <$fh> !~ /^\+\+\+/) { + # Move the file pointer back. + seek $fh, $lastpos, 0; + } + + my @file_diffs = Codestriker::FileParser::UnidiffUtils-> + read_unidiff_text($fh, $filename, $revision, $repmatch); + push @result, @file_diffs; + } else { + # Can't parse this file. + return (); + } + + # Now read the next chunk. + $line = <$fh> if defined $line; } # Return the found diff chunks. Index: PatchUnidiff.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/FileParser/PatchUnidiff.pm,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- PatchUnidiff.pm 14 Jul 2008 05:35:59 -0000 1.7 +++ PatchUnidiff.pm 6 Sep 2008 00:31:44 -0000 1.8 @@ -25,91 +25,91 @@ my $line = <$fh>; while (defined($line)) { - # Values associated with the diff. - my $revision = $Codestriker::PATCH_REVISION; - my $filename = ""; - my $old_linenumber = -1; - my $new_linenumber = -1; - my $binary = 0; - - # Skip any heading or trailing whitespace contained in the review - # text. - while (defined($line) && $line =~ /^\s*$/) { - $line = <$fh>; - } - return @result unless defined $line; - - # For unidiffs, the diff line may appear first, but is optional, - # depending on how the diff was generated. In any case, the line - # is ignored. - if (defined $line && $line =~ /^diff/o) { - $line = <$fh>; - } - return () unless defined $line; - - # Git patches might have an index: line, such as: - # index b3fc290..d13313f 100644 - if ($line =~ /^index /o) { - $line = <$fh>; - } - return () unless defined $line; - + # Values associated with the diff. + my $revision = $Codestriker::PATCH_REVISION; + my $filename = ""; + my $old_linenumber = -1; + my $new_linenumber = -1; + my $binary = 0; + + # Skip any heading or trailing whitespace contained in the review + # text. + while (defined($line) && $line =~ /^\s*$/) { + $line = <$fh>; + } + return @result unless defined $line; + + # For unidiffs, the diff line may appear first, but is optional, + # depending on how the diff was generated. In any case, the line + # is ignored. + if (defined $line && $line =~ /^diff/o) { + $line = <$fh>; + } + return () unless defined $line; + + # Git patches might have an index: line, such as: + # index b3fc290..d13313f 100644 + if ($line =~ /^index /o) { + $line = <$fh>; + } + return () unless defined $line; + # Need to check for binary file differences. # Unfortunately, when you provide the "-N" argument to diff, # it doesn't indicate new files or removed files properly. Without # the -N argument, it then indicates "Only in ...". if ($line =~ /^Binary files .* and (.*) differ$/ || - $line =~ /^Files .* and (.*) differ$/) { + $line =~ /^Files .* and (.*) differ$/) { $filename = $1; $binary = 1; } elsif ($line =~ /^Only in (.*): (.*)$/) { $filename = "$1/$2"; $binary = 1; - } elsif ($line =~ /^\-\-\- \/dev\/null/o) { - # File has been added. - $revision = $Codestriker::ADDED_REVISION; - } elsif ($line =~ /^\-\-\- ([^\t\n]+)/o) { - # Note git and quilt diffs don't have a tab character unlike normal diffs. - $filename = $1; - } else { - return (); - } - - if ($binary == 0) { - # Now expect the +++ line. - $line = <$fh>; - return () unless defined $line; - - # Check if it is a removed file. - if ($line =~ /^\+\+\+ \/dev\/null/o) { - # File has been removed. - $revision = $Codestriker::REMOVED_REVISION; - } elsif ($line =~ /^\+\+\+ ([^\t\n]+)/o) { - $filename = $1; - } else { - return (); - } - - # Extract the diff chunks for this file. - my @file_diffs = Codestriker::FileParser::UnidiffUtils-> - read_unidiff_text($fh, $filename, $revision, 0); - push @result, @file_diffs; - } else { - my $chunk = {}; - $chunk->{filename} = $filename; - $chunk->{revision} = $revision; - $chunk->{old_linenumber} = -1; - $chunk->{new_linenumber} = -1; - $chunk->{binary} = 1; - $chunk->{text} = ""; - $chunk->{description} = ""; - $chunk->{repmatch} = 0; - push @result, $chunk; - } + } elsif ($line =~ /^\-\-\- \/dev\/null/o) { + # File has been added. + $revision = $Codestriker::ADDED_REVISION; + } elsif ($line =~ /^\-\-\- ([^\t\n]+)/o) { + # Note git and quilt diffs don't have a tab character unlike normal diffs. + $filename = $1; + } else { + return (); + } + + if ($binary == 0) { + # Now expect the +++ line. + $line = <$fh>; + return () unless defined $line; + + # Check if it is a removed file. + if ($line =~ /^\+\+\+ \/dev\/null/o) { + # File has been removed. + $revision = $Codestriker::REMOVED_REVISION; + } elsif ($line =~ /^\+\+\+ ([^\t\n]+)/o) { + $filename = $1; + } else { + return (); + } + + # Extract the diff chunks for this file. + my @file_diffs = Codestriker::FileParser::UnidiffUtils-> + read_unidiff_text($fh, $filename, $revision, 0); + push @result, @file_diffs; + } else { + my $chunk = {}; + $chunk->{filename} = $filename; + $chunk->{revision} = $revision; + $chunk->{old_linenumber} = -1; + $chunk->{new_linenumber} = -1; + $chunk->{binary} = 1; + $chunk->{text} = ""; + $chunk->{description} = ""; + $chunk->{repmatch} = 0; + push @result, $chunk; + } - # Read the next line. - $line = <$fh>; + # Read the next line. + $line = <$fh>; } # Return the found diff chunks. @@ -118,4 +118,4 @@ 1; - + Index: ClearCaseSerialDiff.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/FileParser/ClearCaseSerialDiff.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ClearCaseSerialDiff.pm 24 Sep 2007 21:25:45 -0000 1.5 +++ ClearCaseSerialDiff.pm 6 Sep 2008 00:31:44 -0000 1.6 @@ -21,7 +21,7 @@ # Retrieve the repository root, and escape back-slashes in the case of # a Windows CVS repository, as it is used in regular expressions. my $repository_root = - (defined $repository) ? $repository->getRoot() : undef; + (defined $repository) ? $repository->getRoot() : undef; if (defined $repository_root) { $repository_root =~ s/\\/\\\\/g; } @@ -37,128 +37,126 @@ # Ignore any whitespace at the start of the file. my $line = <$fh>; while (defined($line)) { - # Skip any heading or trailing whitespace contained in the review - # text, in addition to the "Files/Directories are identical" lines, - # which happen due to the way review texts are generated. - while (defined($line) && - ($line =~ /^\s*$/o || - $line =~ /^Files are identical$/o || - $line =~ /^Directories are identical$/o)) { - $line = <$fh>; - } - return @result unless defined $line; - - # Check if the next fileheader is being read. - if (defined $line && - $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o) { - - # Now read the file/directory that has been modified. - $line = <$fh>; - return () unless defined $line; - - if ($line =~ /^\<\<\< file 1\: (.*)\@\@(.*)$/o) { - $filename = $1; - $revision = $2; - - # Check if the filename matches the clear case repository. - # This is very simple for now, but will need to be more - # sophisticated later. - if (defined $repository_root && - $filename =~ /^$repository_root[\/\\](.*)$/o) { - $filename = $1; - $repmatch = 1; - } else { - $repmatch = 0; - } - - # Read the next line which is the local file. - $line = <$fh>; - return () unless - defined $line && $line =~ /^\>\>\> file 2\: .*$/o; - - # Now expect the end of the file header. - $line = <$fh>; - return () unless - defined $line && $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o; - - # Read the next line. - $line = <$fh>; - return () unless defined $line; - } - elsif ($line =~ /^\<\<\< directory 1\: (.*)\@\@(.*)$/o) { - # Currently we don't really support directory - # operations. ClearCase captures added/deleted - # sub-directories and deleted files as a directory change, - # but unfortunately added files go straight into the - # VOB - great. Try to fddge this so that we treat the - # directory as a file, where the contents are the diff - # file itself - better than nothing, and the reviewers - # can at least see what is going on. - $filename = $1; - $revision = $2; - - # Check if the filename matches the clear case repository. - # This is very simple for now, but will need to be more - # sophisticated later. - if (defined $repository_root && - $filename =~ /^$repository_root[\/\\](.*)$/o) { - $filename = $1; - } - - # Read the next line which is the local directory. - $line = <$fh>; - return () unless - defined $line && $line =~ /^\>\>\> directory 2\: .*$/o; - - # Now expect the end of the file header. - $line = <$fh>; - return () unless - defined $line && $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o; - - # Keep reading text until there is nothing left for this - # segment. - my $text = ""; - $line = <$fh>; - while (defined $line && - $line !~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o) { - if ($line !~ /^Files are identical$/o && - $line !~ /^Directories are identical$/o) { - $text .= "+$line"; - } - $line = <$fh>; - } - - # Create the chunk, indicating there is not a repository match, - # since this is for a directory entry with some basic text. - my $chunk = {}; - $chunk->{filename} = $filename; - $chunk->{revision} = $revision; - $chunk->{old_linenumber} = 0; - $chunk->{new_linenumber} = 1; - $chunk->{binary} = 0; - $chunk->{text} = $text; - $chunk->{description} = ""; - $chunk->{repmatch} = 0; - push @result, $chunk; - - # Process the next block. - next; - } - else { - # Some unknown format. - return (); - } - } - - # Read the next diff chunk. - my $chunk = - Codestriker::FileParser::BasicDiffUtils->read_diff_text( - $fh, $line, $filename, $revision, $repmatch); - return () unless defined $chunk; - push @result, $chunk; + # Skip any heading or trailing whitespace contained in the review + # text, in addition to the "Files/Directories are identical" lines, + # which happen due to the way review texts are generated. + while (defined($line) && + ($line =~ /^\s*$/o || + $line =~ /^Files are identical$/o || + $line =~ /^Directories are identical$/o)) { + $line = <$fh>; + } + return @result unless defined $line; + + # Check if the next fileheader is being read. + if (defined $line && + $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o) { + + # Now read the file/directory that has been modified. + $line = <$fh>; + return () unless defined $line; + + if ($line =~ /^\<\<\< file 1\: (.*)\@\@(.*)$/o) { + $filename = $1; + $revision = $2; + + # Check if the filename matches the clear case repository. + # This is very simple for now, but will need to be more + # sophisticated later. + if (defined $repository_root && + $filename =~ /^$repository_root[\/\\](.*)$/o) { + $filename = $1; + $repmatch = 1; + } else { + $repmatch = 0; + } + + # Read the next line which is the local file. + $line = <$fh>; + return () unless + defined $line && $line =~ /^\>\>\> file 2\: .*$/o; + + # Now expect the end of the file header. + $line = <$fh>; + return () unless + defined $line && $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o; + + # Read the next line. + $line = <$fh>; + return () unless defined $line; + } elsif ($line =~ /^\<\<\< directory 1\: (.*)\@\@(.*)$/o) { + # Currently we don't really support directory + # operations. ClearCase captures added/deleted + # sub-directories and deleted files as a directory change, + # but unfortunately added files go straight into the + # VOB - great. Try to fddge this so that we treat the + # directory as a file, where the contents are the diff + # file itself - better than nothing, and the reviewers + # can at least see what is going on. + $filename = $1; + $revision = $2; + + # Check if the filename matches the clear case repository. + # This is very simple for now, but will need to be more + # sophisticated later. + if (defined $repository_root && + $filename =~ /^$repository_root[\/\\](.*)$/o) { + $filename = $1; + } + + # Read the next line which is the local directory. + $line = <$fh>; + return () unless + defined $line && $line =~ /^\>\>\> directory 2\: .*$/o; + + # Now expect the end of the file header. + $line = <$fh>; + return () unless + defined $line && $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o; + + # Keep reading text until there is nothing left for this + # segment. + my $text = ""; + $line = <$fh>; + while (defined $line && + $line !~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o) { + if ($line !~ /^Files are identical$/o && + $line !~ /^Directories are identical$/o) { + $text .= "+$line"; + } + $line = <$fh>; + } + + # Create the chunk, indicating there is not a repository match, + # since this is for a directory entry with some basic text. + my $chunk = {}; + $chunk->{filename} = $filename; + $chunk->{revision} = $revision; + $chunk->{old_linenumber} = 0; + $chunk->{new_linenumber} = 1; + $chunk->{binary} = 0; + $chunk->{text} = $text; + $chunk->{description} = ""; + $chunk->{repmatch} = 0; + push @result, $chunk; + + # Process the next block. + next; + } else { + # Some unknown format. + return (); + } + } + + # Read the next diff chunk. + my $chunk = + Codestriker::FileParser::BasicDiffUtils->read_diff_text( + $fh, $line, $filename, $revision, $repmatch); + return () unless defined $chunk; + push @result, $chunk; - # Read the next line. - $line = <$fh>; + # Read the next line. + $line = <$fh>; } # Return the found diff chunks. @@ -167,4 +165,4 @@ 1; - + Index: SubversionDiff.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/FileParser/SubversionDiff.pm,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- SubversionDiff.pm 2 Sep 2008 06:33:57 -0000 1.11 +++ SubversionDiff.pm 6 Sep 2008 00:31:44 -0000 1.12 @@ -24,137 +24,137 @@ my $line = <$fh>; while (defined($line)) { - # Values associated with the diff. - my $entry_type; - my $revision; - my $filename = ""; - my $old_linenumber = -1; - my $new_linenumber = -1; - my $binary = 0; - my $diff = ""; - - # Skip whitespace. - while (defined($line) && $line =~ /^\s*$/o) { - $line = <$fh>; - } - return @result unless defined $line; - - # For SVN diffs, the start of the diff block is the Index line. - # For SVN look diffs, the start of the diff block contains the change type. - # Also check for presence of property set blocks. - while ($line =~ /^.*Property changes on: .*$/o) { - $line = <$fh>; - return () unless defined $line && - $line =~ /^___________________________________________________________________$/o; - - # Keep reading until we either get to the separator line or end of file. - while (defined $line && - $line !~ /^===================================================================$/o) { - if ($line =~ /^.*(Index|Added|Modified|Copied|Deleted): (.*)$/o) { - $entry_type = $1; - $filename = $2; + # Values associated with the diff. + my $entry_type; + my $revision; + my $filename = ""; + my $old_linenumber = -1; + my $new_linenumber = -1; + my $binary = 0; + my $diff = ""; + + # Skip whitespace. + while (defined($line) && $line =~ /^\s*$/o) { + $line = <$fh>; + } + return @result unless defined $line; + + # For SVN diffs, the start of the diff block is the Index line. + # For SVN look diffs, the start of the diff block contains the change type. + # Also check for presence of property set blocks. + while ($line =~ /^.*Property changes on: .*$/o) { + $line = <$fh>; + return () unless defined $line && + $line =~ /^___________________________________________________________________$/o; + + # Keep reading until we either get to the separator line or end of file. + while (defined $line && + $line !~ /^===================================================================$/o) { + if ($line =~ /^.*(Index|Added|Modified|Copied|Deleted): (.*)$/o) { + $entry_type = $1; + $filename = $2; + } + $line = <$fh>; + } + + if (!defined $line) { + # End of file has been reached, return what we have parsed. + return @result; } - $line = <$fh>; } - - if (!defined $line) { - # End of file has been reached, return what we have parsed. - return @result; + + if ($line =~ /^.*(Index|Added|Modified|Copied|Deleted): (.*)$/o) { + $entry_type = $1; + $filename = $2; + $line = <$fh>; } - } - if ($line =~ /^.*(Index|Added|Modified|Copied|Deleted): (.*)$/o) { - $entry_type = $1; - $filename = $2; - $line = <$fh>; - } + # The separator line appears next. + return () unless defined $line && $line =~ /^===================================================================$/o; + $line = <$fh>; + + # Check if this is a file entry with no content. If so, skip it. + next if ! defined $line || $line =~ /^\s*$/o; + + # Check if the delta represents a binary file. + if ($line =~ /^Cannot display: file marked as a binary type\./o || + $line =~ /^\(Binary files differ\)/o) { + + # If it is a new binary file, there will be some lines before + # the next Index: line, or end of file. In other cases, it is + # impossible to know whether the file is being modified or + # removed, and what revision it is based off. + $line = <$fh>; + my $count = 0; + while (defined $line && $line !~ /^Index|Added|Modified|Deleted|Property changes on:/o) { + $line = <$fh>; + $count++; + } + + my $chunk = {}; + $chunk->{filename} = $filename; + if ($entry_type eq "Index") { + $chunk->{revision} = $count > 0 ? $Codestriker::ADDED_REVISION : + $Codestriker::PATCH_REVISION; + } elsif ($entry_type eq "Added") { + $chunk->{revision} = $Codestriker::ADDED_REVISION; + } elsif ($entry_type eq "Deleted") { + $chunk->{revision} = $Codestriker::REMOVED_REVISION; + } else { + $chunk->{revision} = $Codestriker::PATCH_REVISION; + } + $chunk->{old_linenumber} = -1; + $chunk->{new_linenumber} = -1; + $chunk->{binary} = 1; + $chunk->{text} = ""; + $chunk->{description} = ""; + $chunk->{repmatch} = 1; + push @result, $chunk; + } else { + # Try and read the base revision this change is against, + # while handling new and removed files. + my $base_revision = -1; + if ($line =~ /^\-\-\- .*\s.*\(.*?(\d+)\)/io) { + $base_revision = $1; + } elsif ($line !~ /^\-\-\- .*/io) { + return (); + } - # The separator line appears next. - return () unless defined $line && $line =~ /^===================================================================$/o; - $line = <$fh>; - - # Check if this is a file entry with no content. If so, skip it. - next if ! defined $line || $line =~ /^\s*$/o; - - # Check if the delta represents a binary file. - if ($line =~ /^Cannot display: file marked as a binary type\./o || - $line =~ /^\(Binary files differ\)/o) { - - # If it is a new binary file, there will be some lines before - # the next Index: line, or end of file. In other cases, it is - # impossible to know whether the file is being modified or - # removed, and what revision it is based off. - $line = <$fh>; - my $count = 0; - while (defined $line && $line !~ /^Index|Added|Modified|Deleted|Property changes on:/o) { - $line = <$fh>; - $count++; - } - - my $chunk = {}; - $chunk->{filename} = $filename; - if ($entry_type eq "Index") { - $chunk->{revision} = $count > 0 ? $Codestriker::ADDED_REVISION : - $Codestriker::PATCH_REVISION; - } elsif ($entry_type eq "Added") { - $chunk->{revision} = $Codestriker::ADDED_REVISION; - } elsif ($entry_type eq "Deleted") { - $chunk->{revision} = $Codestriker::REMOVED_REVISION; - } else { - $chunk->{revision} = $Codestriker::PATCH_REVISION; - } - $chunk->{old_linenumber} = -1; - $chunk->{new_linenumber} = -1; - $chunk->{binary} = 1; - $chunk->{text} = ""; - $chunk->{description} = ""; - $chunk->{repmatch} = 1; - push @result, $chunk; - } else { - # Try and read the base revision this change is against, - # while handling new and removed files. - my $base_revision = -1; - if ($line =~ /^\-\-\- .*\s.*\(.*?(\d+)\)/io) { - $base_revision = $1; - } elsif ($line !~ /^\-\-\- .*/io) { - return (); - } - - # Make sure the +++ line is present next. - $line = <$fh>; - return () unless defined $line; - if ($line !~ /^\+\+\+ .*/io) { - return (); - } - - # Now parse the unidiff chunks. - my @file_diffs = Codestriker::FileParser::UnidiffUtils-> - read_unidiff_text($fh, $filename, $base_revision, 1); - - # If $base_revision is -1, and old_linenumber is 0, then - # the file is added. If $base_revision is -1, and - # new_linenumber is 0, then the file is removed. Update - # any chunks to indicate this. - if ($base_revision == -1) { - for (my $i = 0; $i <= $#file_diffs; $i++) { - my $delta = $file_diffs[$i]; - if ($delta->{old_linenumber} == 0) { - $delta->{revision} = $Codestriker::ADDED_REVISION; - } elsif ($delta->{new_linenumber} == 0) { - $delta->{revision} = $Codestriker::REMOVED_REVISION; - } - } - } - - push @result, @file_diffs; - - # Read the next line. - $line = <$fh>; - } + # Make sure the +++ line is present next. + $line = <$fh>; + return () unless defined $line; + if ($line !~ /^\+\+\+ .*/io) { + return (); + } + + # Now parse the unidiff chunks. + my @file_diffs = Codestriker::FileParser::UnidiffUtils-> + read_unidiff_text($fh, $filename, $base_revision, 1); + + # If $base_revision is -1, and old_linenumber is 0, then + # the file is added. If $base_revision is -1, and + # new_linenumber is 0, then the file is removed. Update + # any chunks to indicate this. + if ($base_revision == -1) { + for (my $i = 0; $i <= $#file_diffs; $i++) { + my $delta = $file_diffs[$i]; + if ($delta->{old_linenumber} == 0) { + $delta->{revision} = $Codestriker::ADDED_REVISION; + } elsif ($delta->{new_linenumber} == 0) { + $delta->{revision} = $Codestriker::REMOVED_REVISION; + } + } + } + + push @result, @file_diffs; + + # Read the next line. + $line = <$fh>; + } } # Return the found diff chunks. return @result; } - + 1; Index: Parser.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/FileParser/Parser.pm,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- Parser.pm 26 Jun 2008 21:52:23 -0000 1.25 +++ Parser.pm 6 Sep 2008 00:31:44 -0000 1.26 @@ -7,7 +7,7 @@ # the terms of the GPL. # Main delegate parser object, which tries a bunch of parsers to determine what -# format the input review is in. The last resort, is to view it as +# format the input review is in. The last resort, is to view it as # unstructured text, if it is content-type plain/text, otherwise indicate # an error. @@ -32,7 +32,7 @@ # lines, revisions and diffs have been submitted in this review. sub parse ($$$$$$) { my ($type, $fh, $content_type, $repository, $topicid, - $uploaded_filename) = @_; + $uploaded_filename) = @_; # Diffs found. my @diffs = (); @@ -45,139 +45,138 @@ # once this function has finished. my $tmpfh; if (defined $Codestriker::tmpdir && $Codestriker::tmpdir ne "") { - $tmpfh = tempfile(DIR => $Codestriker::tmpdir); - } - else { - $tmpfh = tempfile(); + $tmpfh = tempfile(DIR => $Codestriker::tmpdir); + } else { + $tmpfh = tempfile(); } binmode $tmpfh, ':utf8'; - + if (!$tmpfh) { - die "Unable to create temporary parse file: $!"; + die "Unable to create temporary parse file: $!"; } binmode $fh; my $first_line = 1; while (<$fh>) { - if ($first_line) { - # Remove the UTF8 BOM if it exists. - s/^\xEF\xBB\xBF//o; - $first_line = 0; - } - my $line = Codestriker::decode_topic_text($_); - $line =~ s/\r\n/\n/go; - print $tmpfh $line; + if ($first_line) { + # Remove the UTF8 BOM if it exists. + s/^\xEF\xBB\xBF//o; + $first_line = 0; + } + my $line = Codestriker::decode_topic_text($_); + $line =~ s/\r\n/\n/go; + print $tmpfh $line; } # Rewind the file, then let the parsers have at it. seek($tmpfh,0,0) || - die "Unable to seek to the start of the temporary file: $!"; + die "Unable to seek to the start of the temporary file: $!"; # If the file is plain/text, try all of the text parsers. if ($content_type eq "text/plain") { - # Check if it is a CVS unidiff file. - if ($#diffs == -1) { - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = - Codestriker::FileParser::CvsUnidiff->parse($tmpfh, - $repository); - } - - # Check if it is a Subversion diff file. - if ($#diffs == -1) { - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = - Codestriker::FileParser::SubversionDiff->parse($tmpfh, - $repository); - } - - # Check if it is a Perforce describe file. - if ($#diffs == -1) { - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = - Codestriker::FileParser::PerforceDescribe->parse($tmpfh, - $repository); - } - - # Check if it is a Perforce diff file. - if ($#diffs == -1) { - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = - Codestriker::FileParser::PerforceDiff->parse($tmpfh, - $repository); - } - - # Check if it is a VSS diff file. - if ($#diffs == -1) { - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = - Codestriker::FileParser::VssDiff->parse($tmpfh, - $repository); - } - - # Check if it is a patch unidiff file. - if ($#diffs == -1) { - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = - Codestriker::FileParser::PatchUnidiff->parse($tmpfh, - $repository); - } - - # Check if it is a patch basic file. - if ($#diffs == -1) { - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = - Codestriker::FileParser::PatchBasicDiff->parse($tmpfh, - $uploaded_filename); - } - - # Check if it is a ClearCase serial diff file. - if ($#diffs == -1) { - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = - Codestriker::FileParser::ClearCaseSerialDiff->parse($tmpfh, - $repository); - } - - # Last stop-gap - the file format is unknown, treat it as a - # single file with filename "unknown". - if ($#diffs == -1) { - if (! defined $uploaded_filename || $uploaded_filename eq '') { - $uploaded_filename = 'unknown.txt'; - } - seek($tmpfh, 0, 0) || - die "Unable to seek to the start of the temporary file: $!"; - @diffs = Codestriker::FileParser::UnknownFormat-> - parse($tmpfh, $uploaded_filename); - } + # Check if it is a CVS unidiff file. + if ($#diffs == -1) { + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = + Codestriker::FileParser::CvsUnidiff->parse($tmpfh, + $repository); + } + + # Check if it is a Subversion diff file. + if ($#diffs == -1) { + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = + Codestriker::FileParser::SubversionDiff->parse($tmpfh, + $repository); + } + + # Check if it is a Perforce describe file. + if ($#diffs == -1) { + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = + Codestriker::FileParser::PerforceDescribe->parse($tmpfh, + $repository); + } + + # Check if it is a Perforce diff file. + if ($#diffs == -1) { + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = + Codestriker::FileParser::PerforceDiff->parse($tmpfh, + $repository); + } + + # Check if it is a VSS diff file. + if ($#diffs == -1) { + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = + Codestriker::FileParser::VssDiff->parse($tmpfh, + $repository); + } + + # Check if it is a patch unidiff file. + if ($#diffs == -1) { + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = + Codestriker::FileParser::PatchUnidiff->parse($tmpfh, + $repository); + } + + # Check if it is a patch basic file. + if ($#diffs == -1) { + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = + Codestriker::FileParser::PatchBasicDiff->parse($tmpfh, + $uploaded_filename); + } + + # Check if it is a ClearCase serial diff file. + if ($#diffs == -1) { + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = + Codestriker::FileParser::ClearCaseSerialDiff->parse($tmpfh, + $repository); + } + + # Last stop-gap - the file format is unknown, treat it as a + # single file with filename "unknown". + if ($#diffs == -1) { + if (! defined $uploaded_filename || $uploaded_filename eq '') { + $uploaded_filename = 'unknown.txt'; + } + seek($tmpfh, 0, 0) || + die "Unable to seek to the start of the temporary file: $!"; + @diffs = Codestriker::FileParser::UnknownFormat-> + parse($tmpfh, $uploaded_filename); + } } elsif ($content_type eq "application/gzip" || - $content_type eq "application/x-gzip") { - # Check if it is a gzip file. + $content_type eq "application/x-gzip") { + # Check if it is a gzip file. } elsif ($content_type eq "application/zip" || - $content_type eq "application/x-zip") { - # Check if it is a zip file. + $content_type eq "application/x-zip") { + # Check if it is a zip file. } # Restore the offset back to the start of the file again. seek($fh, 0, 0) || - die "Unable to seek to the start of the temporary file. $!"; + die "Unable to seek to the start of the temporary file. $!"; - if (defined $Codestriker::sort_diffs_by_filename && - $Codestriker::sort_diffs_by_filename) { - # Sort the diff chunks by filename, then old linenumber. - @diffs = sort { $a->{filename} cmp $b->{filename} || - $a->{old_linenumber} <=> $b->{old_linenumber} } @diffs; - } + if (defined $Codestriker::sort_diffs_by_filename && + $Codestriker::sort_diffs_by_filename) { + # Sort the diff chunks by filename, then old linenumber. + @diffs = sort { $a->{filename} cmp $b->{filename} || + $a->{old_linenumber} <=> $b->{old_linenumber} } @diffs; + } # Only include those files whose extension is not in # @Codestriker::exclude_file_types, provided it is defined. @@ -185,16 +184,16 @@ my @trimmed_diffs = (); foreach my $curr (@diffs) { - if ($curr->{filename} =~ /\.([^\.]+)(,v)?$/o) { - my $ext = $1; - push @trimmed_diffs, $curr - unless grep { $_ eq $ext } @Codestriker::exclude_file_types; - } else { - # No extension on this file, add the diff in. - push @trimmed_diffs, $curr; - } + if ($curr->{filename} =~ /\.([^\.]+)(,v)?$/o) { + my $ext = $1; + push @trimmed_diffs, $curr + unless grep { $_ eq $ext } @Codestriker::exclude_file_types; + } else { + # No extension on this file, add the diff in. + push @trimmed_diffs, $curr; + } } - + # Return the diffs found, if any. return @trimmed_diffs; } Index: BasicDiffUtils.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/FileParser/BasicDiffUtils.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- BasicDiffUtils.pm 15 Nov 2004 10:44:06 -0000 1.4 +++ BasicDiffUtils.pm 6 Sep 2008 00:31:44 -0000 1.5 @@ -26,106 +26,106 @@ my $new_length = 0; if ($line =~ /^(\d+)a(\d+),(\d+)$/o || - $line =~ /^\-\-\-\-\-\[after (\d+) inserted(?:\/moved)? (\d+)\-(\d+)(?: \(was at [\d\-]+\))?\]\-\-\-\-\-\s*$/o) { - # Added multiple lines of text. - $old_linenumber = $1+1; - $new_linenumber = $2; - $new_length = $3 - $2 + 1; + $line =~ /^\-\-\-\-\-\[after (\d+) inserted(?:\/moved)? (\d+)\-(\d+)(?: \(was at [\d\-]+\))?\]\-\-\-\-\-\s*$/o) { + # Added multiple lines of text. + $old_linenumber = $1+1; + $new_linenumber = $2; + $new_length = $3 - $2 + 1; } elsif ($line =~ /^(\d+)a(\d+)$/o || - $line =~ /^\-\-\-\-\-\[after (\d+) inserted(?:\/moved)? (\d+)(?: \(was at [\d\-]+\))?\]\-\-\-\-\-\s*$/o) { - # Added a single line of text. - $old_linenumber = $1+1; - $new_linenumber = $2; - $new_length = 1; + $line =~ /^\-\-\-\-\-\[after (\d+) inserted(?:\/moved)? (\d+)(?: \(was at [\d\-]+\))?\]\-\-\-\-\-\s*$/o) { + # Added a single line of text. + $old_linenumber = $1+1; + $new_linenumber = $2; + $new_length = 1; } elsif ($line =~ /^(\d+),(\d+)d(\d+)$/o || - $line =~ /^\-\-\-\-\-\[deleted(?:\/moved)? (\d+)\-(\d+) after (\d+)(?: \(now at [\d\-]+\))?\]\-\-\-\-\-\s*$/o) { - # Multiple lines deleted. - $old_linenumber = $1; - $new_linenumber = $3+1; - $old_length = $2 - $1 + 1; + $line =~ /^\-\-\-\-\-\[deleted(?:\/moved)? (\d+)\-(\d+) after (\d+)(?: \(now at [\d\-]+\))?\]\-\-\-\-\-\s*$/o) { + # Multiple lines deleted. + $old_linenumber = $1; + $new_linenumber = $3+1; + $old_length = $2 - $1 + 1; } elsif ($line =~ /^(\d+)d(\d+)$/o || - $line =~ /^\-\-\-\-\-\[deleted(?:\/moved)? (\d+) after (\d+)(?: \(now at [\d\-]+\))?\]\-\-\-\-\-\s*$/o) { - # Single line deleted. - $old_linenumber = $1; - $new_linenumber = $2+1; - $old_length = 1; + $line =~ /^\-\-\-\-\-\[deleted(?:\/moved)? (\d+) after (\d+)(?: \(now at [\d\-]+\))?\]\-\-\-\-\-\s*$/o) { + # Single line deleted. + $old_linenumber = $1; + $new_linenumber = $2+1; + $old_length = 1; } elsif ($line =~ /^(\d+),(\d+)c(\d+),(\d+)$/o || - $line =~ /^\-\-\-\-\-\[(\d+)\-(\d+) changed to (\d+)\-(\d+)\]\-\-\-\-\-\s*$/o) { - # Multiple text lines changed. - $old_linenumber = $1; - $new_linenumber = $3; - $old_length = $2 - $1 + 1; - $new_length = $4 - $3 + 1; + $line =~ /^\-\-\-\-\-\[(\d+)\-(\d+) changed to (\d+)\-(\d+)\]\-\-\-\-\-\s*$/o) { + # Multiple text lines changed. + $old_linenumber = $1; + $new_linenumber = $3; + $old_length = $2 - $1 + 1; + $new_length = $4 - $3 + 1; } elsif ($line =~ /^(\d+)c(\d+),(\d+)$/o || - $line =~ /^\-\-\-\-\-\[(\d+) changed to (\d+)\-(\d+)\]\-\-\-\-\-\s*$/o) { - # Multiple source lines changed to single line. - $old_linenumber = $1; - $new_linenumber = $2; - $old_length = 1; - $new_length = $3 - $2 + 1; + $line =~ /^\-\-\-\-\-\[(\d+) changed to (\d+)\-(\d+)\]\-\-\-\-\-\s*$/o) { + # Multiple source lines changed to single line. + $old_linenumber = $1; + $new_linenumber = $2; + $old_length = 1; + $new_length = $3 - $2 + 1; } elsif ($line =~ /^(\d+),(\d+)c(\d+)$/o || - $line =~ /^\-\-\-\-\-\[(\d+)\-(\d+) changed to (\d+)\]\-\-\-\-\-\s*$/o) { - # Single source line changed to multiple lines. - $old_linenumber = $1; - $new_linenumber = $3; - $old_length = $2 - $1 + 1; - $new_length = 1; + $line =~ /^\-\-\-\-\-\[(\d+)\-(\d+) changed to (\d+)\]\-\-\-\-\-\s*$/o) { + # Single source line changed to multiple lines. + $old_linenumber = $1; + $new_linenumber = $3; + $old_length = $2 - $1 + 1; + $new_length = 1; } elsif ($line =~ /^(\d+)c(\d+)$/o || - $line =~ /^\-\-\-\-\-\[(\d+) changed to (\d+)\]\-\-\-\-\-\s*$/o) { - # Single line changed to another line. - $old_linenumber = $1; - $new_linenumber = $2; - $old_length = 1; - $new_length = 1; + $line =~ /^\-\-\-\-\-\[(\d+) changed to (\d+)\]\-\-\-\-\-\s*$/o) { + # Single line changed to another line. + $old_linenumber = $1; + $new_linenumber = $2; + $old_length = 1; + $new_length = 1; } else { - # Some other file format. - return undef; + # Some other file format. + return undef; } - + # The chunk in unidiff format. my $chunk_text = ""; - + # First read the old lines, if any. for (my $i = 0; $i < $old_length; $i++) { - $line = <$fh>; - if (defined $line && $line =~ /^\< (.*)$/) { - $chunk_text .= "-${1}\n"; - } else { - # Some other format. - return undef; - } + $line = <$fh>; + if (defined $line && $line =~ /^\< (.*)$/) { + $chunk_text .= "-${1}\n"; + } else { + # Some other format. + return undef; + } } - + # If there is both old and new text, read the separator line. # Note bloody VSS for some versions will put the --- at the end of # the previous line rather than on a new line! if ($old_length > 0 && $new_length > 0) { - my $previous_line = $line; - my $pos = $fh->getpos; - $line = <$fh>; - return undef unless defined $line; - if ($line !~ /^\-\-\-$/o && $chunk_text =~ /^(.*)\-\-\-$/os) { - # Stupid VSS diff format, chop off the seperator characters - # and move the file pointer back. - $chunk_text = "$1\n"; - $fh->setpos($pos); - } elsif ($line !~ /^\-\-\-$/o) { - # Didn't match standard separator, some other format. - return undef; - } + my $previous_line = $line; + my $pos = $fh->getpos; + $line = <$fh>; + return undef unless defined $line; + if ($line !~ /^\-\-\-$/o && $chunk_text =~ /^(.*)\-\-\-$/os) { + # Stupid VSS diff format, chop off the seperator characters + # and move the file pointer back. + $chunk_text = "$1\n"; + $fh->setpos($pos); + } elsif ($line !~ /^\-\-\-$/o) { + # Didn't match standard separator, some other format. + return undef; + } } - + # Now read the new lines, if any. for (my $i = 0; $i < $new_length; $i++) { - $line = <$fh>; - if (defined $line && $line =~ /^\> (.*)$/) { - $chunk_text .= "+${1}\n"; - } else { - # Some other format. - return undef; - } + $line = <$fh>; + if (defined $line && $line =~ /^\> (.*)$/) { + $chunk_text .= "+${1}\n"; + } else { + # Some other format. + return undef; + } } - + # Now create the chunk object, and return it. my $chunk = {}; $chunk->{filename} = $filename; Index: PerforceDescribe.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/FileParser/PerforceDescribe.pm,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- PerforceDescribe.pm 29 Aug 2008 11:48:26 -0000 1.7 +++ PerforceDescribe.pm 6 Sep 2008 00:31:44 -0000 1.8 @@ -30,7 +30,7 @@ # Skip initial whitespace. my $line = <$fh>; while (defined($line) && $line =~ /^\s*$/) { - $line = <$fh>; + $line = <$fh>; } # Array of results found. @@ -51,8 +51,8 @@ # Skip the lines up to the table of contents. $line = <$fh>; while (defined($line) && $line !~ /^\.\.\./) { - $line = <$fh>; - return () unless defined $line; + $line = <$fh>; + return () unless defined $line; } # Now read the initial table of contents entries. For added or @@ -60,37 +60,37 @@ # repository, as it isn't included in the text of the diff, # unlike CVS. while (defined($line) && $line =~ /^\.\.\. (.*)\#(\d+) (.*)$/) { - my $entry = {}; - $entry->{filename} = $1; - $entry->{revision} = $2; - $entry->{change_type} = $3; - $entry->{repmatch} = 1; - $entry->{old_linenumber} = 0; - $entry->{new_linenumber} = 0; - $entry->{text} = ""; - if ($entry->{change_type} eq 'add') { - _retrieve_file($entry, $repository); - } elsif ($entry->{change_type} eq 'delete') { - # Need to retrieve the text of the previous revision number, - # as the current one is empty. - $entry->{revision}--; - _retrieve_file($entry, $repository); - $entry->{revision}++; - } else { - # Assume it is an edit, nothing else to do, as the diffs - # will be included below. - } - - # Add this to the table of contents array. - push @toc, $entry; - - $line = <$fh>; - return () unless defined $line; + my $entry = {}; + $entry->{filename} = $1; + $entry->{revision} = $2; + $entry->{change_type} = $3; + $entry->{repmatch} = 1; + $entry->{old_linenumber} = 0; + $entry->{new_linenumber} = 0; + $entry->{text} = ""; + if ($entry->{change_type} eq 'add') { + _retrieve_file($entry, $repository); + } elsif ($entry->{change_type} eq 'delete') { + # Need to retrieve the text of the previous revision number, + # as the current one is empty. + $entry->{revision}--; + _retrieve_file($entry, $repository); + $entry->{revision}++; + } else { + # Assume it is an edit, nothing else to do, as the diffs + # will be included below. + } + + # Add this to the table of contents array. + push @toc, $entry; + + $line = <$fh>; + return () unless defined $line; } # Skip the lines until the first diff chunk. while (defined($line) && $line !~ /^==== /) { - $line = <$fh>; + $line = <$fh>; } # Now read the actual diff chunks. Any entries not here will be added @@ -98,66 +98,66 @@ # retrieved from the repository. my $toc_index = 0; while (defined($line) && $line =~ /^====/) { - # Read the next diff chunk. - return () unless $line =~ /^==== (.*)\#(\d+) \((.*)\) ====$/; - my $filename = $1; - my $revision = $2; - my $filetype = $3; - - # Check if there are any outstanding added/removed entries from the - # toc that need to be processed first. - my $entry = $toc[$toc_index]; - while ($entry->{filename} ne $filename) { - my $chunk = _make_chunk($entry); - push @result, $chunk; - - # Check the next TOC entry, if any. - last if ($toc_index >= $#toc); - - $toc_index++; - $entry = $toc[$toc_index]; - } - - # Skip the next blank line before the unidiff. - $line = <$fh>; - next unless defined $line; - - if ($filetype =~ /.*text/) { - # Now read the entire diff chunk. - # Note there may be an optional '---' and '+++' lines - # before the chunk. - my $lastpos = tell $fh; - if (<$fh> !~ /^\-\-\-/ || <$fh> !~ /^\+\+\+/) { - # Move the file pointer back. - seek $fh, $lastpos, 0; - } - - my @file_diffs = Codestriker::FileParser::UnidiffUtils-> - read_unidiff_text($fh, $filename, $revision, $repmatch); - push @result, @file_diffs; - } else { - # Assume it is a binary file, initialise the chunk from the - # TOC entry, and flag it as binary. - my $chunk = _make_chunk($entry); - $chunk->{binary} = 1; - push @result, $chunk; - } - - # Move on to the next entry in the TOC. - $toc_index++; - - # Skip the next blank line before the next chunk. - $line = <$fh>; - while (defined $line && $line =~ /^\s*$/) { - $line = <$fh>; - } + # Read the next diff chunk. + return () unless $line =~ /^==== (.*)\#(\d+) \((.*)\) ====$/; + my $filename = $1; + my $revision = $2; + my $filetype = $3; + + # Check if there are any outstanding added/removed entries from the + # toc that need to be processed first. + my $entry = $toc[$toc_index]; + while ($entry->{filename} ne $filename) { + my $chunk = _make_chunk($entry); + push @result, $chunk; + + # Check the next TOC entry, if any. + last if ($toc_index >= $#toc); + + $toc_index++; + $entry = $toc[$toc_index]; + } + + # Skip the next blank line before the unidiff. + $line = <$fh>; + next unless defined $line; + + if ($filetype =~ /.*text/) { + # Now read the entire diff chunk... [truncated message content] |
From: <si...@us...> - 2008-09-02 06:44:29
|
User: sits Date: 08/09/01 23:44:28 Modified: lib/Codestriker/Http Response.pm Log: Minor tweak to get the links to the html directory working for classic URLs. Index: Response.pm =================================================================== RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Http/Response.pm,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- Response.pm 2 Sep 2008 06:36:16 -0000 1.50 +++ Response.pm 2 Sep 2008 06:44:28 -0000 1.51 @@ -231,7 +231,7 @@ } else { # Use the default CSS file. $codestriker_css = $query->url(); - if (defined $Codestriker::cgi_style && $Codestriker::cgi_style) { + if (! defined $Codestriker::cgi_style || $Codestriker::cgi_style) { $codestriker_css =~ s#/[^/]+?/codestriker\.pl#/codestrikerhtml/codestriker.css#; } else { $codestriker_css = $query->url() . "/html/codestriker.css"; |
From: <si...@us...> - 2008-09-02 06:38:28
|
User: sits Date: 08/09/01 23:38:27 Modified: . Makefile Log: Make sure all the files in bin are executable when creating the zip/tar file. Index: Makefile =================================================================== RCS file: /cvsroot/codestriker/codestriker/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- Makefile 19 Aug 2003 21:46:55 -0000 1.3 +++ Makefile 2 Sep 2008 06:38:27 -0000 1.4 @@ -28,7 +28,8 @@ build: build-docs $(RM) -fr $(BUILD_DIR) $(MKDIR) -p $(BUILD_DIR) - $(RSYNC) -Cavz bin/ $(BUILD_DIR)/bin/ + $(RSYNC) -Cavz bin/ $(BUILD_DIR)/bin/ + chmod +x $(BUILD_DIR)/bin/* $(RSYNC) -Cavz lib/ $(BUILD_DIR)/lib/ $(RSYNC) -Cavz html/ $(BUILD_DIR)/html/ $(RSYNC) -Cavz cgi-bin/ $(BUILD_DIR)/cgi-bin/ |