161 lines
4.9 KiB
Perl
161 lines
4.9 KiB
Perl
package BurguillosInfo::Controller::UserConquer;
|
|
|
|
use v5.34.1;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use utf8;
|
|
|
|
use Mojo::Base 'Mojolicious::Controller', '-signatures';
|
|
|
|
use UUID::URandom qw/create_uuid_string/;
|
|
use Crypt::Bcrypt qw/bcrypt bcrypt_check/;
|
|
use Crypt::URandom qw/urandom/;
|
|
use JSON;
|
|
|
|
use BurguillosInfo::Schema;
|
|
|
|
my $username_minimum_chars = 3;
|
|
my $username_maximum_chars = 15;
|
|
my $password_minimum_chars = 8;
|
|
my $password_maximum_chars = 4096;
|
|
|
|
sub get_self($self) {
|
|
my $user = $self->current_user;
|
|
if (!defined $user) {
|
|
return $self->_renderError(401, 'No estás loggeado.');
|
|
}
|
|
return $self->render(json => $user->serialize_to_owner, status => 200);
|
|
}
|
|
|
|
sub create ($self) {
|
|
my $input = $self->_expectJson;
|
|
if ( !defined $input ) {
|
|
return;
|
|
}
|
|
my $username = $input->{username};
|
|
my $password = $input->{password};
|
|
my $repeat_password = $input->{repeat_password};
|
|
return
|
|
unless $self->_createCheckInput( $username, $password, $repeat_password );
|
|
return $self->_createUser( $username, $password );
|
|
}
|
|
|
|
sub _expectJson ($self) {
|
|
my $input;
|
|
eval { $input = $self->req->json; };
|
|
if ($@) {
|
|
say STDERR $@;
|
|
$self->_renderError(400, 'Se esperaba JSON.');
|
|
return;
|
|
}
|
|
return $input;
|
|
}
|
|
|
|
sub login ($self) {
|
|
my $input = $self->_expectJson;
|
|
if ( !defined $input ) {
|
|
return;
|
|
}
|
|
my $username = $input->{username};
|
|
my $password = $input->{password};
|
|
|
|
my $resultset_conquer_user =
|
|
BurguillosInfo::Schema->Schema->resultset('ConquerUser');
|
|
my @tentative_users =
|
|
$resultset_conquer_user->search( { username => $username } );
|
|
my $tentative_user = $tentative_users[0];
|
|
if (!defined $tentative_user) {
|
|
$self->_renderError(401, 'El usuario especificado no existe.');
|
|
return;
|
|
}
|
|
if ( !bcrypt_check( $password, $tentative_user->encrypted_password ) ) {
|
|
$self->_renderError( 401, 'Contraseña incorrecta.' );
|
|
return;
|
|
}
|
|
my $user = $tentative_user;
|
|
$self->set_current_user($user);
|
|
$self->render(
|
|
json => {
|
|
success => $JSON::true
|
|
},
|
|
status => 200
|
|
);
|
|
}
|
|
|
|
sub _createUser ( $self, $username, $password ) {
|
|
my $user;
|
|
my $uuid = create_uuid_string();
|
|
my $new_salt = urandom(16);
|
|
my $encrypted_password = bcrypt $password, '2b', 12, $new_salt;
|
|
eval {
|
|
$user = BurguillosInfo::Schema->Schema->resultset('ConquerUser')->new(
|
|
{
|
|
uuid => $uuid,
|
|
encrypted_password => $encrypted_password,
|
|
username => $username
|
|
}
|
|
);
|
|
$user->insert;
|
|
};
|
|
if ($@) {
|
|
if ( $@ =~ /Key \((.*?)\)=\((.*?)\) already exists\./ ) {
|
|
return $self->_renderError( 400,
|
|
"La clave $1 ($2) ya existe en la base de datos.",
|
|
);
|
|
}
|
|
say STDERR $@;
|
|
return $self->_renderError( 400,
|
|
'No se pudo crear el usuario por razones desconocidas.' );
|
|
}
|
|
$self->render( status => 200, json => $user->serialize_to_owner );
|
|
return 1;
|
|
}
|
|
|
|
sub _renderError ( $self, $status, $message ) {
|
|
$self->render( status => $status, json => { error => $message } );
|
|
return 0;
|
|
}
|
|
|
|
sub _createCheckInput ( $self, $username, $password, $repeat_password ) {
|
|
if ( !defined $username
|
|
|| $username !~
|
|
/^(?:\w|\d|[ÑÁÉÍÓÚñáéíóú ]){$username_minimum_chars,$username_maximum_chars}$/
|
|
)
|
|
{
|
|
return $self->_renderError( 400,
|
|
"Username invalido, las reglas son tamaño entre $username_minimum_chars y $username_maximum_chars"
|
|
. ' carácteres y solo se podrán usar letras, números y espacios.'
|
|
);
|
|
}
|
|
if ( !defined $password
|
|
|| $password eq $username
|
|
|| $password !~ /^.{$password_minimum_chars,$password_maximum_chars}$/
|
|
|| $password =~ /^\d+$/ )
|
|
{
|
|
return $self->_renderError(
|
|
400,
|
|
'Contraseña invalida, las reglas son la contraseña debe ser'
|
|
. ' distinta al nombre de usuario, la contraseña debe tener entre'
|
|
. " $password_minimum_chars y $password_maximum_chars carácteres"
|
|
. ' (Tu contraseña no se guardará en texto plano, el límite de'
|
|
. " $password_maximum_chars caracteres es para evitar denegaciones"
|
|
. ' de servicio), la contraseña no puede estar compuesta solo de números.',
|
|
);
|
|
}
|
|
if ( !defined $repeat_password || $password ne $repeat_password ) {
|
|
$self->_renderError(
|
|
400,
|
|
'El campo de repetir contraseña debe coincidir de forma'
|
|
. ' totalmente exacta con el campo de contraseña para asegurar'
|
|
. ' que podrás recordar la contraseña y/o que no has cometido'
|
|
. ' ningún error, si pierdes el acceso a tu cuenta no podrás'
|
|
. ' recuperarlo de ningún modo.',
|
|
);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
1;
|