View | Details | Raw Unified | Return to bug 28786
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/members-toolbar.inc (+4 lines)
Lines 52-57 Link Here
52
                    <li class="disabled"><a data-toggle="tooltip" data-placement="left" title="You are not authorized to set permissions" id="patronflags" href="#">Set permissions</a></li>
52
                    <li class="disabled"><a data-toggle="tooltip" data-placement="left" title="You are not authorized to set permissions" id="patronflags" href="#">Set permissions</a></li>
53
                [% END %]
53
                [% END %]
54
54
55
                [% IF Koha.Preference('TwoFactorAuthentication') && logged_in_user.borrowernumber == patron.borrowernumber %]
56
                    <li><a id="twofa" href="/cgi-bin/koha/members/two_factor_auth.pl">Enable Two-Factor Authentication</a></li>
57
                [% END %]
58
55
                [% IF CAN_user_borrowers_edit_borrowers && useDischarge %]
59
                [% IF CAN_user_borrowers_edit_borrowers && useDischarge %]
56
                    <li><a href="/cgi-bin/koha/members/discharge.pl?borrowernumber=[% patron.borrowernumber | uri %]">Discharge</a></li>
60
                    <li><a href="/cgi-bin/koha/members/discharge.pl?borrowernumber=[% patron.borrowernumber | uri %]">Discharge</a></li>
57
                [% END %]
61
                [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/two_factor_auth.tt (+115 lines)
Line 0 Link Here
1
[% USE raw %]
2
[% USE Koha %]
3
[% USE Asset %]
4
[% SET footerjs = 1 %]
5
[% INCLUDE 'doc-head-open.inc' %]
6
<title>Two-Factor Authentication &rsaquo; Patrons &rsaquo; Koha</title>
7
[% INCLUDE 'doc-head-close.inc' %]
8
</head>
9
<body id="pat_two_factor_auth" class="pat">
10
[% INCLUDE 'header.inc' %]
11
[% INCLUDE 'patron-search.inc' %]
12
13
<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
14
    <ol>
15
        <li>
16
            <a href="/cgi-bin/koha/mainpage.pl">Home</a>
17
        </li>
18
        <li>
19
            <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>
20
        </li>
21
        <li>
22
            <a href="#" aria-current="page">
23
                Manage two-factor authentication
24
            </a>
25
        </li>
26
    </ol>
27
</nav>
28
29
<div class="main container-fluid">
30
    <div class="row">
31
        <div class="col-sm-10 col-sm-push-2">
32
            <main>
33
34
                [% INCLUDE 'members-toolbar.inc' %]
35
36
                [% IF op == 'register' %]
37
                    <h1>Register Two-Factor Authenticator</h1>
38
                    <div class="dialog message">
39
                        <p>We recommend cloud-based mobile authenticator apps such as Authy, Duo Mobile, and LastPass. They can restore access if you lose your hardware device.</p>
40
                        <p>Can't scan the code?</p>
41
                        <p>To add the entry manually, provide the following details to the application on your phone.</p>
42
                        <p>Account: [% issuer %]</p>
43
                        <p>Key: [% key_id %]</p>
44
                        <p>Time based: Yes</p>
45
                    </div>
46
47
                    [% IF invalid_pin %]
48
                        <div class="dialog error">Invalid pin code</div>
49
                    [% END %]
50
                    <form id="two-factor-auth" action="/cgi-bin/koha/members/two_factor_auth.pl" method="post">
51
                        <fieldset class="rows">
52
                            <input type="hidden" name="csrf_token" value="[% csrf_token | html %]" />
53
                            <input type="hidden" name="op" value="register-2FA" />
54
                            <input type="hidden" name="secret32" value="[% secret32 %]" />
55
                            <ol>
56
                                <li>
57
                                    <label for="qr_code">QR code: </label>
58
                                    <img id="qr_code" src="[% qr_code_url %]" />
59
                                </li>
60
                                <li>
61
                                    <label for="pin_code">Pin code: </label>
62
                                    <input type="text" id="pin_code" name="pin_code" value="" />
63
                                </li>
64
                            </ol>
65
                        </fieldset>
66
                        <fieldset class="action">
67
                            <input type="submit" value="Register with two-factor app" />
68
                            <a class="cancel" href="/cgi-bin/koha/members/two_factor_auth.pl">Cancel</a>
69
                        </fieldset>
70
                    </form>
71
                [% ELSE %]
72
                    <h1>Two-Factor Authentication</h1>
73
                    [% IF patron.auth_method == "two-factor" %]
74
                        <div class="two-factor-status">Status: Enabled</div>
75
76
                        <form id="two-factor-auth" action="/cgi-bin/koha/members/two_factor_auth.pl" method="post">
77
                            <input type="hidden" name="csrf_token" value="[% csrf_token | html %]" />
78
                            <input type="hidden" name="op" value="disable-2FA" />
79
                            <input type="submit" value="Disable Two-Factor Authentication" />
80
                        </form>
81
                    [% ELSE %]
82
                        <div class="two-factor-status">Status: Disabled</div>
83
84
                        <form id="two-factor-auth" action="/cgi-bin/koha/members/two_factor_auth.pl" method="post">
85
                            <input type="hidden" name="csrf_token" value="[% csrf_token | html %]" />
86
                            <input type="hidden" name="op" value="enable-2FA" />
87
                            <input type="submit" value="Enable Two-Factor Authentication" />
88
                        </form>
89
90
                    [% END %]
91
                [% END %]
92
            </main>
93
        </div> <!-- /.col-sm-10.col-sm-push-2 -->
94
95
        <div class="col-sm-2 col-sm-pull-10">
96
            <aside>
97
                [% INCLUDE 'circ-menu.inc' %]
98
            </aside>
99
        </div> <!-- /.col-sm-2.col-sm-pull-10 -->
100
    </div> <!-- /.row -->
101
102
103
[% MACRO jsinclude BLOCK %]
104
    [% INCLUDE 'str/members-menu.inc' %]
105
    [% Asset.js("js/members-menu.js") | $raw %]
106
    <script>
107
        $(document).ready(function(){
108
            $(".delete").on("click", function(e){
109
                return confirmDelete(_("Are you sure you want to delete this key?"));
110
            });
111
        });
112
    </script>
113
[% END %]
114
115
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/members/two_factor_auth.pl (-1 / +106 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use CGI;
21
22
use C4::Auth qw( get_template_and_user );
23
use C4::Output qw( output_and_exit output_html_with_http_headers );
24
25
use Koha::Patrons;
26
use Koha::Auth::TwoFactorAuth;
27
28
my $cgi = CGI->new;
29
30
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
31
    {
32
        template_name => 'members/two_factor_auth.tt',
33
        query         => $cgi,
34
        type          => 'intranet',
35
        flagsrequired => { editcatalogue => '*' },
36
    }
37
);
38
39
unless ( C4::Context->preference('TwoFactorAuthentication') ) {
40
    print $cgi->redirect("/cgi-bin/koha/errors/404.pl");
41
    exit;
42
}
43
44
my $logged_in_user = Koha::Patrons->find($loggedinuser);
45
46
my $op = $cgi->param('op') // '';
47
48
if ( $op eq 'register-2FA' ) {
49
    my $pin_code = $cgi->param('pin_code');
50
    my $secret32 = $cgi->param('secret32');
51
    my $auth     = Koha::Auth::TwoFactorAuth::get_auth(
52
        { patron => $logged_in_user, secret32 => $secret32 } );
53
54
    my $verified = $auth->verify(
55
        $pin_code,
56
        1,    # range
57
        $secret32,
58
        undef,    # timestamp (defaults to now)
59
        30,       # interval (default 30)
60
    );
61
62
    if ($verified) {
63
        $logged_in_user->secret($secret32);
64
        $op = 'registered';
65
66
        # FIXME Generate a (new?) secret
67
        $logged_in_user->auth_method('two-factor')->store;
68
    }
69
    else {
70
        $template->param( invalid_pin => 1, );
71
        $op = 'enable-2FA';
72
    }
73
}
74
75
if ( $op eq 'enable-2FA' ) {
76
77
    my $secret = Koha::AuthUtils::generate_salt( 'weak', 16 );
78
    my $auth = Koha::Auth::TwoFactorAuth::get_auth(
79
        { patron => $logged_in_user, secret => $secret } );
80
81
    my $secret32 = $auth->generate_secret32;
82
    my $qr_code_url =
83
      $auth->qr_code( $secret32, $auth->key_id, $auth->issuer, );
84
85
    $template->param(
86
        issuer      => $auth->issuer,
87
        key_id      => $auth->key_id,
88
        secret32    => $secret32,
89
        qr_code_url => $qr_code_url,
90
    );
91
    $auth->clear;
92
    $op = 'register';
93
}
94
elsif ( $op eq 'disable-2FA' ) {
95
    $logged_in_user->auth_method('password')->store;
96
}
97
98
$template->param(
99
    csrf_token => Koha::Token->new->generate_csrf(
100
        { session_id => scalar $cgi->cookie('CGISESSID') }
101
    ),
102
    patron => $logged_in_user,
103
    op     => $op,
104
);
105
106
output_html_with_http_headers $cgi, $cookie, $template->output;

Return to bug 28786