Passed
Pull Request — master (#31)
by Tim
02:10
created

ManageToken::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
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
nc 1
nop 1
cc 1
1
<?php
2
3
namespace SimpleSAML\Module\webauthn\Controller;
4
5
use Exception;
6
use SimpleSAML\Auth;
7
use SimpleSAML\Configuration;
8
use SimpleSAML\Error;
9
use SimpleSAML\HTTP\RunnableResponse;
10
use SimpleSAML\Logger;
11
use SimpleSAML\Module;
12
use SimpleSAML\Module\webauthn\WebAuthn\StaticProcessHelper;
13
use SimpleSAML\Session;
14
use SimpleSAML\Utils;
15
use Symfony\Component\HttpFoundation\Request;
16
17
/**
18
 * Controller class for the webauthn module.
19
 *
20
 * This class serves the different views available in the module.
21
 *
22
 * @package SimpleSAML\Module\webauthn
23
 */
24
class ManageToken
25
{
26
    /** @var \SimpleSAML\Configuration */
27
    protected $config;
28
29
    /** @var \SimpleSAML\Session */
30
    protected $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\Logger|string
40
     * @psalm-var \SimpleSAML\Logger|class-string
41
     */
42
    protected $logger = Logger::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\Logger dependency.
77
     *
78
     * @param \SimpleSAML\Logger $logger
79
     */
80
    public function setLogger(Logger $logger): void
81
    {
82
        $this->logger = $logger;
83
    }
84
85
86
    /**
87
     * @param \Symfony\Component\HttpFoundation\Request $request
88
     * @return \SimpleSAML\HTTP\RunnableResponse  A Symfony Response-object.
89
     */
90
    public function main(Request $request): RunnableResponse
91
    {
92
        if (session_status() != PHP_SESSION_ACTIVE) {
93
            session_cache_limiter('nocache');
94
        }
95
96
        $this->logger::info('FIDO2 - Accessing WebAuthn token management');
97
98
        $stateId = $request->query->get('StateId');
99
        if ($stateId === null) {
100
            throw new Error\BadRequest('Missing required StateId query parameter.');
101
        }
102
103
        $state = $this->authState::loadState($stateId, 'webauthn:request');
104
105
        if ($state['FIDO2AuthSuccessful'] === false) {
106
            throw new Exception("Attempt to access the token management page unauthenticated.");
107
        }
108
109
        switch ($request->request->get('submit')) {
110
            case "NEVERMIND":
111
                return new RunnableResponse([Auth\ProcessingChain::class, 'resumeProcessing'], [$state]);
112
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
113
            case "DELETE":
114
                $credId = $request->request->get('credId');
115
                if ($state['FIDO2AuthSuccessful'] == $credId) {
116
                    throw new Exception("Attempt to delete the currently used credential despite UI preventing this.");
117
                }
118
119
                $store = $state['webauthn:store'];
120
                $store->deleteTokenData($credId);
121
122
                if (array_key_exists('Registration', $state)) {
0 ignored issues
show
Bug introduced by
It seems like $state can also be of type null; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

122
                if (array_key_exists('Registration', /** @scrutinizer ignore-type */ $state)) {
Loading history...
123
                    foreach ($state['FIDO2Tokens'] as $key => $value) {
124
                        if ($state['FIDO2Tokens'][$key][0] == $credId) {
125
                            unset($state['FIDO2Tokens'][$key]);
126
                            break;
127
                        }
128
                    }
129
130
                    return new RunnableResponse([StaticProcessHelper::class, 'saveStateAndRedirect'], [$state]);
131
                } else {
132
                    return new RunnableResponse([Auth\ProcessingChain::class, 'resumeProcessing'], [$state]);
133
                }
134
                break;
135
            default:
136
                throw new Exception("Unknown submit button state.");
137
        }
138
    }
139
}
140