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;
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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;
}
$ENV{'Shib_Identity_Provider'} || # local SP
$headers->header('Shib-Identity-Provider'); # remote SP
my $name =
$ENV{displayName} || # local SP
$headers->header('displayName'); # remote SP
my $user = {
idp => $idp,
name => $name
};
$self->stash(user => $user);
return $user;
}
sub check_authentication {
my $self = shift;
return $self->abort(
status => 401,
log_message => sprintf("unauthenticated user for action %s", $self->current_route()),
user_message => Registry::Error::AuthenticationRequired->new()
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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 get_sp {
my ($self, %args) = @_;
my $entityid = $args{entityid};
return $self->abort(
log_message => "Missing parameter: entityid",
user_message => "missing_entityid"
) if !$entityid;
my $pattern = qr{
^
(?:
https?://[\w.:/-]+
|
urn:[\w.:-]+
)
$
}x;
return $self->abort(
log_message => "Invalid parameter: entityid",
user_message => "invalid_entityid"
) if $entityid !~ $pattern;
my $db = $self->stash('db');
my $sp = AccountManager::Entity->new(
db => $db,
entityid => $entityid
);
return $self->abort(
log_message => sprintf("No such SP '%s' in database", $entityid),
user_message => "no_such_entity"
) if !$sp->load(speculative => 1);
return $sp;
}
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(@_);
}
sub mock_contacts {
my $self = shift;
my $sp = shift;
my $config = $self->app()->config();
my $entityid = $sp->entityid();
my $contacts =
$config->{$entityid}->{contacts} ||
$config->{service}->{contacts};
if ($contacts) {
if ($contacts =~ /^\+(.+)/) {
# complement original contacts
$sp->contacts($sp->contacts(), $self->string_to_list($1));
} else {
# replace original contacts
$sp->contacts($self->string_to_list($contacts));
}
}
}