]> ruin.nu Git - ndwebbie.git/blobdiff - lib/NDWeb/Controller/Wiki.pm
Be more paranoid with param in list context
[ndwebbie.git] / lib / NDWeb / Controller / Wiki.pm
index d15c609672670e43b3f9dbd477a0383f23b21229..60f210d266b80e9e3282dd9b91c61982c085272e 100644 (file)
@@ -29,16 +29,22 @@ sub auto : Priate {
        $c->stash(wikiformat => \&wikiformat);
 }
 
-sub index :Path :Args(0) {
-       my ( $self, $c ) = @_;
+sub index :Path :Args(1) {
+       my ( $self, $c, $page ) = @_;
 
-       push @{$c->req->captures}, ('Info','Main');
-       $c->forward('page');
+       $c->forward('page',$page);
        $c->stash(template => 'wiki/page.tt2');
 }
 
-sub page : LocalRegex(^(?:([A-Z]\w*)(?::|%3A))?([A-Z]\w*)$) {
+sub main :Path :Args(0) {
        my ( $self, $c ) = @_;
+
+       $c->forward('page', ['Info:Main']);
+       $c->stash(template => 'wiki/page.tt2');
+}
+
+sub page : Private {
+       my ( $self, $c, $p ) = @_;
        my $dbh = $c->model;
 
        $c->forward('findPage');
@@ -47,8 +53,8 @@ sub page : LocalRegex(^(?:([A-Z]\w*)(?::|%3A))?([A-Z]\w*)$) {
        $c->forward('loadText');
 
        unless ($c->stash->{page}->{wpid}){
-               $c->stash->{page}->{namespace} = $c->req->captures->[0];
-               $c->stash->{page}->{name} = $c->req->captures->[1];
+               $c->stash->{page}->{namespace} = $c->stash->{namespace};
+               $c->stash->{page}->{name} = $c->stash->{name};
                $c->stash->{page}->{fullname} = ($c->stash->{page}->{namespace} ? $c->stash->{page}->{namespace}.':' : '')
                        . $c->stash->{page}->{name};
                $c->stash->{page}->{post} = $dbh->selectrow_array(q{SELECT post
@@ -59,8 +65,8 @@ sub page : LocalRegex(^(?:([A-Z]\w*)(?::|%3A))?([A-Z]\w*)$) {
        $c->stash(title => $c->stash->{page}->{fullname});
 }
 
-sub edit : LocalRegex(^edit/(?:([A-Z]\w*)(?::|%3A))?([A-Z]\w*)$) {
-       my ( $self, $c ) = @_;
+sub edit :Local :Args(1) {
+       my ( $self, $c, @p ) = @_;
        my $dbh = $c->model;
 
        $c->forward('findPage');
@@ -72,12 +78,12 @@ sub edit : LocalRegex(^edit/(?:([A-Z]\w*)(?::|%3A))?([A-Z]\w*)$) {
        unless ($c->stash->{page}->{wpid}){
                $c->acl_access_denied('test',$c->action,'No edit access for this page')
                        unless @{$c->stash->{namespaces}};
-               $c->stash->{page}->{namespace} = $c->req->captures->[0];
-               $c->stash->{page}->{name} = $c->req->captures->[1];
+               $c->stash->{page}->{namespace} = $c->stash->{namespace};
+               $c->stash->{page}->{name} = $c->stash->{name};
        }
 }
 
-sub history : LocalRegex(^history/(?:([A-Z]\w*)(?::|%3A))?([A-Z]\w*)$) {
+sub history :Local :Args(1) {
        my ( $self, $c ) = @_;
        my $dbh = $c->model;
 
@@ -97,18 +103,24 @@ sub postedit : Local {
        my ( $self, $c, $p ) = @_;
        my $dbh = $c->model;
 
+       my $ns = $c->req->param('namespace');
+       my $name = $c->req->param('name');
+       my $text = $c->req->param('text');
        eval {
                $dbh->begin_work;
 
                my $wpid = $c->req->param('wpid');
                if ( $wpid eq 'new'){
+                       unless ($c->req->param('name') =~ /^([A-Z]\w*)$/){
+                               die 'The name is not valid, start with a capital letter and only use alphanumerical characters or _ for the rest';
+                       }
                        my $namespace = $dbh->selectrow_array(q{SELECT namespace
                                FROM wiki_namespace_access
                                WHERE namespace = $1 AND post AND gid IN (SELECT groups($2))
-                       },undef,$c->req->param('namespace'), $c->stash->{UID});
+                       },undef,$ns, $c->stash->{UID});
 
                        my $query = $dbh->prepare(q{INSERT INTO wiki_pages (namespace,name) VALUES($1,$2) RETURNING wpid});
-                       $query->execute($namespace,$c->req->param('name'));
+                       $query->execute($namespace,$name);
                        $wpid = $query->fetchrow;
                }
                $c->forward('findPage',[$wpid]);
@@ -120,8 +132,10 @@ sub postedit : Local {
                        RETURNING wprev
                        });
                $c->req->params->{parent}||= undef;
-               $query->execute($wpid,$c->req->param('parent'),$c->req->param('text')
-                       ,$c->req->param('comment'),$c->stash->{UID});
+               my $parent = $c->req->param('parent');
+               my $comment = $c->req->param('comment');
+               $query->execute($wpid,$parent,$text
+                       ,$comment,$c->stash->{UID});
                my $rev = $query->fetchrow;
                $dbh->do(q{UPDATE wiki_pages SET wprev = $1 WHERE wpid = $2}
                        ,undef,$rev,$wpid);
@@ -145,25 +159,64 @@ sub postedit : Local {
        $c->forward('findPage') if $p;
        $c->forward('findNamespaces');
 
-       $c->stash->{page}->{namespace} = $c->req->param('namespace');
-       $c->stash->{page}->{name} = $c->req->param('name');
+       $c->stash->{page}->{namespace} = $ns;
+       $c->stash->{page}->{name} = $name;
 
-       $c->stash(text => $c->req->param('text'));
+       $c->stash(text => $text);
        $c->stash(template => 'wiki/edit.tt2');
 }
 
+sub search : Local {
+       my ( $self, $c ) = @_;
+       my $dbh = $c->model;
+
+       if ($c->req->param('search')){
+               $c->stash(search => $c->req->param('search'));
+               my $queryfunc = 'plainto_tsquery';
+               $queryfunc = 'to_tsquery' if $c->req->param('advsearch');
+               my $posts = $dbh->prepare(q{SELECT wp.wpid,namespace,name
+                       ,(CASE WHEN namespace <> '' THEN namespace || ':' ELSE '' END) || name AS fullname
+                       ,ts_headline(wpr.text,}.$queryfunc.q{($2)) AS headline
+                       ,ts_rank_cd(textsearch, }.$queryfunc.q{($2),32) AS rank
+                       FROM wiki_pages wp
+                               JOIN wiki_page_revisions wpr USING (wprev)
+                       WHERE (namespace IN (SELECT namespace FROM wiki_namespace_access WHERE gid IN (SELECT groups($1)))
+                                       OR wp.wpid IN (SELECT wpid FROM wiki_page_access WHERE uid = $1))
+                               AND textsearch @@ }.$queryfunc.q{($2)
+                       ORDER BY rank DESC
+               });
+               eval {
+                       my $search = $c->req->param('search');
+                       $posts->execute($c->stash->{UID},$search);
+                       my @posts;
+                       while (my $post = $posts->fetchrow_hashref){
+                               push @posts,$post;
+                       }
+                       $c->stash(searchresults => \@posts);
+               };
+               if ($@){
+                       $c->stash( searcherror => $dbh->errstr);
+               }
+       }
+
+}
+
 sub findPage : Private {
        my ( $self, $c, $p ) = @_;
        my $dbh = $c->model;
 
        my @arguments = ($c->stash->{UID});
        my $where;
-       if ($p){
+       if ($p =~ /^\d+$/){
                $where =  q{AND wpid = $2};
                push @arguments, $p;
-       }else{
+       } elsif ($p =~ /^(?:([A-Z]\w*):)?([A-Z]\w*)$/){
                $where = q{AND (namespace = COALESCE($2,'') AND name = $3)};
-               push @arguments, @{$c->req->captures};
+               push @arguments, $1, $2;
+               $c->stash(namespace => $1);
+               $c->stash(name => $2);
+       } else {
+               $c->detach('/default');
        }
 
        my $query = q{SELECT wpid,namespace,name,wprev