File Coverage

File:lib/OpenAPI/Handler/Login.pm
Coverage:87.0%

linestmtbrancondsubpodtimecode
1package OpenAPI;
2
3#use Smart::Comments;
4
22
22
22
174
67
176
use strict;
5
22
22
22
234
74
172
use warnings;
6
22
22
22
351
76
239
use vars qw($Cache $UUID $Dumper);
7
22
22
22
317
85
296
use CGI::Cookie;
8
22
22
22
251
64
352
use Encode 'is_utf8';
9
10sub GET_login_user {
11
6
0
46
    my ($self, $bits) = @_;
12
6
40
    my $user = $bits->[1];
13
6
48
    $self->login($user);
14}
15
16sub GET_login_user_password {
17
22
0
189
    my ($self, $bits) = @_;
18
22
147
    my $user = $bits->[1];
19
22
120
    my $password = $bits->[2];
20
22
277
    $self->login($user, { password => $password });
21}
22
23sub trim_sol {
24
8
0
37
    my $s = $_[0];
25
8
75
    unless (is_utf8($s)) {
26
8
56
        $s = decode('UTF-8', $s);
27    }
28
8
235
    $s =~ s/\W+//g;
29
8
116
    $s;
30}
31
32sub login {
33
71
0
529
    my ($self, $user, $params) = @_;
34
71
565
    _STRING($user) or die "Bad user name: ", $Dumper->($user), "\n";
35
71
1940
    $params ||= {};
36    ### $params
37    ### caller: caller()
38
71
475
    my $password = $params->{password};
39
71
381
    my $captcha = $params->{captcha};
40
71
218
    my $account;
41
71
315
    my $role = 'Admin';
42
71
843
    if ($user =~ /^(\w+)\.(\w+)$/) {
43
40
392
        ($account, $role) = ($1, $2);
44    } elsif ($user =~ /^\w+$/) {
45
29
259
        $account = $&;
46    } else {
47
2
10
        die "Bad user name: ", $Dumper->($user), "\n";
48    }
49
69
560
    _IDENT($account) or die "Bad account name: ", $Dumper->($account), "\n";
50
69
514
    _IDENT($role) or die "Bad role name: ", $Dumper->($role), "\n";
51    ### $role
52    # this part is lame?
53
69
474
    if (!$account) {
54
0
0
        die "Login required.\n";
55    }
56
69
603
    if (!$self->has_user($account)) {
57        ### Found user: $user
58
0
0
        die "Account \"$account\" does not exist.\n";
59    }
60
69
1902
    $self->set_user($account);
61
62
69
707
    if (!$self->has_role($role)) {
63        ### Found user: $user
64
0
0
        die "Role \"$role\" does not exist.\n";
65    }
66
67    ### $account
68    ### $role
69    ### $password
70    ### capture param: $captcha
71
69
4921
    if (defined $captcha) {
72
12
153
        my ($id, $user_sol) = split /:/, $captcha, 2;
73
12
191
        if (!$id or !$user_sol) {
74
1
4
            die "Bad captcha parameter: $captcha\n";
75        }
76
11
101
        my $res = $self->select("select count(*) from _roles where name = " . Q($role) . " and login = 'captcha'");
77        ### with captcha: $res
78
11
8058
        if ($res->[0][0] == 0) {
79
1
4
            die "Cannot login as $account.$role via captchas.\n";
80        }
81        ### Captcha ID: $id
82
10
122
        my $true_sol = $Cache->get($id);
83        ### True sol: $true_sol
84
10
682
        $Cache->remove($id);
85
10
1110
        if (!defined $true_sol) {
86
4
18
            die "Capture ID is bad or expired.\n";
87        }
88
6
47
        if ($true_sol eq '1') {
89
2
8
            die "Captcha image never used.\n";
90        }
91        # XXX for testing purpose...
92
4
127
        if ($OpenAPI::Config{'frontend.debug'} && $account eq 'peee' && $role eq 'Poster') {
93
4
39
            if ($true_sol =~ /[a-z]/) {
94
2
15
                $true_sol = 'hello world ';
95            } else {
96
2
33
                $true_sol = '你好世界';
97            }
98        }
99
4
28
        if (trim_sol($user_sol) ne trim_sol($true_sol)) {
100
2
9
            die "Solution to the captcha is incorrect.\n";
101        }
102    } elsif (defined $password) {
103
51
512
        my $res = $self->select("select count(*) from _roles where name = " . Q($role) . " and login = 'password' and password = " . Q($password) . ";");
104        ### with password: $res
105
51
40259
        if ($res->[0][0] == 0) {
106
1
5
            die "Password for $account.$role is incorrect.\n";
107        }
108    } else {
109
6
71
        my $res = $self->select("select count(*) from _roles where name = " . Q($role) . " and login = 'anonymous';");
110        ### no password: $res
111        ### no password (2): $res->[0][0]
112
6
4930
        if ($res->[0][0] == 0) {
113            ### dying...
114
5
22
            die "Password for $account.$role is required.\n";
115        }
116    }
117
53
584
    $self->set_role($role);
118
119
53
357
    my $session_from_cookie = $self->{_session_from_cookie};
120    ### Get session ID from cookie: $session_from_cookie
121
53
358
    if ($session_from_cookie) {
122
29
287
        $OpenAPI::Cache->remove($session_from_cookie)
123    }
124
125
53
3475
    my $captcha_from_cookie = $self->{_captcha_from_cookie};
126
53
328
    if ($captcha_from_cookie) {
127
3
21
        $OpenAPI::Cache->remove($captcha_from_cookie);
128    }
129
130
53
5167
    my $uuid = $UUID->create_str;
131
53
550
    if ($self->{_use_cookie}) {
132
29
383
        $self->{_cookie} = { session => $uuid };
133    }
134
53
743
    $Cache->set($uuid => "$account.$role");
135
136    return {
137
53
13035
        success => 1,
138        account => $account,
139        role => $role,
140        session => $uuid,
141    };
142}
143
1441;
145