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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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;
}
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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 => "Incorrect parameter format: entityid",
user_message => "format_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(@_);
}
1;