package Net::OpenVPN::Manager::Plugin::Token;

use namespace::autoclean;
use Moose;
use Net::OpenVPN::Manager::Plugin;

with 'Net::OpenVPN::Manager::Authenticable';
with 'Net::OpenVPN::Manager::Connectable';

has '+order' => (
    default => 5,
);

has 'tokens' => (
    is => 'ro',
    isa => 'HashRef[Str]',
    traits => ['Hash'],
    default => sub { {} },
    handles => {
        get_token => 'get',
        set_token => 'set',
        has_token => 'exists',
    }
);

has 'secret' => (
    is => 'ro',
    isa => 'Str',
);

sub authenticate {
    my ($self, $client) = @_;

    my $found = $self->has_token($client->cid) && $self->get_token($client->cid) eq $client->get_env('password');
    $self->log($found ? "token found" : "token not found", $client);

    return $found ? PLUG_OK : PLUG_ERROR;
}

sub connect {
    my ($self, $client) = @_;

    unless ($self->has_token($client->cid)) {
        $self->log("create auth-token", $client);
        my $token = $self->_create_token;
        $self->set_token($client->cid, $token);
        $client->add_config("push \"auth-token $token\"");
    }

    return PLUG_OK;
}

sub _create_token {
    return unpack("h32", pack ("n8",
        rand(65536), rand(65536), rand(65536), rand(65536),
        rand(65536), rand(65536), rand(65536), rand(65536)));
}

__PACKAGE__->meta->make_immutable;

1;
