WWW-Suffit-API

 view release on metacpan or  search on metacpan

lib/WWW/Suffit/Server/API/V1.pm  view on Meta::CPAN

    E1102   [500]   RSA decrypt error
    E1103   [ * ]   Incorrect username or password
    E1104   [ * ]   Access denied (authz)
    E1105   [ * ]   Access denied by realm restrictions (access)
    E1106   [---]   Reserved
    E1107   [---]   Reserved
    E1108   [---]   Reserved
    E1109   [---]   Reserved

B<*> -- this code will be defined later on the interface side

See also list of common Suffit API error codes in L<WWW::Suffit::API/"ERROR CODES">

=head1 HISTORY

See C<Changes> file

=head1 TO DO

See C<TODO> file

=head1 SEE ALSO

L<Mojolicious>, L<WWW::Suffit>, L<WWW::Suffit::Server>, L<WWW::Suffit::API>

=head1 AUTHOR

Serż Minus (Sergey Lepenkov) L<https://www.serzik.com> E<lt>abalama@cpan.orgE<gt>

=head1 COPYRIGHT

Copyright (C) 1998-2026 D&D Corporation

=head1 LICENSE

This program is distributed under the terms of the Artistic License Version 2.0

See the C<LICENSE> file or L<https://opensource.org/license/artistic-2-0> for details

=cut

use Mojo::Base 'Mojolicious::Controller';

use Mojo::Path;
use Mojo::URL;

use Acrux::RefUtil qw/ is_hash_ref /;

use WWW::Suffit::RSA;

sub authn {
    my $self = shift;
    my $username = $self->req->json('/username') // '';
    my $password = $self->req->json('/password') // '';
    my $address = $self->req->json('/address') // '';
    my $encrypted = $self->req->json('/encrypted') || 0;
    my $cachekey = $self->stash('cachekey');
    my $authdb = $self->authdb;
    my $acc_user = $authdb->user($self->stash('username'), $cachekey);
    my $public_key = $acc_user->public_key // '';
    my $private_key = $acc_user->private_key // '';
    $authdb->clean;

    # Password decrypt
    if ($encrypted && length($password)) {
        return $self->reply->json_error(400 => "E1100" => "No RSA public key found") unless length $public_key;
        return $self->reply->json_error(400 => "E1101" => "No RSA private key found") unless length $private_key;
        my $rsa = WWW::Suffit::RSA->new->private_key($private_key);
        $password = $rsa->decrypt($password); # RSA Decrypt password
        return $self->reply->json_error(500 => "E1102" => $rsa->error || "RSA decrypt error") if $rsa->error;
    }

    # Authentication
    return $self->reply->json_error(
        $authdb->code, $authdb->error || "E1103: Incorrect username or password"
    ) unless $authdb->authn(
        u => $username,
        p => $password,
        k => $cachekey,
        a => $address, # For check by stats
    ); # Unauthenticated

    # Render ok
    return $self->reply->json_ok;
}
sub authz {
    my $self = shift;
    my $authdb = $self->authdb->clean;
    my $cachekey = $self->stash('cachekey');
    my $username = $self->req->json('/username') // '';
    my $verbose = $self->req->json('/verbose') || 0;
    my $url = $self->req->json('/url') // $self->base_url // '';
    my $uri = Mojo::URL->new($url);
       $username = $uri->username unless length $username;
    my %args = (controller => $self, username => $username, cachekey => $cachekey);
    $args{address} = $self->req->json('/address') // '';
    $args{method} = $self->req->json('/method') // '';
    $args{path} = $self->req->json('/path') //
        $uri->path->leading_slash(1)->trailing_slash(0)->to_string // '';
    $args{base} = $self->req->json('/base') //
        $uri->path_query("")->path(Mojo::Path->new->leading_slash(0)->trailing_slash(0) )->to_string // '';
    my $headers = $self->req->json('/headers') || {};
    if (is_hash_ref($headers)) {
        my %hdrs = ();
        while (my ($k, $v) = each %$headers) {
            $hdrs{$k} = $v if defined($v) && !ref($v);
        }
        $args{headers} = {%hdrs} if scalar %hdrs;
    }

    # Authorization (External!)
    my $user = $authdb->authz(
        u => $username,
        's' => 1,
        k => $cachekey,
    );
    return $self->reply->json_error(
        $authdb->code, $authdb->error || "E1104: Access denied"
    ) unless $user; # Unauthorized
    #$self->log->debug($self->dumper($user));

    # Access (username is optional)
    return $self->reply->json_error(
        $authdb->code, $authdb->error || "E1105: Access denied by realm restrictions"
    ) unless ($authdb->access(%args)); # Forbidden

    # Render ok
    return $self->reply->json_ok unless $verbose;



( run in 0.989 second using v1.01-cache-2.11-cpan-39bf76dae61 )