MyRedland/lib/MyRedland/Lusers.pm

182 lines
4.7 KiB
Perl

package MyRedland::Lusers;
use v5.34.1;
use strict;
use warnings;
use DateTime;
use DateTime::Format::Pg;
use Moo;
use Crypt::URandom;
use Types::Standard qw/InstanceOf Str ArrayRef/;
use Params::ValidationCompiler qw/validation_for/;
use MyRedland::DB;
use MyRedland::Luser;
use List::AllUtils qw/any/;
my $fpg = DateTime::Format::Pg->new;
my @FIELDS = qw/uuid username email verified
password mail_verification_payload avatar
mail_verification_expiration creation_date
last_access stripe_customer_id/;
has app => (
is => 'rw',
isa => InstanceOf ['Mojolicious'],
required => 1,
);
has dbh => ( is => 'lazy', );
sub _build_dbh {
my $self = shift;
return MyRedland::DB->connect( $self->app );
}
{
my $validator = validation_for(
params => {
username => { type => Str },
email => { type => Str },
password => { type => Str },
}
);
sub create {
my $self = shift;
my %params = $validator->(@_);
my $dbh = $self->dbh;
my $username = $params{username};
my $email = $params{email};
my $password = $params{password};
my $test_mode = $self->app->config->{test_mode};
my $verified = 0;
if ($test_mode) {
$verified = 1;
}
my $mail_verification_payload = unpack 'H*',
Crypt::URandom::urandom(30);
my $avatar = '';
my $mail_verification_expiration =
$fpg->format_datetime( DateTime->now->add( days => 1 ) );
my $user_hash = $dbh->selectrow_hashref(
<<"EOF", undef, $username, $email, $verified, $password, $mail_verification_payload, $avatar, $mail_verification_expiration );
INSERT INTO lusers
(username, email, verified, password,
mail_verification_payload, avatar,
mail_verification_expiration)
VALUES
(?, ?, ?, ?, ?, ?, ?)
RETURNING @{[join ', ', @FIELDS]};
EOF
$self->_convert_user_hash_dates($user_hash);
my $user = MyRedland::Luser->new(%$user_hash);
return $user;
}
}
{
my $validator = validation_for(
params => {
user => { type => InstanceOf ['MyRedland::Luser'] },
fields => { type => ArrayRef [Str] },
}
);
sub update {
my $self = shift;
my %params = $validator->(@_);
my $user = $params{user};
my $fields = $params{fields};
my %updates;
for my $field (@$fields) {
if ( any { $field eq $_ } qw/verified email password mail_verification_expiration mail_verification_payload last_access avatar stripe_customer_id/) {
$updates{$field} = $user->$field;
next;
}
die "No such field $field.";
}
my $query = <<"EOF";
UPDATE lusers
SET @{[
join ', ', map { "$_ = ?" } @$fields
]} WHERE uuid = ?
RETURNING @{[join ', ', @FIELDS]};
EOF
my $dbh = $self->dbh;
my $user_hash = $dbh->selectrow_hashref($query, undef, @updates{@$fields}, $user->uuid);
$self->_convert_user_hash_dates($user_hash);
$user = MyRedland::Luser->new(%$user_hash);
return $user;
}
}
sub _convert_user_hash_dates {
my $self = shift;
my $user_hash = shift;
$user_hash->{mail_verification_expiration} =
$fpg->parse_datetime( $user_hash->{mail_verification_expiration} );
$user_hash->{creation_date} =
$fpg->parse_datetime( $user_hash->{creation_date} );
$user_hash->{last_access} =
$fpg->parse_datetime( $user_hash->{last_access} );
}
{
my $validator = validation_for(
params => {
uuid => { type => Str },
}
);
sub find_by_uuid {
my $self = shift;
my %params = $validator->(@_);
my $uuid = $params{uuid};
my $dbh = $self->dbh;
my $user_hash = $dbh->selectrow_hashref( <<"EOF", undef, $uuid );
SELECT @{[join ', ', @FIELDS]} FROM lusers where uuid = ?;
EOF
if ( !defined $user_hash ) {
return;
}
$self->_convert_user_hash_dates($user_hash);
my $user = MyRedland::Luser->new(%$user_hash);
return $user;
}
}
{
my $validator = validation_for(
params => {
username => { type => Str },
}
);
sub find_by_username {
my $self = shift;
my %params = $validator->(@_);
my $username = $params{username};
my $dbh = $self->dbh;
my $user_hash = $dbh->selectrow_hashref( <<"EOF", undef, $username );
SELECT @{[join ', ', @FIELDS]} FROM lusers where username = ?;
EOF
if ( !defined $user_hash ) {
return;
}
$self->_convert_user_hash_dates($user_hash);
my $user = MyRedland::Luser->new(%$user_hash);
return $user;
}
}
1;