Compare commits

..

2 Commits

17 changed files with 152 additions and 139 deletions

View File

@ -12,39 +12,39 @@ use CharmBoard::Util::Crypt::Seasoning;
# this method will run once at server start # this method will run once at server start
sub startup { sub startup {
my $self = shift; my $app = shift;
# load plugins that require no additional conf # load plugins that require no additional conf
$self->plugin('TagHelpers'); $app->plugin('TagHelpers');
$self->plugin('Model', {namespaces => ['CharmBoard::Model']}); $app->plugin('Model', {namespaces => ['CharmBoard::Model']});
# load configuration from config file # load configuration from config file
my $config = my $config =
$self->plugin('Config' => { file => 'charmboard.conf' }); $app->plugin('Config' => { file => 'charmboard.conf' });
# set this specific forum's name # set this specific forum's name
$self->helper(board_name => sub { $config->{board_name} }); $app->helper(board_name => sub { $config->{board_name} });
# load dev env only stuff, if applicable # load dev env only stuff, if applicable
if (lc($config->{environment}) eq 'dev') { if (lc($config->{environment}) eq 'dev') {
$self->renderer->cache->max_keys(0) $app->renderer->cache->max_keys(0)
} }
# import Mojolicious secrets # import Mojolicious secrets
$self->secrets($config->{secrets}); $app->secrets($config->{secrets});
# import password pepper value # import password pepper value
$self->helper(pepper => sub { $config->{pass_crypt}->{pepper} }); $app->helper(pepper => sub { $config->{pass_crypt}->{pepper} });
## database setup ## database setup
# ? this could maybe be a given/when # ? this could maybe be a given/when
{ {
my ($_dsn, $_unicode); my ($_dsn, $_unicode);
if (lc($self->config->{database}->{type}) eq 'sqlite') { if (lc($app->config->{database}->{type}) eq 'sqlite') {
$_dsn = "dbi:SQLite:" . $config->{database}->{name}; $_dsn = "dbi:SQLite:" . $config->{database}->{name};
$_unicode = "sqlite_unicode" $_unicode = "sqlite_unicode"
} elsif (lc($self->config->{database}->{type}) eq 'mariadb') { } elsif (lc($app->config->{database}->{type}) eq 'mariadb') {
$_dsn = "dbi:mysql:" . $config->{database}->{name}; $_dsn = "dbi:mysql:" . $config->{database}->{name};
$_unicode = "mysql_enable_utf" $_unicode = "mysql_enable_utf"
@ -63,18 +63,18 @@ sub startup {
{ $_unicode => 1 } { $_unicode => 1 }
); );
$self->helper(schema => sub { $schema }) $app->helper(schema => sub { $schema })
} }
# session helpers # session helpers
## create session ## create session
$self->helper(session_create => sub { $app->helper(session_create => sub {
my $self = shift; my $app = shift;
my $_session_key = seasoning(16); my $_session_key = seasoning(16);
# create session entry in db # create session entry in db
$self->schema->resultset('Session')->create({ $app->schema->resultset('Session')->create({
session_key => $_session_key, session_key => $_session_key,
user_id => $_[0], user_id => $_[0],
session_expiry => time + 604800, session_expiry => time + 604800,
@ -83,64 +83,69 @@ sub startup {
}); });
# now create session cookie # now create session cookie
$self->session(is_auth => 1 ); $app->session(is_auth => 1 );
$self->session(user_id => $_[0] ); $app->session(user_id => $_[0] );
$self->session(session_key => $_session_key); $app->session(session_key => $_session_key);
$self->session(expiration => 604800 ); $app->session(expiration => 604800 );
}); });
## destroy session ## destroy session
$self->helper(session_destroy => sub { $app->helper(session_destroy => sub {
my $self = shift; my $app = shift;
my $_session_key = $self->session('session_key'); my $_session_key = $app->session('session_key');
# destroy entry for this session in the database # destroy entry for this session in the database
$self->schema->resultset('Session') $app->schema->resultset('Session')
->search({ session_key => $_session_key }) ->search({ session_key => $_session_key })
->delete; ->delete;
# now nuke the actual session cookie # now nuke the actual session cookie
$self->session(expires => 1); $app->session(expires => 1);
}); });
## verify session ## verify session
$self->helper(session_verify => sub { $app->helper(session_verify => sub {
my $self = shift; my $app = shift;
# get info from user's session cookie and store it in vars
my $_user_id = $self->session('user_id');
my $_session_key = $self->session('session_key');
my $_validity = 1; my $_validity = 1;
my $_catch_error; my $_catch_error;
# get info from user's session cookie and store it in vars
my $_user_id = $app->session('user_id');
my $_session_key = $app->session('session_key');
my $_is_auth = $app->session('is_auth');
if ($_is_auth) {
try { try {
# check to see if session with this id is present in db # check to see if session with this id is present in db
($self->schema->resultset('Session')->search ($app->schema->resultset('Session')->search
({ 'session_key' => $_session_key }) ({ 'session_key' => $_session_key })
->get_column('session_key')->first) ->get_column('session_key')->first)
or die; or die;
# check to see if the current session key's user id matches # check to see if the current session key's user id matches
# that of the user id in the database # that of the user id in the database
$_user_id == ($self->schema->resultset('Session')-> $_user_id == ($app->schema->resultset('Session')->
session_uid($_session_key)) session_uid($_session_key))
or die; or die;
# check if session is still within valid time as recorded in # check if session is still within valid time as recorded in
# the db # the db
time < ($self->schema->resultset('Session')-> time < ($app->schema->resultset('Session')->
session_expiry($_session_key)) session_expiry($_session_key))
or die; or die;
} catch ($_catch_error) { } catch ($_catch_error) {
$_validity = undef; $_validity = undef;
$self->session_destroy; $app->session_destroy;
}
} else {
$_validity = 0;
} }
return $_validity; return $_validity;
}); });
# router # router
my $r = $self->routes; my $r = $app->routes;
# controller routes # controller routes
## index page ## index page

View File

@ -10,11 +10,15 @@ use Mojo::Base 'Mojolicious::Controller', -signatures;
use Tree::Simple; use Tree::Simple;
sub index { sub index {
my $self = shift; my $c = shift;
$self->render( if ($c->session_verify eq undef) {
$c->redirect_to('/')
}
$c->render(
template => 'index', template => 'index',
category_tree => $self->model('forums')->list_full category_tree => $c->model('forums')->list_full
) )
} }

View File

@ -11,19 +11,19 @@ use CharmBoard::Util::Crypt::Password;
use CharmBoard::Util::Crypt::Seasoning; use CharmBoard::Util::Crypt::Seasoning;
sub login { sub login {
my $self = shift; my $c = shift;
$self->render( $c->render(
template => 'login', template => 'login',
error => $self->flash('error'), error => $c->flash('error'),
message => $self->flash('message') message => $c->flash('message')
) )
} }
sub login_do { sub login_do {
my $self = shift; my $c = shift;
my $username = $self->param('username'); my $username = $c->param('username');
my $password = $self->pepper . ':' . $self->param('password'); my $password = $c->pepper . ':' . $c->param('password');
my $catch_error; my $catch_error;
@ -34,7 +34,7 @@ sub login_do {
# check user credentials first # check user credentials first
try { try {
# check to see if user by entered username exists # check to see if user by entered username exists
$user_info = $self->schema->resultset('Users') $user_info = $c->schema->resultset('Users')
->search({ username => $username }); ->search({ username => $username });
$user_info or die; $user_info or die;
@ -45,27 +45,27 @@ sub login_do {
} catch ($catch_error) { # redirect to login page on fail } catch ($catch_error) { # redirect to login page on fail
print $catch_error; print $catch_error;
$self->flash(error => 'Username or password incorrect.'); $c->flash(error => 'Username or password incorrect.');
$self->redirect_to('login'); $c->redirect_to('login');
} }
try { # now attempt to create session try { # now attempt to create session
# get user ID for session creation # get user ID for session creation
$user_id = $user_info->get_column('user_id')->first; $user_id = $user_info->get_column('user_id')->first;
$self->session_create($user_id); $c->session_create($user_id);
# redirect to index upon success # redirect to index upon success
$self->redirect_to('/') $c->redirect_to('/')
} catch ($catch_error) { # redirect to login page on fail } catch ($catch_error) { # redirect to login page on fail
print $catch_error; print $catch_error;
$self->flash( $c->flash(
error => 'Your username and password were correct, but a server error => 'Your username and password were correct, but a server
error prevented you from logging in. This has been logged error prevented you from logging in. This has been logged
so the administrator can fix it.' so the administrator can fix it.'
); );
$self->redirect_to('login') $c->redirect_to('login')
} }
} }

View File

@ -9,12 +9,12 @@ use feature ':5.20';
use Mojo::Base 'Mojolicious::Controller', -signatures; use Mojo::Base 'Mojolicious::Controller', -signatures;
sub logout_do { sub logout_do {
my $self = shift; my $c = shift;
$self->session_destroy; $c->session_destroy;
# redirect to index # redirect to index
$self->redirect_to('/') $c->redirect_to('/')
} }
1; 1;

View File

@ -9,32 +9,33 @@ use feature ':5.20';
use Mojo::Base 'Mojolicious::Controller', -signatures; use Mojo::Base 'Mojolicious::Controller', -signatures;
sub thread_compose { sub thread_compose {
my $self = shift; my $c = shift;
my $subf_id = $self->param('id'); my $subf_id = $c->param('id');
my $subf_cat = my $subf_cat =
$self->schema->resultset('Subforums')->cat_from_id($subf_id); $c->schema->resultset('Subforums')->cat_from_id($subf_id);
my $cat_title = my $cat_title =
$self->schema->resultset('Categories') $c->schema->resultset('Categories')
->title_from_id($subf_cat); ->title_from_id($subf_cat);
$self->render( $c->render(
template => 'thread_compose', template => 'thread_compose',
subf_id => $subf_id, subf_id => $subf_id,
cat_title => $cat_title, cat_title => $cat_title,
subf_title => $self->schema->resultset('Subforums') subf_title => $c->schema->resultset('Subforums')
->title_from_id($subf_id), ->title_from_id($subf_id),
error => $self->flash('error'), error => $c->flash('error'),
message => $self->flash('message') message => $c->flash('message')
) )
} }
sub thread_submit { sub thread_submit {
my $self = shift; my $c = shift;
my $thread_title = $self->param('thread-title'); my $thread_title = $c->param('thread-title');
my $post_content = $self->param('post-content'); my $post_content = $c->param('post-content');
my $post_time = time; my $post_time = time;
my $subf_id = $c->param('id');
my $catch_error; my $catch_error;
@ -43,9 +44,12 @@ sub thread_submit {
($thread_title, $post_content) ($thread_title, $post_content)
or die "Please fill both the title and post content fields" or die "Please fill both the title and post content fields"
} catch ($catch_error) { } catch ($catch_error) {
$self->flash(error => $catch_error); $c->flash(error => $catch_error);
$self->redirect_to('/:id/new') $c->redirect_to('board/:id/new')
} }
# now send it
} }
1; 1;

View File

@ -11,22 +11,22 @@ use CharmBoard::Util::Crypt::Password;
# initial registration page # initial registration page
sub register { sub register {
my $self = shift; my $c = shift;
$self->render( $c->render(
template => 'register', template => 'register',
error => $self->flash('error'), error => $c->flash('error'),
message => $self->flash('message') message => $c->flash('message')
) )
} }
# process submitted registration form # process submitted registration form
sub register_do { sub register_do {
my $self = shift; my $c = shift;
my $username = $self->param('username'); my $username = $c->param('username');
my $email = $self->param('email'); my $email = $c->param('email');
my $password = $self->param('password'); my $password = $c->param('password');
my $confirm_password = $self->param('confirm-password'); my $confirm_password = $c->param('confirm-password');
my $catch_error; my $catch_error;
@ -50,9 +50,9 @@ sub register_do {
# check to make sure username and/or email isn't already in use; # check to make sure username and/or email isn't already in use;
# if not, continue with registration # if not, continue with registration
## search for input username and email in database ## search for input username and email in database
$user_check = $self->schema->resultset('Users') $user_check = $c->schema->resultset('Users')
->search({ username => $username })->single; ->search({ username => $username })->single;
$email_check = $self->schema->resultset('Users') $email_check = $c->schema->resultset('Users')
->search({ email => $email })->single; ->search({ email => $email })->single;
# TODO: compress this into something less redundant # TODO: compress this into something less redundant
@ -63,18 +63,18 @@ sub register_do {
($email_check) eq undef ($email_check) eq undef
or die "email already in use." or die "email already in use."
} catch ($catch_error) { } catch ($catch_error) {
$self->flash(error => $catch_error); $c->flash(error => $catch_error);
$self->redirect_to('register') $c->redirect_to('register')
} }
try { try {
$password = $self->pepper . ':' . $password; $password = $c->pepper . ':' . $password;
# return hashed result + salt # return hashed result + salt
($salt, $hash) = passgen($password) or die; ($salt, $hash) = passgen($password) or die;
# add user info and pw/salt to DB # add user info and pw/salt to DB
$self->schema->resultset('Users')->create({ $c->schema->resultset('Users')->create({
username => $username, username => $username,
email => $email, email => $email,
password => $hash, password => $hash,
@ -83,17 +83,17 @@ sub register_do {
}) })
or die; or die;
$self->flash(message => 'User registered successfully!'); $c->flash(message => 'User registered successfully!');
$self->redirect_to('register') $c->redirect_to('register')
} catch ($catch_error) { } catch ($catch_error) {
print $catch_error; print $catch_error;
$self->flash( $c->flash(
error => error =>
'Your registration info was correct, but a server error 'Your registration info was correct, but a server error
prevented you from registering. This has been logged so the prevented you from registering. This has been logged so the
administrator can fix it.' administrator can fix it.'
); );
$self->redirect_to('register') $c->redirect_to('register')
} }
} }

View File

@ -9,23 +9,23 @@ use feature ':5.20';
use Mojo::Base 'Mojolicious::Controller', -signatures; use Mojo::Base 'Mojolicious::Controller', -signatures;
sub subf_view { sub subf_view {
my $self = shift; my $c = shift;
my $subf_id = $self->param('id'); my $subf_id = $c->param('id');
my $subf_cat = my $subf_cat =
$self->schema->resultset('Subforums')->cat_from_id($subf_id); $c->schema->resultset('Subforums')->cat_from_id($subf_id);
my $cat_title = my $cat_title =
$self->schema->resultset('Categories') $c->schema->resultset('Categories')
->title_from_id($subf_cat); ->title_from_id($subf_cat);
my @thread_list = my @thread_list =
$self->schema->resultset('Threads')->fetch_by_subf($subf_id); $c->schema->resultset('Threads')->fetch_by_subf($subf_id);
$self->render( $c->render(
template => 'subf', template => 'subf',
subf_id => $subf_id, subf_id => $subf_id,
cat_title => $cat_title, cat_title => $cat_title,
subf_title => $self->schema->resultset('Subforums') subf_title => $c->schema->resultset('Subforums')
->title_from_id($subf_id), ->title_from_id($subf_id),
thread_list => \@thread_list thread_list => \@thread_list
) )

View File

@ -10,9 +10,9 @@ use Mojo::Base 'MojoX::Model';
use Tree::Simple; use Tree::Simple;
sub list_full { sub list_full {
my $self = shift; my $c = shift;
# fetch a list of all categories # fetch a list of all categories
my @_all_cat = $self->{app}->schema->resultset('Categories')->fetch_all; my @_all_cat = $c->{app}->schema->resultset('Categories')->fetch_all;
# create a Tree::Simple object that will contain the list # create a Tree::Simple object that will contain the list
# of categories and the subforums that belong to them # of categories and the subforums that belong to them
@ -26,7 +26,7 @@ sub list_full {
# fetch all subforums that belong to this category # fetch all subforums that belong to this category
@_fetch_subf = @_fetch_subf =
$self->{app}->schema->resultset('Subforums') $c->{app}->schema->resultset('Subforums')
->fetch_by_cat($_iter_cat); ->fetch_by_cat($_iter_cat);
# add each fetched subforum as children of the branch # add each fetched subforum as children of the branch

View File

@ -9,18 +9,18 @@ use feature ':5.20';
use base 'DBIx::Class::ResultSet'; use base 'DBIx::Class::ResultSet';
sub fetch_all { sub fetch_all {
my $_set = shift; my $set = shift;
my $_fetch = $_set->search({}, { order_by => 'cat_rank' }); my $_fetch = $set->search({}, { order_by => 'cat_rank' });
return ($_fetch->get_column('cat_id')->all) return ($_fetch->get_column('cat_id')->all)
} }
sub title_from_id { sub title_from_id {
my $_set = shift; my $set = shift;
return ( return (
$_set->search({ 'cat_id' => $_[0] })->get_column('cat_name') $set->search({ 'cat_id' => $_[0] })->get_column('cat_name')
->first) ->first)
} }

View File

@ -9,26 +9,26 @@ use feature ':5.20';
use base 'DBIx::Class::ResultSet'; use base 'DBIx::Class::ResultSet';
sub fetch_by_cat { sub fetch_by_cat {
my $_set = shift; my $set = shift;
my $_fetch = $_set->search({ 'subf_cat' => $_[0] }, my $_fetch = $set->search({ 'subf_cat' => $_[0] },
{ order_by => 'subf_rank' }); { order_by => 'subf_rank' });
return ($_fetch->get_column('subf_id')->all) return ($_fetch->get_column('subf_id')->all)
} }
sub cat_from_id { sub cat_from_id {
my $_set = shift; my $set = shift;
return ( return (
$_set->search({ 'subf_id' => $_[0] })->get_column('subf_cat') $set->search({ 'subf_id' => $_[0] })->get_column('subf_cat')
->first) ->first)
} }
sub title_from_id { sub title_from_id {
my $_set = shift; my $set = shift;
return ($_set->search({ 'subf_id' => $_[0] }) return ($set->search({ 'subf_id' => $_[0] })
->get_column('subf_name')->first) ->get_column('subf_name')->first)
} }

View File

@ -9,18 +9,18 @@ use feature ':5.20';
use base 'DBIx::Class::ResultSet'; use base 'DBIx::Class::ResultSet';
sub fetch_by_subf { sub fetch_by_subf {
my $_set = shift; my $set = shift;
my $_fetch = my $_fetch =
$_set->search({ 'thread_subf' => $_[0] }); $set->search({ 'thread_subf' => $_[0] });
return ($_fetch->get_column('thread_id')->all) return ($_fetch->get_column('thread_id')->all)
} }
sub title_from_id { sub title_from_id {
my $_set = shift; my $set = shift;
return ($_set->search({ 'thread_id' => $_[0] }) return ($set->search({ 'thread_id' => $_[0] })
->get_column('thread_title')->first) ->get_column('thread_title')->first)
} }

View File

@ -1,5 +1,5 @@
% layout 'default', % layout 'default',
% title => $self->board_name; % title => $c->board_name;
<% my $cat_header = begin %> <% my $cat_header = begin %>
% my $_cat_id = shift; my $_name = shift; % my $_cat_id = shift; my $_name = shift;
@ -21,13 +21,13 @@
foreach my $category ($category_tree->getAllChildren) { %> foreach my $category ($category_tree->getAllChildren) { %>
<%= $cat_header->( <%= $cat_header->(
$category->getNodeValue, $category->getNodeValue,
$self->schema->resultset('Categories')-> $c->schema->resultset('Categories')->
title_from_id($category->getNodeValue)) %> title_from_id($category->getNodeValue)) %>
<% <%
foreach my $subforum ($category->getAllChildren) { %> foreach my $subforum ($category->getAllChildren) { %>
<%= $subf_item->( <%= $subf_item->(
$subforum->getNodeValue, $subforum->getNodeValue,
$category->getNodeValue, $category->getNodeValue,
$self->schema->resultset('Subforums')-> $c->schema->resultset('Subforums')->
title_from_id($subforum->getNodeValue)) %> title_from_id($subforum->getNodeValue)) %>
<% }} %> <% }} %>

View File

@ -2,13 +2,13 @@
my $userControls; my $userControls;
# TODO: once implemented, put username + profile link first # TODO: once implemented, put username + profile link first
if ($self->session('is_auth') == 1) { if ($c->session('is_auth')) {
my $username = my $username = '';
$userControls = "<a href=\"/logout\">logout</a>"} $userControls = "<a href=\"/logout\">logout</a>"}
else { else {
$userControls = $userControls =
"<a href=\"/login\">login</a> | "<a href=\"/login\">login</a> |
<a href=\"/register\">register</a>"}; <a href=\"/register\">register</a>"};
%> %>
<a href="/"><h2><%== $self->board_name %></h2></a> <a href="/"><h2><%== $c->board_name %></h2></a>
<%== $userControls %><br /><br /> <%== $userControls %><br /><br />

View File

@ -1,5 +1,5 @@
% layout 'default', % layout 'default',
% title => $self->board_name . ' - Login'; % title => $c->board_name . ' - Login';
% if ($error) { % if ($error) {
<p style="color: red"><%= $error %></p> <p style="color: red"><%= $error %></p>
%}; %};

View File

@ -1,5 +1,5 @@
% layout 'default', % layout 'default',
% title => $self->board_name . ' - Registration'; % title => $c->board_name . ' - Registration';
% if ($error) { % if ($error) {
<p style="color: red"><%= $error %></p> <p style="color: red"><%= $error %></p>
%}; %};

View File

@ -1,5 +1,5 @@
% layout 'default', % layout 'default',
% title => $subf_title . ' - ' . $self->board_name; % title => $subf_title . ' - ' . $c->board_name;
% my @thread_list = @{stash('thread_list')}; % my @thread_list = @{stash('thread_list')};
<% my $thread_item = begin %> <% my $thread_item = begin %>
@ -9,7 +9,7 @@
</div> </div>
<% end %> <% end %>
<a href="/"><%= $self->board_name %></a> » <%= $cat_title %> » <a href="/"><%= $c->board_name %></a> » <%= $cat_title %> »
<%= $subf_title %> <%= $subf_title %>
<br /><br /> <br /><br />
@ -20,6 +20,6 @@ like to <a href="<%= $subf_id %>/new/">make one?</a>
foreach my $thread_id (@thread_list) { %> foreach my $thread_id (@thread_list) { %>
<%= $thread_item->( <%= $thread_item->(
$thread_id, $thread_id,
$self->schema->resultset('Threads')-> $c->schema->resultset('Threads')->
title_from_id($thread_id)) %> title_from_id($thread_id)) %>
<% }} %> <% }} %>

View File

@ -1,6 +1,6 @@
% layout 'default', % layout 'default',
% title => 'New thread - ' . $self->board_name; % title => 'New thread - ' . $c->board_name;
<a href="/"><%= $self->board_name %></a> » <%= $cat_title %> » <a href="/"><%= $c->board_name %></a> » <%= $cat_title %> »
<%= $subf_title %> » new thread <%= $subf_title %> » new thread
<br /><br /> <br /><br />
<form method="post" action="/board/<%= $subf_id %>/new/"> <form method="post" action="/board/<%= $subf_id %>/new/">