line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Slovo::Controller::Auth; |
2
|
14
|
|
|
14
|
|
113
|
use Mojo::Base 'Slovo::Controller', -signatures; |
|
14
|
|
|
|
|
32
|
|
|
14
|
|
|
|
|
86
|
|
3
|
|
|
|
|
|
|
|
4
|
14
|
|
|
14
|
|
3217
|
use Mojo::Util qw(encode sha1_sum); |
|
14
|
|
|
|
|
36
|
|
|
14
|
|
|
|
|
2822
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
# Returns the name of the geter for the current user. |
7
|
|
|
|
|
|
|
# Needed by Mojolicious::Plugin::Authentication. |
8
|
|
|
|
|
|
|
# See Slovo::_before_dispatch to understand how this function name is used. |
9
|
14
|
|
|
14
|
1
|
42523
|
sub current_user_fn { return 'user' } |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# Display the form for signing in. |
12
|
|
|
|
|
|
|
# GET /in |
13
|
14
|
|
|
14
|
1
|
166
|
sub form ($c) { |
|
14
|
|
|
|
|
28
|
|
|
14
|
|
|
|
|
22
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
#TODO: remember where the user is comming from to redirect him back |
16
|
|
|
|
|
|
|
#afterwards if the place he is comming from in the siame domain. If not, |
17
|
|
|
|
|
|
|
#redirect him to the main page. |
18
|
14
|
50
|
|
|
|
74
|
$c->is_user_authenticated && return $c->redirect_to('/'); |
19
|
14
|
|
|
|
|
796
|
$c->stash(sign_in_error => ''); |
20
|
14
|
|
|
|
|
284
|
return $c->render; |
21
|
|
|
|
|
|
|
} |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# Sign in the user. |
24
|
|
|
|
|
|
|
# POST /in |
25
|
12
|
|
|
12
|
1
|
134
|
sub sign_in ($c) { |
|
12
|
|
|
|
|
25
|
|
|
12
|
|
|
|
|
25
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
#1. do basic validation first |
28
|
12
|
|
|
|
|
89
|
my $v = $c->validation; |
29
|
12
|
|
|
|
|
6811
|
$v->required('login_name', 'trim')->like(qr/^[\p{IsAlnum}\.\-\$]{3,12}$/x); |
30
|
12
|
|
|
|
|
1955
|
$v->required('digest')->like(qr/[0-9a-f]{40}/i); |
31
|
12
|
|
|
|
|
855
|
$c->stash(sign_in_error => ''); |
32
|
|
|
|
|
|
|
|
33
|
12
|
100
|
|
|
|
245
|
if ($v->csrf_protect->has_error('csrf_token')) { |
|
|
50
|
|
|
|
|
|
34
|
1
|
|
|
|
|
42
|
return $c->render( |
35
|
|
|
|
|
|
|
sign_in_error => 'Bad CSRF token!', |
36
|
|
|
|
|
|
|
status => 401, |
37
|
|
|
|
|
|
|
template => 'auth/form' |
38
|
|
|
|
|
|
|
); |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
elsif ($v->has_error) { |
41
|
0
|
|
|
|
|
0
|
return $c->render( |
42
|
|
|
|
|
|
|
sign_in_error => 'И двете полета са задължителни!..', |
43
|
|
|
|
|
|
|
status => 401, |
44
|
|
|
|
|
|
|
template => 'auth/form' |
45
|
|
|
|
|
|
|
); |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
11
|
|
|
|
|
353
|
my $o = $v->output; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# TODO: Redirect to the page where user wanted to go or where he was before |
51
|
11
|
50
|
|
|
|
134
|
if ($c->authenticate($o->{login_name}, $o->{digest}, $o)) { |
52
|
|
|
|
|
|
|
my $route |
53
|
|
|
|
|
|
|
= ($c->stash('passw_login') |
54
|
|
|
|
|
|
|
? {'edit_users' => {id => $c->user->{id}}} |
55
|
11
|
100
|
|
|
|
38586
|
: 'home_upravlenie'); |
56
|
11
|
100
|
|
|
|
263
|
return $c->redirect_to(ref($route) ? %$route : $route); |
57
|
|
|
|
|
|
|
} |
58
|
0
|
|
|
|
|
0
|
$c->stash(sign_in_error => 'Няма такъв потребител или ключът ви е грешен.'); |
59
|
0
|
|
|
|
|
0
|
return $c->render('auth/form'); |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# GET /out |
63
|
7
|
|
|
7
|
0
|
105
|
sub sign_out ($c) { |
|
7
|
|
|
|
|
22
|
|
|
7
|
|
|
|
|
13
|
|
64
|
7
|
|
|
|
|
37
|
my $login_name = $c->user->{login_name}; |
65
|
7
|
|
|
|
|
337
|
$c->logout; |
66
|
7
|
|
|
|
|
280
|
$c->app->log->info('$user ' . $login_name . ' logged out!'); |
67
|
7
|
|
|
|
|
250
|
return $c->redirect_to('authform'); |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
65
|
|
|
65
|
1
|
567
|
sub under_management ($c) { |
|
65
|
|
|
|
|
99
|
|
|
65
|
|
|
|
|
90
|
|
71
|
65
|
100
|
|
|
|
308
|
unless ($c->is_user_authenticated) { |
72
|
3
|
|
|
|
|
202
|
$c->redirect_to('authform'); |
73
|
3
|
|
|
|
|
1781
|
return 0; |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
62
|
|
|
|
|
217589
|
my $uid = $c->user->{id}; |
77
|
62
|
|
|
|
|
1724
|
my $path = $c->req->url->path->to_string; |
78
|
62
|
|
|
|
|
5683
|
my $route = $c->current_route; |
79
|
|
|
|
|
|
|
|
80
|
62
|
100
|
|
|
|
1993
|
return 1 if $c->groups->is_admin($uid); |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# for now only admins can manage groups and domains |
83
|
24
|
100
|
|
|
|
6683
|
if ($route =~ /groups|domove$/) { |
84
|
1
|
|
|
|
|
53
|
$c->flash(message => 'Само управителите се грижат' |
85
|
|
|
|
|
|
|
. ' за множествата от потребители и домейните.'); |
86
|
1
|
|
|
|
|
38
|
$c->redirect_to('home_upravlenie'); |
87
|
1
|
|
|
|
|
804
|
return 0; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# only admins and users with id=created_by can change another's user account |
91
|
23
|
|
|
|
|
1290
|
my ($e_uid) = $path =~ m|/users/(\d+)|; #Id of the user being edited |
92
|
23
|
100
|
|
|
|
108
|
my $e_user = $e_uid ? $c->users->find_where({id => $e_uid}) : undef; |
93
|
23
|
100
|
66
|
|
|
1011
|
if ( $route =~ /^(show|edit|update|remove)_users$/x |
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
94
|
|
|
|
|
|
|
&& $e_user |
95
|
|
|
|
|
|
|
&& ($e_user->{created_by} != $uid && $e_user->{id} != $uid)) |
96
|
|
|
|
|
|
|
{ |
97
|
1
|
|
|
|
|
12
|
$c->flash( |
98
|
|
|
|
|
|
|
message => 'Само управителите на сметки могат да ' . 'променят чужда сметка.'); |
99
|
1
|
|
|
|
|
43
|
$c->redirect_to('home_upravlenie'); |
100
|
1
|
|
|
|
|
865
|
return 0; |
101
|
|
|
|
|
|
|
} |
102
|
22
|
|
|
|
|
92
|
return 1; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# secure route /manage/minion. |
106
|
|
|
|
|
|
|
# Allow access to only authenticated members of the admin group. |
107
|
0
|
|
|
0
|
1
|
0
|
sub under_minion ($c) { |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
# TODO: make the group configurable |
110
|
0
|
0
|
|
|
|
0
|
unless ($c->groups->is_admin($c->user->{id})) { |
111
|
0
|
|
|
|
|
0
|
$c->flash(message => 'Само управителите могат да управляват задачите.'); |
112
|
0
|
|
|
|
|
0
|
$c->redirect_to('home_upravlenie'); |
113
|
0
|
|
|
|
|
0
|
return 0; |
114
|
|
|
|
|
|
|
} |
115
|
0
|
|
|
|
|
0
|
return 1; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
196
|
|
|
196
|
1
|
8525
|
sub load_user ($c, $uid) { |
|
196
|
|
|
|
|
338
|
|
|
196
|
|
|
|
|
286
|
|
|
196
|
|
|
|
|
256
|
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# TODO: implement some smarter caching (at least use Mojo::Cache). |
121
|
|
|
|
|
|
|
# state $users ={}; |
122
|
|
|
|
|
|
|
# keys %$users >2000 && $users = {};#reset cached users. |
123
|
|
|
|
|
|
|
# return $users->{$uid}//=$c->users->find($uid); |
124
|
196
|
|
|
|
|
846
|
return $c->users->find($uid); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# Used in $c->authenticate by Mojolicious::Plugin::Authentication |
128
|
|
|
|
|
|
|
# returns the user id or nothing. |
129
|
11
|
|
|
11
|
1
|
237
|
sub validate_user ($c, $login_name, $csrf_digest, $dat) { |
|
11
|
|
|
|
|
23
|
|
|
11
|
|
|
|
|
21
|
|
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
21
|
|
|
11
|
|
|
|
|
19
|
|
130
|
11
|
|
|
|
|
29
|
state $app = $c->app; |
131
|
11
|
|
|
|
|
47
|
state $log = $app->log; |
132
|
11
|
|
|
|
|
85
|
my $u = $c->users->find_by_login_name($login_name); |
133
|
11
|
50
|
|
|
|
41650
|
if (!$u) { |
134
|
0
|
|
|
|
|
0
|
$log->error("Error signing in user [$login_name]: " |
135
|
|
|
|
|
|
|
. "No such user or user disabled, or stop_date < now!"); |
136
|
0
|
|
|
|
|
0
|
return; |
137
|
|
|
|
|
|
|
} |
138
|
11
|
|
|
|
|
968
|
my $csrf_token = $c->csrf_token; |
139
|
11
|
|
|
|
|
514
|
my $checksum = sha1_sum($csrf_token . $u->{login_password}); |
140
|
11
|
100
|
|
|
|
58
|
unless ($checksum eq $csrf_digest) { |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# try the passw_login |
143
|
1
|
|
|
|
|
15
|
my $t = time; |
144
|
|
|
|
|
|
|
my $row = $c->dbx->db->select( |
145
|
|
|
|
|
|
|
passw_login => 'token', |
146
|
1
|
|
|
|
|
11
|
{start_date => {'<=' => $t}, to_uid => $u->{id}, stop_date => {'>' => $t}}, |
147
|
|
|
|
|
|
|
{-desc => ['id']})->hash; |
148
|
|
|
|
|
|
|
my $checksum2 = sha1_sum( |
149
|
1
|
|
|
|
|
2698
|
$csrf_token . sha1_sum(encode('UTF-8' => $u->{login_name} . $row->{token}))); |
150
|
1
|
50
|
33
|
|
|
94
|
if ($row && ($checksum2 eq $csrf_digest)) { |
151
|
1
|
|
|
|
|
12
|
$app->dbx->db->delete('passw_login' => {to_uid => $u->{id}}); |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# also delete expired but not deleted (for any reason) login tokens. |
154
|
1
|
|
|
|
|
1381
|
$app->dbx->db->delete('passw_login' => {stop_date => {'<=' => $t}}); |
155
|
1
|
|
|
|
|
1127
|
$log->info('$user ' . $u->{login_name} . ' logged in using passw_login!'); |
156
|
1
|
|
|
|
|
79
|
$c->flash(message => 'Задайте нов таен ключ!'); |
157
|
1
|
|
|
|
|
49
|
$c->stash(passw_login => 1); |
158
|
1
|
|
|
|
|
24
|
return $u->{id}; |
159
|
|
|
|
|
|
|
} |
160
|
0
|
|
|
|
|
0
|
$log->error("Error signing in user [$u->{login_name}]:" |
161
|
|
|
|
|
|
|
. "\$csrf_token:$csrf_token|\$checksum:$checksum \$csrf_digest:$csrf_digest)"); |
162
|
0
|
|
|
|
|
0
|
$log->error('$checksum:sha1_sum($csrf_token . $u->{login_password}) ne $csrf_digest'); |
163
|
0
|
|
|
|
|
0
|
return; |
164
|
|
|
|
|
|
|
} |
165
|
10
|
|
|
|
|
95
|
$log->info('$user ' . $u->{login_name} . ' logged in!'); |
166
|
|
|
|
|
|
|
|
167
|
10
|
|
|
|
|
156
|
return $u->{id}; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
my $msg_expired_token = 'Връзката, която ви доведе тук, е с изтекла годност.' . ''; |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
# GET /first_login/ |
173
|
|
|
|
|
|
|
# GET /first_login/32e36608c72bc51c7c39a72fd7e71cba55f3e9ad |
174
|
1
|
|
|
1
|
1
|
26
|
sub first_login_form ($c) { |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
6
|
|
175
|
1
|
50
|
33
|
|
|
10
|
$c->logout && $c->user($c->users->find_by_login_name('guest')) |
176
|
|
|
|
|
|
|
if $c->is_user_authenticated; |
177
|
1
|
|
|
|
|
3281
|
my $token = $c->param('token'); |
178
|
1
|
|
|
|
|
105
|
my $t = time; |
179
|
1
|
|
|
|
|
12
|
my $row = $c->dbx->db->select( |
180
|
|
|
|
|
|
|
first_login => '*', |
181
|
|
|
|
|
|
|
{start_date => {'<=' => $t}, stop_date => {'>' => $t}, token => $token})->hash; |
182
|
1
|
50
|
|
|
|
2102
|
unless (defined $row) { |
183
|
0
|
|
|
|
|
0
|
$c->stash('error_message' => $msg_expired_token); |
184
|
0
|
|
0
|
|
|
0
|
$c->app->log->error('Token for first_login_form was not found for user comming from ' |
185
|
|
|
|
|
|
|
. ($c->req->headers->referrer || 'nowhere') |
186
|
|
|
|
|
|
|
. '.'); |
187
|
|
|
|
|
|
|
} |
188
|
1
|
|
|
|
|
61
|
return $c->render(row => $row); |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# POST /first_login |
192
|
1
|
|
|
1
|
1
|
16
|
sub first_login ($c) { |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
5
|
|
193
|
1
|
|
|
|
|
11
|
state $app = $c->app; |
194
|
1
|
|
|
|
|
12
|
my $token = $c->param('token'); |
195
|
1
|
|
|
|
|
470
|
my $t = time; |
196
|
1
|
|
|
|
|
5
|
my $row = $c->dbx->db->select( |
197
|
|
|
|
|
|
|
first_login => '*', |
198
|
|
|
|
|
|
|
{start_date => {'<=' => $t}, stop_date => {'>' => $t}, token => $token})->hash; |
199
|
1
|
50
|
|
|
|
2026
|
unless (defined $row) { |
200
|
0
|
|
|
|
|
0
|
$c->stash(error_message => $msg_expired_token); |
201
|
0
|
|
|
|
|
0
|
return $c->render('auth/first_login_form'); |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
} |
204
|
1
|
|
|
|
|
63
|
my $v = $c->validation; |
205
|
1
|
|
|
|
|
171
|
$v->required('first_name', 'trim')->required('last_name', 'trim'); |
206
|
1
|
|
|
|
|
146
|
my $in = $v->output; |
207
|
|
|
|
|
|
|
my $ok = ( |
208
|
|
|
|
|
|
|
sha1_sum( |
209
|
|
|
|
|
|
|
$row->{start_date} |
210
|
|
|
|
|
|
|
. encode('UTF-8' => $in->{first_name} . $in->{last_name}) |
211
|
|
|
|
|
|
|
. $row->{from_uid} |
212
|
|
|
|
|
|
|
. $row->{to_uid} |
213
|
1
|
|
|
|
|
13
|
) eq $token |
214
|
|
|
|
|
|
|
); |
215
|
1
|
50
|
|
|
|
18
|
unless ($ok) { |
216
|
0
|
|
|
|
|
0
|
$c->stash(error_message => 'Моля, въведете имената на човека,' |
217
|
|
|
|
|
|
|
. ' създал вашата сметка, както са изписани в' |
218
|
|
|
|
|
|
|
. ' електроннто съобщение с препратката за първо влизане.'); |
219
|
0
|
|
|
|
|
0
|
return $c->render(template => 'auth/first_login_form', row => $row); |
220
|
|
|
|
|
|
|
} |
221
|
1
|
50
|
|
|
|
9
|
if ($INC{'Slovo/Task/SendOnboardingEmail.pm'}) { |
222
|
1
|
|
|
|
|
15
|
$app->minion->enqueue(delete_first_login => [$row->{to_uid}, $token]); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
else { |
225
|
0
|
|
|
|
|
0
|
$app->dbx->db->delete('first_login' => {token => $token, user_id => $row->{to_uid}}); |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# also delete expired but not deleted (for any reason) login tokens. |
228
|
0
|
|
|
|
|
0
|
$app->dbx->db->delete('first_login' => {stop_date => {'<=' => time}}); |
229
|
|
|
|
|
|
|
} |
230
|
1
|
|
|
|
|
739
|
$c->users->save($row->{to_uid}, {disabled => 0}); |
231
|
1
|
|
|
|
|
85
|
$c->authenticate(undef, undef, {auto_validate => $row->{to_uid}}); |
232
|
1
|
|
|
|
|
3242
|
return $c->redirect_to('edit_users' => {id => $row->{to_uid}}); |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
# GET /lost_password |
236
|
2
|
|
|
2
|
1
|
21
|
sub lost_password_form ($c) { |
|
2
|
|
|
|
|
13
|
|
|
2
|
|
|
|
|
12
|
|
237
|
2
|
100
|
|
|
|
9
|
if ($c->req->method eq 'POST') { |
238
|
1
|
|
|
|
|
19
|
my $v = $c->validation; |
239
|
1
|
|
|
|
|
409
|
$v->required('email', 'trim')->like(qr/^[\w\-\+\.]{1,154}\@[\w\-\+\.]{1,100}$/x); |
240
|
1
|
|
|
|
|
171
|
my $in = $v->output; |
241
|
|
|
|
|
|
|
|
242
|
1
|
50
|
|
|
|
12
|
if ($INC{'Slovo/Task/SendPasswEmail.pm'}) { |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
# send email to the user to login with a temporary password and change his |
245
|
|
|
|
|
|
|
# password. |
246
|
1
|
50
|
|
|
|
13
|
if (my $user = $c->users->find_where({email => $in->{email}})) { |
247
|
1
|
|
|
|
|
603
|
my $job_id |
248
|
|
|
|
|
|
|
= $c->minion->enqueue(mail_passw_login => [$user, $c->req->headers->host]); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
else { |
251
|
0
|
|
|
|
|
0
|
$c->app->log->warn('User not found by email to send temporary login password.'); |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
} |
255
|
2
|
|
|
|
|
744
|
return $c->render(); |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
1; |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
=encoding utf8 |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=head1 NAME |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
Slovo::Controller::Auth - и миръ Его не позна. |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=head1 DESCRIPTION |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
L implements actions for authenticating users. It |
270
|
|
|
|
|
|
|
depends on functionality, provided by L. |
271
|
|
|
|
|
|
|
All the routes' paths mentioned below are easily modifiable because they are |
272
|
|
|
|
|
|
|
described in C thanks to |
273
|
|
|
|
|
|
|
L. |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=head1 ACTIONS |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
Mojolicious::Plugin::Authentication implements the following actions. |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
=head2 first_login_form |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
Displays a form for confirmation of the names of the user who invited the new |
282
|
|
|
|
|
|
|
user. |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
GET /first_login/ |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
C is a route type matching C. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head2 first_login |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Compares the entered names of the inviting user with the token and makes other |
291
|
|
|
|
|
|
|
checks. Signs in the user for the first time. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=head2 form |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
Route: C<{get =E '/in', to =E 'auth#form', name =E 'authform'}>. |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
Renders a login form. The password is never transmitted in plain text. A digest |
298
|
|
|
|
|
|
|
is prepared in the browser using JavaScript (see |
299
|
|
|
|
|
|
|
C). The digest is sent and |
300
|
|
|
|
|
|
|
compared on the server side. The digest is different in every POST request. |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=head2 lost_password_form |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
Route: |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
{ |
307
|
|
|
|
|
|
|
any => '/lost_password', |
308
|
|
|
|
|
|
|
to => 'auth#lost_password_form', |
309
|
|
|
|
|
|
|
name => 'lost_password_form' |
310
|
|
|
|
|
|
|
}, |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
In case the request is not C C<$c-Eurl_for('lost_password_form')> displays a form |
313
|
|
|
|
|
|
|
for entering email to which a temporary password to be send. If the request |
314
|
|
|
|
|
|
|
method is C, enqueues L, if a |
315
|
|
|
|
|
|
|
user with the given email is found in the database. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=head2 sign_in |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
Route: C<{post =E '/in', to =E 'auth#sign_in', name =E 'sign_in'}>. |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
Finds and logs in a user locally. On success redirects the user to |
322
|
|
|
|
|
|
|
L. On failure redirects |
323
|
|
|
|
|
|
|
again to the login page. |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=head2 under_management |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
This is a callback when user tries to access a page I C. If |
328
|
|
|
|
|
|
|
user is authenticated returns true. If not, returns false and redirects to |
329
|
|
|
|
|
|
|
L. |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=head2 under_minion |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
Allow access to only authenticated members of the admin group. All routes |
335
|
|
|
|
|
|
|
generated by L are under this route. |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
GET /manage/minion |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=head2 METHODS |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
L inherits all methods from L and |
343
|
|
|
|
|
|
|
implements the following new ones. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=head1 FUNCTIONS |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Slovo::Controller::Auth implements the following functions executed or used by |
348
|
|
|
|
|
|
|
L. |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=head2 current_user_fn |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
Returns the name of the helper used for getting the properties of the current |
353
|
|
|
|
|
|
|
user. The name is C. It is passed in configuration to |
354
|
|
|
|
|
|
|
L to generate the helper with this name. |
355
|
|
|
|
|
|
|
This value must not be changed. Otherwise you will get runtime errors all over |
356
|
|
|
|
|
|
|
the place because C<$c-Euser> is used a lot. |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=head2 load_user |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
This function is passed to L as reference. |
361
|
|
|
|
|
|
|
See L. |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
=head2 validate_user |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
This function is passed to L as reference. |
367
|
|
|
|
|
|
|
See L. |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=head1 SEE ALSO |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
L, |
373
|
|
|
|
|
|
|
L |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=cut |