Bladeren bron

more admin routes, start of acls

George S. Baugh 5 jaren geleden
bovenliggende
commit
a3abc3908f

+ 2 - 1
lib/Trog/Config.pm

@@ -5,9 +5,10 @@ use warnings;
 
 use Config::Simple;
 
+our $home_cfg = "$ENV{HOME}/.tcms/main.cfg";
+
 sub get {
     my $cf;
-    my $home_cfg = "$ENV{HOME}/.tcms/main.cfg"; #XXX probably should pass this in and sanitize ENV
     $cf = Config::Simple->new($home_cfg) if -f $home_cfg;
     return $cf if $cf;
     $cf = Config::Simple->new('config/default.cfg');

+ 72 - 12
lib/Trog/Routes/HTML.pm

@@ -18,13 +18,12 @@ $theme_dir = "themes/".$conf->param('general.theme') if $conf->param('general.th
 
 use lib 'www';
 
-# TODO Things which should be themable
-our $landing_page = 'default.tx';
+our $landing_page  = 'default.tx';
 our $htmltitle     = 'title.tx';
 our $midtitle      = 'midtitle.tx';
-our $rightbar     = 'rightbar.tx';
-our $leftbar      = 'leftbar.tx';
-our $footbar      = 'footbar.tx';
+our $rightbar      = 'rightbar.tx';
+our $leftbar       = 'leftbar.tx';
+our $footbar       = 'footbar.tx';
 
 our %routes = (
     default => {
@@ -159,27 +158,50 @@ sub index ($query, $input, $render_cb, $content = '', $i_styles = []) {
 
 These are things that issue returns other than 200, and are not directly accessible by users via any defined route.
 
+=head2 notfound, forbidden, badrequest
+
+Implements the 4XX status codes.  Override templates named the same for theming this.
+
 =cut
 
-sub notfound ($query,$input,$render_cb) {
-    $query->{code} = 404;
+sub _generic_route ($rname, $code, $title, $query,$input,$render_cb) {
+    $query->{code} = $code;
 
     my $processor = Text::Xslate->new(
-        path   => _dir_for_resource('notfound.tx'),
+        path   => _dir_for_resource("$rname.tx"),
     );
 
-    my $styles = _build_themed_styles('notfound.css');
-    my $content = $processor->render('notfound.tx', {
-        title    => "Return to Sender, Address unknown",
+    my $styles = _build_themed_styles("$rname.css");
+    my $content = $processor->render("$rname.tx", {
+        title    => $title,
         route    => $query->{route},
+        styles   => $styles,
     });
     return Trog::Routes::HTML::index($query, $input, $render_cb, $content, $styles);
 }
 
+sub notfound (@args) {
+    return _generic_route('notfound',404,"Return to sender, Address unknown", @args);
+}
+
+sub forbidden (@args) {
+    return _generic_route('forbidden', 403, "STAY OUT YOU RED MENACE", @args);
+}
+
+sub badrequest (@args) {
+    return _generic_route('badrequest', 400, "Bad Request", @args);
+}
+
+# TODO Rate limiting route
+
 =head1 NORMAL ROUTES
 
 These are expected to either return a 200, or redirect to something which does.
 
+=head2 setup
+
+One time setup page; should only display to the first user to visit the site which we presume to be the administrator.
+
 =cut
 
 sub setup ($query, $input, $render_cb) {
@@ -190,6 +212,12 @@ sub setup ($query, $input, $render_cb) {
     });
 }
 
+=head2 login
+
+Sets the user cookie if the provided user exists, or sets up the user as an admin with the provided credentials in the event that no users exist.
+
+=cut
+
 sub login ($query, $input, $render_cb) {
 
     # Redirect if we actually have a logged in user.
@@ -237,6 +265,12 @@ sub login ($query, $input, $render_cb) {
     }, @headers);
 }
 
+=head2 config
+
+Renders the configuration page, or redirects you back to the login page.
+
+=cut
+
 sub config ($query, $input, $render_cb) {
     if (!$query->{user}) {
         $query->{to} = '/config';
@@ -286,6 +320,12 @@ sub _get_data_models {
     return \@dmods
 }
 
+=head2 config_save
+
+Implements /config/save route.  Saves what little configuration we actually use to ~/.tcms/tcms.conf
+
+=cut
+
 sub config_save ($query, $input, $render_cb) {
     my $postdata = _input2postdata($input);
     $conf->param( 'general.theme',      $postdata->{theme} )      if defined $postdata->{theme};
@@ -293,7 +333,7 @@ sub config_save ($query, $input, $render_cb) {
 
     $query->{failure} = 1;
     $query->{message} = "Failed to save configuration!";
-    if ($conf->save()) {
+    if ($conf->save($Trog::Config::home_config)) {
         $query->{failure} = 0;
         $query->{message} = "Configuration updated succesfully.";
     }
@@ -306,6 +346,12 @@ sub profile ($query, $input, $render_cb) {
     return config($query, $input, $render_cb);
 }
 
+=head2 themeclone
+
+Clone a theme by copying a directory.
+
+=cut
+
 sub themeclone ($query, $input, $render_cb) {
     my $postdata = _input2postdata($input);
     my ($theme, $newtheme) = ($postdata->{theme},$postdata->{newtheme});
@@ -322,6 +368,12 @@ sub themeclone ($query, $input, $render_cb) {
     return config($query, $input, $render_cb);
 }
 
+=head2 post
+
+Display the route for making new posts.
+
+=cut
+
 sub post ($query, $input, $render_cb) {
     if (!$query->{user}) {
         $query->{to} = '/config';
@@ -336,6 +388,7 @@ sub post ($query, $input, $render_cb) {
 
     return $render_cb->('post.tx', {
         title       => 'New Post',
+        post_visibilities => ['public', 'private', 'unlisted'],
         stylesheets => $css,
         scripts     => $js,
         posts       => $posts,
@@ -350,10 +403,17 @@ sub post ($query, $input, $render_cb) {
     });
 }
 
+#TODO actually do stuff
 sub post_save ($query, $input, $render_cb) {
     return post($query, $input, $render_cb);
 }
 
+=head2 posts
+
+Display multi or single posts, supports RSS and pagination.
+
+=cut
+
 sub posts ($query, $input, $render_cb) {
     my $tags = _coerce_array($query->{tag});
     my $posts = _post_helper($query, $tags);

+ 2 - 2
www/server.psgi

@@ -78,7 +78,7 @@ my $app = sub {
 
     #Disallow any paths that are naughty ( starman auto-removes .. up-traversal)
     if (index($path,'/templates') == 0 || $path =~ m/.*\.psgi$/i ) {
-        return [ 403, [$content_types{plain}], ["STAY OUT YOU RED MENACE"]];
+        return Trog::Routes::HTML::forbidden($query,$env->{'psgi.input'}, \&_render);
     }
 
     # If it's just a file, serve it up
@@ -102,7 +102,7 @@ my $app = sub {
 
     #TODO reject inappropriate content-lengths
     return Trog::Routes::HTML::notfound($query,$env->{'psgi.input'}, \&_render) unless exists $routes{$path};
-    return [ 400, [$content_types{plain}], ["BAD REQUEST"]] unless $routes{$path}{method} eq $env->{REQUEST_METHOD};
+    return Trog::Routes::HTML::badrequest($query,$env->{'psgi.input'}, \&_render) unless $routes{$path}{method} eq $env->{REQUEST_METHOD};
 
     @{$query}{keys(%{$routes{$path}{'data'}})} = values(%{$routes{$path}{'data'}}) if ref $routes{$path}{'data'} eq 'HASH' && %{$routes{$path}{'data'}};
 

+ 3 - 0
www/templates/badrequest.tx

@@ -0,0 +1,3 @@
+400 Bad Request
+<br /><br />
+See the SiteMap <a href="/sitemap">here</a> as to the valid ways to communicate with this website.

+ 6 - 0
www/templates/blog.tx

@@ -1,5 +1,11 @@
 <form class="Submissions" action="/post/save" method="POST">
     Title *<br /><input class="cooltext" type="text" name="title" placeholder="Iowa Man Destroys Moon" />
+    Visibility<br />
+    <select class="cooltext" name="visibility">
+        : for $post_visibilities -> $visibility {
+            <option value="<: $visibility :>"><: $visibility :></option>
+        : }
+    </select>
     Content<br /><textarea class="cooltext" name="comment" placeholder="Potzrebie"></textarea>
     <input type="hidden" name="app" value="blog" />
     <input class="coolbutton" type="submit" value="Publish" text="Publish" />

+ 6 - 0
www/templates/file.tx

@@ -3,6 +3,12 @@
     File *<br /><input class="cooltext" type="file" name="file" />
     <br /> TODO: Add "alternative" links, which scrape the appropriate icon for the alt link from the favicon<br />
     Preview Image<br /><input type="file" class="cooltext" name="preview" placeholder="PROMO.JPG"></input>
+    Visibility<br />
+    <select class="cooltext" name="visibility">
+        : for $post_visibilities -> $visibility {
+            <option value="<: $visibility :>"><: $visibility :></option>
+        : }
+    </select>
     Comments<br /><textarea class="cooltext" name="comment" placeholder="Potzrebie"></textarea>
     <input type="hidden" name="app" value="file" />
     <input class="coolbutton" type="submit" value="Publish" text="Publish" />

+ 3 - 0
www/templates/forbidden.tx

@@ -0,0 +1,3 @@
+403 Forbidden
+<br /><br />
+Log in <a href="/login?to=<: $route :>">here</a>.

+ 6 - 0
www/templates/microblog.tx

@@ -4,6 +4,12 @@
     Image<br /><input class="cooltext" type="text" name="IMG" placeholder="https://gifdump.tld/Advice_Dog.jpg" />
     Audio<br /><input class="cooltext" type="text" name="AUD" placeholder="https://soundclod.com/static.mp3"/>
     Video<br /><input class="cooltext" type="text" name="VID" placeholder="https://youvimeo.tv/infomercial.mp4" />
+    Visibility<br />
+    <select class="cooltext" name="visibility">
+        : for $post_visibilities -> $visibility {
+            <option value="<: $visibility :>"><: $visibility :></option>
+        : }
+    </select>
     Comments<br /><textarea class="cooltext" name="comment" placeholder="Potzrebie"></textarea>
     <input type="hidden" name="app" value="microblog" />
     <input class="coolbutton" type="submit" value="Publish" text="Publish" />