Largely just add POD doc

This commit is contained in:
ngoomie 2023-05-13 17:49:55 -06:00
parent cce6e230c9
commit 4eec3f79c5
12 changed files with 247 additions and 33 deletions

View File

@ -12,9 +12,11 @@
"passgen", "passgen",
"resultset", "resultset",
"signup", "signup",
"SMALLINT",
"subf", "subf",
"subforum", "subforum",
"subforums" "subforums",
"TINYTEXT"
], ],
"better-comments.highlightPlainText": true, "better-comments.highlightPlainText": true,
"better-comments.tags": [ "better-comments.tags": [

View File

@ -5,6 +5,7 @@ use Mojo::Base 'Mojolicious', -signatures;
use CharmBoard::Schema; use CharmBoard::Schema;
=pod =pod
=encoding utf8
=head1 NAME =head1 NAME
CharmBoard - revive the fun posting experience! CharmBoard - revive the fun posting experience!
=head1 NOTES =head1 NOTES

View File

@ -6,6 +6,7 @@ use CharmBoard::Crypt::Password;
use CharmBoard::Crypt::Seasoning; use CharmBoard::Crypt::Seasoning;
=pod =pod
=encoding utf8
=head1 NAME =head1 NAME
CharmBoard::Controller::Login CharmBoard::Controller::Login
=cut =cut
@ -28,7 +29,7 @@ sub login_do ($self) {
try { # check user credentials first try { # check user credentials first
# check to see if user by entered username exists # check to see if user by entered username exists
$userInfo = $self->schema->resultset('Users')->search( $userInfo = $self->schema->resultset('Users')->find(
{username => $username}); {username => $username});
$userInfo or die; $userInfo or die;

View File

@ -5,7 +5,7 @@ use Mojo::Base 'Mojolicious::Controller', -signatures;
sub logout_do ($self) { sub logout_do ($self) {
# destroy entry for this session in the database # destroy entry for this session in the database
$self->schema->resultset('Session')->search({ $self->schema->resultset('Session')->find({
session_key => $self->session('session_key')})->delete; session_key => $self->session('session_key')})->delete;
# now nuke the actual session cookie # now nuke the actual session cookie
$self->session(expires => 1); $self->session(expires => 1);

View File

@ -39,10 +39,10 @@ sub register_do ($self) {
# 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
$userCheck = $self->schema->resultset('Users')->search( $userCheck = $self->schema->resultset('Users')->find(
{username => $username})->single; {username => $username});
$emailCheck = $self->schema->resultset('Users')->search( $emailCheck = $self->schema->resultset('Users')->find(
{email => $email})->single; {email => $email});
($userCheck && $emailCheck) eq undef ($userCheck && $emailCheck) eq undef
or die "Username already in use.\nemail already in use."; or die "Username already in use.\nemail already in use.";

View File

@ -7,30 +7,37 @@ use Exporter qw(import);
our @EXPORT = qw(passgen passchk); our @EXPORT = qw(passgen passchk);
=pod =pod
=encoding utf8
=head1 NAME =head1 NAME
CharmBoard::Crypt::Password - password processing module CharmBoard::Crypt::Password - password processing module
=head1 SYNOPSIS =head1 SYNOPSIS
=begin perl =begin perl
use CharmBoard::Crypt::Password; use CharmBoard::Crypt::Password;
($salt, $hash) = passgen($plaintextPassword); my ($salt, $hash) =
$passwordVerification = passchk($salt, $hash, $plaintextPassword) passgen($plaintextPassword);
$passwordVerification =
passchk($salt, $hash, $plaintextPassword)
=end perl =end perl
=head1 DESCRIPTION =head1 DESCRIPTION
CharmBoard::Crypt::Password processes passwords, either processing CharmBoard::Crypt::Password processes passwords, either
new passwords for database storage, or checking passwords entered processing new passwords for database storage, or checking
when logging in to make sure they're correct. passwords entered when logging in to make sure they're
correct.
Currently the only available password hashing scheme is Argon2, but Currently the only available password hashing scheme is
this might be changed later on. Argon2, but this might be changed later on.
=over
=cut =cut
=pod =pod
=head2 passgen =item passgen
passgen is the function for generating password salts and hashes to passgen is the function for generating password salts and
be inserted into the database. It takes the plaintext password you hashes to be inserted into the database. It takes the
wish to hash as the only argument, and outputs the salt and plaintext password you wish to hash as the only argument,
Argon2 hash string in hexadecimal form. and outputs the salt and Argon2 hash string in hexadecimal
form.
=cut =cut
sub passgen ($) { sub passgen ($) {
my $argon2 = Authen::Passphrase::Argon2->new( my $argon2 = Authen::Passphrase::Argon2->new(
@ -44,15 +51,18 @@ sub passgen ($) {
return ($argon2->salt_hex, $argon2->hash_hex)}; return ($argon2->salt_hex, $argon2->hash_hex)};
=pod =pod
=head2 passchk =item passchk
passchk is the function for checking plaintext passwords against the passchk is the function for checking plaintext passwords
hashed password + salt already stored in the database. It takes the against the hashed password + salt already stored in the
salt and Argon2 hash string in hex form plus the plaintext password database. It takes the salt and Argon2 hash string in hex
as inputs, and outputs a true/false value indicating whether or not form plus the plaintext password as inputs, and outputs a
the input password matched. Intended for login authentication or true/false value indicating whether or not the input
anywhere else where one may need to verify passwords (i.e. before password matched. Intended for login authentication or
changing existing passwords, or for admins confirming they wish to anywhere else where one may need to verify passwords (i.e.
perform a risky or nonreversible operation.) before changing existing passwords, or for admins
confirming they wish to perform a risky or nonreversible
operation.)
=back
=cut =cut
sub passchk ($$$) { sub passchk ($$$) {
my $argon2 = Authen::Passphrase::Argon2->new( my $argon2 = Authen::Passphrase::Argon2->new(

View File

@ -1,14 +1,51 @@
package CharmBoard::Schema::Source::Categories; package CharmBoard::Schema::Source::Categories;
use base qw(DBIx::Class::Core); use base qw(DBIx::Class::Core);
=pod
=encoding utf8
=head1 NAME
CharmBoard::Schema::Source::Categories - DBIx::Class
ResultSource module for the database's C<categories> table
=head1 DESCRIPTION
This table contains info about categories, which are used
solely to organize subforums on places like the index page.
=head2 Columns
=over
=item cat_id
Contains unique IDs for individual categories.
Data type is SQLite C<INTEGER>; MariaDB C<INT>.
Cannot be C<NULL>.
=item cat_rank
The order in which categories should be displayed.
Data type is SQLite C<INTEGER>; MariaDB C<SMALLINT>.
Cannot be C<NULL>.
=item cat_name
The name of the category to be displayed in the forum list.
Data type is SQLite C<TEXT>; MariaDB C<TINYTEXT>.
Cannot be C<NULL>.
=back
=cut
__PACKAGE__->table('categories'); __PACKAGE__->table('categories');
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
cat_id => { cat_id => {
data_type => 'integer', data_type => 'integer',
is_numeric => 1,
is_auto_increment => 1, is_auto_increment => 1,
is_nullable => 0, }, is_nullable => 0, },
cat_rank => {
data_type => 'integer',
is_auto_increment => 0,
is_nullable => 0, },
cat_name => { cat_name => {
data_type => 'text', data_type => 'text',
is_auto_increment => 0,
is_nullable => 0, }); is_nullable => 0, });
__PACKAGE__->set_primary_key('cat_id'); __PACKAGE__->set_primary_key('cat_id');

View File

@ -1,6 +1,48 @@
package CharmBoard::Schema::Source::Posts; package CharmBoard::Schema::Source::Posts;
use base qw(DBIx::Class::Core); use base qw(DBIx::Class::Core);
=pod
=encoding utf8
=head1 NAME
CharmBoard::Schema::Source::Posts - DBIx::Class
ResultSource module for the database's C<posts> table
=head1 DESCRIPTION
This table contains post content and other important post
information (such as post date).
=head2 Columns
=over
=item post_id
Contains unique IDs for posts.
Data type is SQLite C<INTEGER>; MariaDB C<INT>. Cannot
be C<NULL>.
=item user_id
Contains the user ID of the creator of a given post.
Is foreign key of C<users.user_id>, and as such, shares the
same datatype (SQLite C<INTEGER>; MariaDB C<INT>).
Cannot be C<NULL>.
=item thread_id
Contains the ID of the thread this post was posted in.
Is foreign key of C<threads.thread_id>, and as such, shares
the same datatype (C<INTEGER> in SQLite). Cannot be C<NULL>.
=item post_date
Contains the date the post was made, in the format provided
by Perl's C<time> function.
Data type is SQLite C<INTEGER>. Cannot be C<NULL>.
=item post_body
Contains the actual text content of the post.
Data type is SQLite C<TEXT>. Cannot be C<NULL>.
=back
=cut
__PACKAGE__->table('posts'); __PACKAGE__->table('posts');
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
post_id => { post_id => {
@ -22,6 +64,11 @@ __PACKAGE__->add_columns(
data_type => 'integer', data_type => 'integer',
is_foreign_key => 0, is_foreign_key => 0,
is_auto_increment => 0, is_auto_increment => 0,
is_nullable => 0, },
post_body => {
data_type => 'text',
is_foreign_key => 0,
is_auto_increment => 0,
is_nullable => 0, }); is_nullable => 0, });
__PACKAGE__->set_primary_key('post_id'); __PACKAGE__->set_primary_key('post_id');

View File

@ -24,7 +24,7 @@ __PACKAGE__->add_columns(
is_auto_increment => 0, is_auto_increment => 0,
is_nullable => 1, }); is_nullable => 1, });
__PACKAGE__->set_primary_key('session_key'); __PACKAGE__->set_primary_key(qw(session_key user_id));
__PACKAGE__->belongs_to( __PACKAGE__->belongs_to(
user_id => user_id =>

View File

@ -1,6 +1,47 @@
package CharmBoard::Schema::Source::Subforums; package CharmBoard::Schema::Source::Subforums;
use base qw(DBIx::Class::Core); use base qw(DBIx::Class::Core);
=pod
=encoding utf8
=head1 NAME
CharmBoard::Schema::Source::Subforums - DBIx::Class
ResultSource module for the database's C<subforums> table
=head1 DESCRIPTION
This table contains information about subforums.
=head2 Columns
=over
=item subf_id
Contains unique IDs for individual subforums.
Data type is SQLite C<INTEGER>.. Cannot be C<NULL>.
=item subf_cat
Which category from the C<categories> table this subforum
belongs to and should show up as a child of.
Is foreign key of C<categories.cat_id> and as such, shares
the same datatype (C<INTEGER> in SQLite). Cannot be C<NULL>.
=item subf_rank
The order in which subforums from a given category should
be displayed, which should be unique per category group.
Data type is SQLite C<INTEGER>. Cannot be C<NULL>.
=item subf_name
The name of the subforum to be displayed in the forum list,
or anywhere else where it is relevant.
Data type is SQLite C<TEXT>. Cannot be C<NULL>.
=item subf_desc
A blurb of text describing the use of a subforum to be
displayed in the forum list.
Data type is SQLite C<TEXT>. Can be C<NULL>.
=back
=cut
__PACKAGE__->table('subforums'); __PACKAGE__->table('subforums');
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
subf_id => { subf_id => {
@ -12,6 +53,11 @@ __PACKAGE__->add_columns(
is_foreign_key => 1, is_foreign_key => 1,
is_auto_increment => 0, is_auto_increment => 0,
is_nullable => 0, }, is_nullable => 0, },
subf_rank => {
data_type => 'integer',
is_foreign_key => 0,
is_auto_increment => 0,
is_nullable => 0, },
subf_name => { subf_name => {
data_type => 'text', data_type => 'text',
is_auto_increment => 0, is_auto_increment => 0,

View File

@ -1,6 +1,33 @@
package CharmBoard::Schema::Source::Threads; package CharmBoard::Schema::Source::Threads;
use base qw(DBIx::Class::Core); use base qw(DBIx::Class::Core);
=pod
=encoding utf8
=head1 NAME
CharmBoard::Schema::Source::Categories - DBIx::Class
ResultSource module for the database's C<threads> table
=head1 DESCRIPTION
This table contains information about threads.
=head2 COLUMNS
=over
=item thread_id
Contains unique IDs for threads.
Data type is SQLite C<INTEGER>. Cannot be C<NULL>.
=item thread_title
Contains the title for a given thread.
Data type is SQLite C<TEXT>. Cannot be C<NULL>.
=item thread_subf
Contains the ID of the subforum a given thread belongs to.
Is foreign key of C<subforums.subf_id>, and as such, shares
the same datatype (SQLite C<INTEGER>). Cannot be C<NULL>.
=back
=cut
__PACKAGE__->table('threads'); __PACKAGE__->table('threads');
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
thread_id => { thread_id => {
@ -13,12 +40,9 @@ __PACKAGE__->add_columns(
thread_subf => { thread_subf => {
data_type => 'integer', data_type => 'integer',
is_foreign_key => 1, is_foreign_key => 1,
is_nullable => 1, }); is_nullable => 0, });
# ! thread_subf should NOT be nullable once subforums
# ! are properly implemented
__PACKAGE__->set_primary_key('thread_id'); __PACKAGE__->set_primary_key('thread_id');
__PACKAGE__->belongs_to( __PACKAGE__->belongs_to(
thread_subf => thread_subf =>
'CharmBoard::Schema::Source::Subforums', 'CharmBoard::Schema::Source::Subforums',

View File

@ -2,6 +2,52 @@ package CharmBoard::Schema::Source::Users;
use utf8; use utf8;
use base qw(DBIx::Class::Core); use base qw(DBIx::Class::Core);
=pod
=encoding utf8
=head1 NAME
CharmBoard::Schema::Source::Users - DBIx::Class
ResultSource module for the database's C<users> table
=head1 DESCRIPTION
This table contains information about users.
=head2 COLUMNS
=over
=item user_id
Contains unique IDs for users.
Data type is SQLite C<INTEGER>; MariaDB C<INT>. Cannot
be C<NULL>.
=item username
Contains a given user's username. Please do not use this
field as an identifier for users, that's what C<user_id> is
intended for, instead.
Data type is SQLite C<TEXT>. Cannot be C<NULL>.
=item email
Contains a user's email address.
Data type is SQLite C<TEXT>. Cannot be C<NULL>.
=item password
Contains the user's password in the form of a
Crypt::Passphrase string in hexadecimal form.
Data type is SQLite C<TEXT>. Cannot be C<NULL>.
=item salt
Contains the user's salt in hexadecimal form.
Data type is SQLite C<TEXT>. Cannot be C<NULL>.
=item signup_date
Contains the date the user signed up, in the format
provided by Perl's C<time> function.
Data type is SQLite C<INTEGER>. Cannot be C<NULL>.
=back
=cut
__PACKAGE__->table('users'); __PACKAGE__->table('users');
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
user_id => { user_id => {