Dancer2-Plugin-Auth-YARBAC

 view release on metacpan or  search on metacpan

lib/Dancer2/Plugin/Auth/YARBAC/Provider/Base.pm  view on Meta::CPAN

package Dancer2::Plugin::Auth::YARBAC::Provider::Base;

use strict;
use warnings;

use Moo;
use namespace::clean;
use Crypt::PBKDF2;
use Data::Dumper;

our $VERSION = '0.011';

has dsl                   => ( is => 'ro' );
has app                   => ( is => 'ro' );
has settings              => ( is => 'ro' );
has pw_min_length         => ( is => 'ro', default => \&_pw_min_length, lazy => 1 );
has pw_max_length         => ( is => 'ro', default => \&_pw_max_length, lazy => 1 );
has pw_special_characters => ( is => 'ro', default => \&_pw_special_characters, lazy => 1 );
has pw_control_characters => ( is => 'ro', default => \&_pw_control_characters, lazy => 1 );
has pw_no_repeating       => ( is => 'ro', default => \&_pw_no_repeating, lazy => 1 );
has pw_upper_case         => ( is => 'ro', default => \&_pw_upper_case, lazy => 1 ); 
has pw_lower_case         => ( is => 'ro', default => \&_pw_lower_case, lazy => 1 );
has pw_numbers            => ( is => 'ro', default => \&_pw_numbers, lazy => 1 );
has pw_required_score     => ( is => 'ro', default => \&_pw_required_score, lazy => 1 );
has pw_truncate           => ( is => 'ro', default => \&_pw_truncate, lazy => 1 );
has hash_class            => ( is => 'ro', default => sub { 'HMACSHA2' } );
has hash_args             => ( is => 'ro', default => sub { { sha_size => 512, } } );
has iterations            => ( is => 'ro', default => \&_iterations, lazy => 1 );
has output_len            => ( is => 'ro', default => \&_output_len, lazy => 1 );
has salt_len              => ( is => 'ro', default => \&_salt_len, lazy => 1 );
has pbkdf2                => ( is => 'ro', default => \&_pbkdf2, lazy => 1 );

sub _pw_min_length
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{min_length} 
             && $self->settings->{password_strength}->{min_length} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{min_length}
           : 6;
}

sub _pw_max_length
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{max_length} 
             && $self->settings->{password_strength}->{max_length} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{max_length}
           : 32;
}

sub _pw_special_characters
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{special_characters}   
             && $self->settings->{password_strength}->{special_characters} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{special_characters}
           : 1;
}

sub _pw_control_characters
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{control_characters}
             && $self->settings->{password_strength}->{control_characters} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{control_characters}
           : 1;
}

sub _pw_no_repeating
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{no_repeating}
             && $self->settings->{password_strength}->{no_repeating} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{no_repeating}
           : 1;
}

sub _pw_upper_case
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{upper_case}
             && $self->settings->{password_strength}->{upper_case} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{upper_case}
           : 1;
}

sub _pw_lower_case
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{lower_case}
             && $self->settings->{password_strength}->{lower_case} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{lower_case}
           : 1;
}

sub _pw_numbers
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{numbers}
             && $self->settings->{password_strength}->{numbers} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{numbers}
           : 1;
}

sub _pw_required_score
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{required_score}
             && $self->settings->{password_strength}->{required_score} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{required_score}
           : 25;
}

sub _pw_truncate
{
    my $self = shift;

    return ( defined $self->settings->{password_strength}->{truncate}
             && $self->settings->{password_strength}->{truncate} =~ m{^\d$} )
           ? $self->settings->{password_strength}->{truncate}
           : 1;
}

sub _iterations
{
    my $self = shift;

   return ( defined $self->settings->{PBKDF2}->{iterations} 
            && $self->settings->{PBKDF2}->{iterations} =~ m{^\d^} )
          ? $self->settings->{PBKDF2}->{iterations} 
          : 4000;
}

sub _output_len
{
    my $self = shift;

    return ( defined $self->settings->{PBKDF2}->{output_len} 
             && $self->settings->{PBKDF2}->{output_len} =~ m{^\d$} )
           ? $self->settings->{PBKDF2}->{output_len} 
           : 64;
}

sub _salt_len
{
    my $self = shift;

    return ( defined $self->settings->{PBKDF2}->{salt_len} 
             && $self->settings->{PBKDF2}->{salt_len} =~ m{^\d$} )
           ? $self->settings->{PBKDF2}->{salt_len} 
           : 24;
}

sub _pbkdf2
{
    my $self   = shift;

    return Crypt::PBKDF2->new(
        hash_class => $self->hash_class,
        hash_args  => $self->hash_args,
        iterations => $self->iterations,
        output_len => $self->output_len,
        salt_len   => $self->salt_len,
    );
}

sub generate_hash
{
    my $self   = shift;
    my $params = shift;
    my $opts   = shift;

    return if ( ! defined $params->{password} );

    if ( $params->{password} =~ m/^{X-PBKDF2}HMACSHA2.+/ )
    {
        return $params->{password};
    }
    else
    {
        $params->{password} = $self->truncate_password( $params );

        return $self->pbkdf2->generate( $params->{password} );
    }
}

sub validate_password
{
    my $self   = shift;
    my $params = shift;
    my $opts   = shift;

    return if ( ! defined $params->{hash} || ! defined $params->{password} );

    $params->{password} = $self->truncate_password( $params );

    return ( $self->pbkdf2->validate( $params->{hash}, $params->{password} ) ) ? 1 : undef;
}

sub truncate_password
{
    # Enforcing the truncating of long passwords to avoid DDOS attacks.
    my $self   = shift;
    my $params = shift;
    my $opts   = shift;

    return if ( ! defined $params->{password} );

    return ( $self->pw_truncate ) ? substr( $params->{password}, 0, $self->pw_max_length ) : $params->{password};
}

sub password_strength
{
    my $self      = shift;
    my $params    = shift;
    my $opts      = shift;
    my $password  = $params->{password};
    my $pw_length = ( defined $password ) ? length $password : 0;
    my @errors;

    if ( ! defined $password )



( run in 0.793 second using v1.01-cache-2.11-cpan-71847e10f99 )