70-2F-TOTP.t 3.43 KB
Newer Older
Xavier Guimard's avatar
Xavier Guimard committed
1 2 3 4 5
use Test::More;
use strict;
use IO::String;

require 't/test-lib.pm';
6
my $maintests = 16;
Xavier Guimard's avatar
Xavier Guimard committed
7 8 9 10 11 12 13 14 15

SKIP: {
    eval { require Convert::Base32 };
    if ($@) {
        skip 'Convert::Base32 is missing', $maintests;
    }
    require Lemonldap::NG::Common::TOTP;

    my $client = LLNG::Manager::Test->new(
Xavier Guimard's avatar
Xavier Guimard committed
16 17
        {
            ini => {
18 19 20
                logLevel               => 'error',
                totp2fSelfRegistration => 1,
                totp2fActivation       => 1,
21
                portalMainLogo         => 'common/logos/logo_llng_old.png',
Xavier Guimard's avatar
Xavier Guimard committed
22 23 24 25 26 27 28
            }
        }
    );
    my $res;

    # Try to authenticate
    # -------------------
Xavier Guimard's avatar
Xavier Guimard committed
29 30
    ok(
        $res = $client->_post(
Xavier Guimard's avatar
Xavier Guimard committed
31 32 33 34 35 36 37 38 39
            '/',
            IO::String->new('user=dwho&password=dwho'),
            length => 23
        ),
        'Auth query'
    );
    my $id = expectCookie($res);

    # TOTP form
Xavier Guimard's avatar
Xavier Guimard committed
40 41
    ok(
        $res = $client->_get(
42 43 44 45 46 47 48
            '/2fregisters',
            cookie => "lemonldap=$id",
            accept => 'text/html',
        ),
        'Form registration'
    );
    expectRedirection( $res, qr#/2fregisters/totp$# );
Xavier Guimard's avatar
Xavier Guimard committed
49 50
    ok(
        $res = $client->_get(
51
            '/2fregisters/totp',
Xavier Guimard's avatar
Xavier Guimard committed
52 53 54 55 56 57
            cookie => "lemonldap=$id",
            accept => 'text/html',
        ),
        'Form registration'
    );
    ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' );
Xavier Guimard's avatar
Xavier Guimard committed
58 59 60 61
    ok(
        $res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
        'Found custom Main Logo'
    ) or print STDERR Dumper( $res->[2]->[0] );
62
    count(1);
Xavier Guimard's avatar
Xavier Guimard committed
63 64

    # JS query
Xavier Guimard's avatar
Xavier Guimard committed
65 66
    ok(
        $res = $client->_post(
67
            '/2fregisters/totp/getkey', IO::String->new(''),
Xavier Guimard's avatar
Xavier Guimard committed
68 69 70 71 72 73 74
            cookie => "lemonldap=$id",
            length => 0,
        ),
        'Get new key'
    );
    eval { $res = JSON::from_json( $res->[2]->[0] ) };
    ok( not($@), 'Content is JSON' )
Xavier Guimard's avatar
Xavier Guimard committed
75
      or explain( $res->[2]->[0], 'JSON content' );
Xavier Guimard's avatar
Xavier Guimard committed
76 77 78 79 80 81 82 83 84 85 86
    my ( $key, $token );
    ok( $key   = $res->{secret}, 'Found secret' );
    ok( $token = $res->{token},  'Found token' );
    $key = Convert::Base32::decode_base32($key);

    # Post code
    my $code;
    ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
        'Code' );
    ok( $code =~ /^\d{6}$/, 'Code contains 6 digits' );
    my $s = "code=$code&token=$token";
Xavier Guimard's avatar
Xavier Guimard committed
87 88
    ok(
        $res = $client->_post(
89
            '/2fregisters/totp/verify',
Xavier Guimard's avatar
Xavier Guimard committed
90 91 92 93 94 95 96 97
            IO::String->new($s),
            length => length($s),
            cookie => "lemonldap=$id",
        ),
        'Post code'
    );
    eval { $res = JSON::from_json( $res->[2]->[0] ) };
    ok( not($@), 'Content is JSON' )
Xavier Guimard's avatar
Xavier Guimard committed
98
      or explain( $res->[2]->[0], 'JSON content' );
Xavier Guimard's avatar
Xavier Guimard committed
99
    ok( $res->{result} == 1, 'Key is registered' );
Xavier Guimard's avatar
Xavier Guimard committed
100

Christophe Maudoux's avatar
Christophe Maudoux committed
101
    # Try to sign-in
Xavier Guimard's avatar
Xavier Guimard committed
102
    $client->logout($id);
Xavier Guimard's avatar
Xavier Guimard committed
103 104
    ok(
        $res = $client->_post(
Xavier Guimard's avatar
Xavier Guimard committed
105 106 107 108 109 110 111
            '/',
            IO::String->new('user=dwho&password=dwho'),
            length => 23,
            accept => 'text/html',
        ),
        'Auth query'
    );
Xavier Guimard's avatar
Xavier Guimard committed
112 113
    my ( $host, $url, $query ) =
      expectForm( $res, undef, '/totp2fcheck', 'token' );
Xavier Guimard's avatar
Xavier Guimard committed
114 115 116
    ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
        'Code' );
    $query =~ s/code=/code=$code/;
Xavier Guimard's avatar
Xavier Guimard committed
117 118
    ok(
        $res = $client->_post(
Xavier Guimard's avatar
Xavier Guimard committed
119 120 121 122 123 124 125 126 127 128 129 130 131 132
            '/totp2fcheck', IO::String->new($query),
            length => length($query),
        ),
        'Post code'
    );
    $id = expectCookie($res);
    $client->logout($id);
}
count($maintests);

clean_sessions();

done_testing( count() );