LasTres/lib/LasTres/Controller/Player.pm

178 lines
4.7 KiB
Perl

package LasTres::Controller::Player;
use v5.36.0;
use strict;
use warnings;
use Crypt::URandom qw/urandom/;
use Crypt::Bcrypt qw/bcrypt bcrypt_check/;
use UUID::URandom qw/create_uuid_string/;
use LasTres::DAO::Players;
use Mojo::Base 'Mojolicious::Controller', -signatures;
my $result_set_players = LasTres::DAO::Players->ResultSet;
sub check_login($self) {
my $user = $self->user;
my $return_hash = {
is_login => 0,
is_verified => 0,
};
if (!defined $user) {
return $self->render(status => 200, json => $return_hash);
}
$return_hash->{is_login} = 1;
if ($user->verified) {
$return_hash->{is_verified} = 1;
}
return $self->render(status => 200, json => $return_hash);
}
sub login ($self) {
my %params = %{ $self->req->json };
my $username = $params{username};
my $password = $params{password};
my @players = $result_set_players->search({
-or => [
username => $username,
email => $username,
]
});
my $player = $players[0];
if (!defined $player) {
return $self->return_incorrect_username_or_password();
}
if (!bcrypt_check($password, $player->encrypted_password)) {
return $self->return_incorrect_username_or_password();
}
$self->session->{uuid} = $player->uuid;
return $self->render(
status => 200,
json => {
info => 'Login sucessful',
}
);
}
sub return_incorrect_username_or_password($self) {
return $self->render(
status => 400,
json => {
error => 'Incorrect username or password.',
}
);
}
sub register ($self) {
my %params = %{ $self->req->json };
my $username = $params{username};
my $password = $params{password};
my $repeat_password = $params{repeat_password};
my $email = $params{email};
if ( !defined $username || length $username < 5 ) {
return $self->render(
status => 400,
json => { error => 'Username too short, minimum 5 characters.', },
);
}
if ($username =~ /@/) {
return $self->render(
status => 400,
json => { error => 'The character @ is forbidden in usernames.', },
);
}
if ( !defined $email || $email !~ /@/ ) {
return $self->render(
status => 400,
json => { error => 'This is not a valid mail.', },
);
}
if ( $password ne $repeat_password ) {
return $self->render(
status => 400,
json => { error => 'Passwords do not match.' }
);
}
if ( $password =~ /^\d+$/ ) {
return $self->render(
status => 400,
json => {
error => 'Numeric only password are too unsafe to be allowed.'
}
);
}
if ( length $password < 12 ) {
return $self->render(
status => 400,
json => {
error => 'The password should be at least 12 characters long.'
}
);
}
my $new_salt = urandom(16);
my $encrypted_password = bcrypt $password, '2b', 12, $new_salt;
my $uuid = create_uuid_string();
eval {
$result_set_players->create(
{
uuid => $uuid,
username => $username,
encrypted_password => $encrypted_password,
email => $email,
verified => 0,
}
);
};
if ($@) {
if ( $@ =~ /Key \((.*?)\)=\((.*?)\) already exists\./ ) {
return $self->render(
status => 400,
json => {
error => "The key $1 ($2) already exists in the database.",
}
);
}
say STDERR $@;
return $self->render(
status => 500,
json => {
error => 'Unhandled database error.',
}
);
}
my @players = $result_set_players->search({
uuid => $uuid,
});
my $player = $players[0];
if (!defined $player) {
return $self->render(
status => 500,
json => {
error => 'Unknown error creating entity player.',
}
);
}
undef($@);
$self->session->{uuid} = $player->uuid;
return $self->render(
status => 200,
json => {
user => {
username => $username,
email => $email,
verified => 0,
},
info => 'User sucessfully created',
}
);
}
1;