Passed
Push — master ( 6c8d6a...add111 )
by Tim
02:24
created

Yubikey::setAuthState()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\yubikey\Controller;
6
7
use InvalidArgumentException;
8
use SimpleSAML\Auth;
9
use SimpleSAML\Configuration;
10
use SimpleSAML\Error;
11
use SimpleSAML\HTTP\RunnableResponse;
12
use SimpleSAML\Module\yubikey\Auth\Process\OTP;
13
use SimpleSAML\Session;
14
use SimpleSAML\XHTML\Template;
15
use Symfony\Component\HttpFoundation\Request;
16
17
/**
18
 * Controller class for the yubikey module.
19
 *
20
 * This class serves the different views available in the module.
21
 *
22
 * @package simplesamlphp/simplesamlphp-module-yubikey
23
 */
24
class Yubikey
25
{
26
    /** @var \SimpleSAML\Configuration */
27
    protected Configuration $config;
28
29
    /** @var \SimpleSAML\Session */
30
    protected Session $session;
31
32
    /**
33
     * @var \SimpleSAML\Auth\State|string
34
     * @psalm-var \SimpleSAML\Auth\State|class-string
35
     */
36
    protected $authState = Auth\State::class;
37
38
    /**
39
     * @var \SimpleSAML\Module\yubikey\Auth\Process\OTP|string
40
     * @psalm-var \SimpleSAML\Module\yubikey\Auth\Process\OTP|class-string
41
     */
42
    protected $otp = OTP::class;
43
44
45
    /**
46
     * Controller constructor.
47
     *
48
     * It initializes the global configuration and session for the controllers implemented here.
49
     *
50
     * @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
51
     * @param \SimpleSAML\Session $session The session to use by the controllers.
52
     *
53
     * @throws \Exception
54
     */
55
    public function __construct(
56
        Configuration $config,
57
        Session $session
58
    ) {
59
        $this->config = $config;
60
        $this->session = $session;
61
    }
62
63
64
    /**
65
     * Inject the \SimpleSAML\Auth\State dependency.
66
     *
67
     * @param \SimpleSAML\Auth\State $authState
68
     */
69
    public function setAuthState(Auth\State $authState): void
70
    {
71
        $this->authState = $authState;
72
    }
73
74
75
    /**
76
     * Inject the \SimpleSAML\Module\yubikey\Auth\Process\OTP dependency.
77
     *
78
     * @param \SimpleSAML\Module\yubikey\Auth\Process\OTP $otp
79
     */
80
    public function setOtp(OTP $otp): void
81
    {
82
        $this->otp = $otp;
83
    }
84
85
86
    /**
87
     * This page asks the user to authenticate using a Yubikey.
88
     *
89
     * @param \Symfony\Component\HttpFoundation\Request $request The current request.
90
     * @return \SimpleSAML\XHTML\Template|\SimpleSAML\HTTP\RunnableResponse
91
     */
92
    public function main(Request $request)
93
    {
94
        $stateId = $request->get('StateId');
95
        if ($stateId === null) {
96
            throw new Error\BadRequest('Missing AuthState parameter.');
97
        }
98
99
        /** @var array $state */
100
        $state = $this->authState::loadState($stateId, 'yubikey:otp:init');
101
102
        $error = false;
103
104
        $otp = $request->get('otp');
105
        if ($otp !== null) {
106
            // we were given an OTP
107
            try {
108
                if ($this->otp::authenticate($state, $otp)) {
109
                    $this->authState::saveState($state, 'yubikey:otp:init');
110
                    return new RunnableResponse([Auth\ProcessingChain::class, 'resumeProcessing'], [$state]);
111
                } else {
112
                    $error = 'The YubiKey used is invalid. Make sure to use the YubiKey associated with your account.';
113
                }
114
            } catch (InvalidArgumentException $e) {
115
                $error = $e->getMessage();
116
            }
117
        }
118
119
        $t = new Template($this->config, 'yubikey:otp.twig');
120
        $t->data['params'] = ['StateId' => $stateId];
121
        $t->data['error'] = $error || false;
122
        $t->data['autofocus'] = 'otp';
123
124
        return $t;
125
    }
126
}
127