Skip to content
Snippets Groups Projects
Controller.pm 3.63 KiB
Newer Older
package AccountManager::App::Controller;

use Mojo::Base qw(Mojolicious::Controller);

use English qw(-no_match_vars);
use Syntax::Keyword::Try;

use AccountManager::DB;
use AccountManager::L10N;
use AccountManager::Token;

sub init_l10n {
    my $self = shift;

    my $log = $self->app()->log();

    # lang identification first, as needed for any further error message
    my ($l10n, $lang);
    if ($self->param('lang')) {
        $lang = $self->param('lang');
        $l10n = AccountManager::L10N->get_handle($lang);
        $log->debug(sprintf("setting language from parameter: %s", $lang));
    } elsif ($self->session('lang')) {
        $lang = $self->session('lang');
        $l10n = AccountManager::L10N->get_handle($lang);
        $log->debug(sprintf("setting language from session: %s", $lang));
    } elsif ($self->req()->headers->header('Accept-Language')) {
        $l10n = AccountManager::L10N->get_handle();
        $lang = $l10n->language_tag();
        $log->debug(sprintf("setting language from Accept-Language header: %s", $lang));
    } else {
        $lang = 'en';
        $l10n = AccountManager::L10N->get_handle($lang);
    }

    $self->session(lang => $lang);
    $self->stash(lang => $lang);
    $self->stash(l10n => $l10n);

    return $l10n;
}

sub init_db {
    my $self = shift;

    my $config = $self->app()->config();

    AccountManager::DB->register_db(
        driver   => $config->{database}->{type},
        database => $config->{database}->{name},
        host     => $config->{database}->{host},
        password => $config->{database}->{password},
        username => $config->{database}->{username},
        options  => [ $self->string_to_list($config->{database}->{options}) ]
    );

    my $db;
    try {
        $db = AccountManager::DB->new();
    } catch {
    }

    $self->stash(db => $db);

    return $db;
}

sub check_authentication {
    my $self = shift;

    my $idp = 
        $ENV{'Shib_Identity_Provider'} ||                          # local SP
        $self->req()->headers()->header('Shib-Identity-Provider'); # remote SP

    return $self->abort(
        status       => 401,
        log_message  => sprintf("unauthenticated user for action %s",  $self->current_route()),
        user_message => Registry::Error::AuthenticationRequired->new()
    ) if !$idp;

    return 1;

}

sub check_token {
    my ($self, %args) = @_;

    my $secret = $args{token};

    my $token = AccountManager::Token->new(
        db     => $self->{db},
        secret => $secret
    );

    return $self->abort(
        status       => 400,
        log_message  => "No such authentication token $secret",
        user_message => "wrong_token"
    ) if !$token->load(speculative => 1);

    return $self->abort(
        status       => 400,
        log_message  => "Authentication token $secret cannot be used for SP $args{entityid}",
        user_message => "wrong_token_for_sp"
    ) if $token->entityid() ne $args{entityid};

    ## delete the token
    try {
        $token->delete();
    } catch {
        $self->app()->log()->error(
            sprintf("Failed to delete authentication token %s", $secret)
        );
    }

    return 1;
}

sub abort {
    my $self = shift;
    my %args = @_;

    my $status = $args{status} || 200;
    my $format = $args{format} || 'html';

    my $db = $self->stash('db');
    $db->rollback() if $db && $db->in_transaction();

    $self->app()->log()->error($args{log_message}) if $args{log_message};

    $self->stash(error => $args{user_message});
    $self->render(status => $status, template => 'errors', format => 'html');

    return;
}

sub loc {
    my $self = shift;

    return $self->stash('l10n')->maketext(@_);
}

1;