Completed
Pull Request — master (#182)
by Alexander
02:19
created

CsrfTest::emptyTokenInRequestResultIn400()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
rs 10
1
<?php
2
3
4
namespace Yiisoft\Yii\Web\Tests\Middleware;
5
6
use Nyholm\Psr7\Factory\Psr17Factory;
7
use Nyholm\Psr7\Response;
8
use Nyholm\Psr7\ServerRequest;
9
use PHPUnit\Framework\MockObject\MockObject;
10
use PHPUnit\Framework\TestCase;
11
use Psr\Http\Message\ResponseInterface;
12
use Psr\Http\Message\ServerRequestInterface;
13
use Psr\Http\Server\RequestHandlerInterface;
14
use TheSeer\Tokenizer\Token;
15
use Yiisoft\Router\Method;
16
use Yiisoft\Security\Random;
17
use Yiisoft\Security\TokenMask;
18
use Yiisoft\Yii\Web\Middleware\Csrf;
19
use Yiisoft\Yii\Web\Session\SessionInterface;
20
21
final class CsrfTest extends TestCase
22
{
23
    private const PARAM_NAME = 'csrf';
24
25
    /**
26
     * @test
27
     */
28
    public function validTokenInBodyPostRequestResultIn200()
29
    {
30
        $token = $this->generateToken();
31
        $middleware = $this->createCsrfMiddlewareWithToken($token);
32
        $response = $middleware->process($this->createPostServerRequestWithBodyToken($token), $this->createRequestHandler());
33
        $this->assertEquals(200, $response->getStatusCode());
34
    }
35
36
    /**
37
     * @test
38
     */
39
    public function validTokenInBodyPutRequestResultIn200()
40
    {
41
        $token = $this->generateToken();
42
        $middleware = $this->createCsrfMiddlewareWithToken($token);
43
        $response = $middleware->process($this->createPutServerRequestWithBodyToken($token), $this->createRequestHandler());
44
        $this->assertEquals(200, $response->getStatusCode());
45
    }
46
47
    /**
48
     * @test
49
     */
50
    public function validTokenInBodyDeleteRequestResultIn200()
51
    {
52
        $token = $this->generateToken();
53
        $middleware = $this->createCsrfMiddlewareWithToken($token);
54
        $response = $middleware->process($this->createDeleteServerRequestWithBodyToken($token), $this->createRequestHandler());
55
        $this->assertEquals(200, $response->getStatusCode());
56
    }
57
58
    /**
59
     * @test
60
     */
61
    public function validTokenInHeaderResultIn200()
62
    {
63
        $token = $this->generateToken();
64
        $middleware = $this->createCsrfMiddlewareWithToken($token);
65
        $response = $middleware->process($this->createPostServerRequestWithHeaderToken($token), $this->createRequestHandler());
66
        $this->assertEquals(200, $response->getStatusCode());
67
    }
68
69
    /**
70
     * @test
71
     */
72
    public function getIsAlwaysAllowed()
73
    {
74
        $middleware = $this->createCsrfMiddlewareWithToken('');
75
        $response = $middleware->process($this->createServerRequest(Method::GET), $this->createRequestHandler());
76
        $this->assertEquals(200, $response->getStatusCode());
77
    }
78
79
    /**
80
     * @test
81
     */
82
    public function invalidTokenResultIn403()
83
    {
84
        $middleware = $this->createCsrfMiddlewareWithToken($this->generateToken());
85
        $response = $middleware->process($this->createPostServerRequestWithBodyToken($this->generateToken()), $this->createRequestHandler());
86
        $this->assertEquals(403, $response->getStatusCode());
87
    }
88
89
    /**
90
     * @test
91
     */
92
    public function emptyTokenInSessionResultIn403()
93
    {
94
        $middleware = $this->createCsrfMiddlewareWithToken('');
95
        $response = $middleware->process($this->createPostServerRequestWithBodyToken($this->generateToken()), $this->createRequestHandler());
96
        $this->assertEquals(403, $response->getStatusCode());
97
    }
98
99
    /**
100
     * @test
101
     */
102
    public function emptyTokenInRequestResultIn403()
103
    {
104
        $middleware = $this->createCsrfMiddlewareWithToken($this->generateToken());
105
        $response = $middleware->process($this->createServerRequest(), $this->createRequestHandler());
106
        $this->assertEquals(403, $response->getStatusCode());
107
    }
108
109
    private function createServerRequest(string $method = Method::POST, array $bodyParams = [], array $headParams = []): ServerRequestInterface
110
    {
111
        $request = new ServerRequest($method, '/', $headParams);
112
        return $request->withParsedBody($bodyParams);
113
    }
114
115
    private function createPostServerRequestWithBodyToken(string $token): ServerRequestInterface
116
    {
117
        return $this->createServerRequest(Method::POST, $this->getBodyRequestParamsByToken($token));
118
    }
119
120
    private function createPutServerRequestWithBodyToken(string $token): ServerRequestInterface
121
    {
122
        return $this->createServerRequest(Method::PUT, $this->getBodyRequestParamsByToken($token));
123
    }
124
125
    private function createDeleteServerRequestWithBodyToken(string $token): ServerRequestInterface
126
    {
127
        return $this->createServerRequest(Method::DELETE, $this->getBodyRequestParamsByToken($token));
128
    }
129
130
    private function createPostServerRequestWithHeaderToken(string $token): ServerRequestInterface
131
    {
132
        return $this->createServerRequest(Method::POST, [], [
133
            Csrf::HEADER_NAME => TokenMask::apply($token),
134
        ]);
135
    }
136
137
    private function createRequestHandler(): RequestHandlerInterface
138
    {
139
        return new class implements RequestHandlerInterface {
140
            public function handle(ServerRequestInterface $request): ResponseInterface
141
            {
142
                return new Response(200);
143
            }
144
        };
145
    }
146
147
    private function createSessionMock(string $returnToken)
148
    {
149
        /**
150
         * @var SessionInterface|MockObject $sessionMock
151
         */
152
        $sessionMock = $this->createMock(SessionInterface::class);
153
154
        $sessionMock
155
            ->expects($this->once())
156
            ->method('get')
157
            ->willReturn($returnToken);
158
159
        return $sessionMock;
160
    }
161
162
    private function createCsrfMiddlewareWithToken(string $token): Csrf
163
    {
164
        $middleware = new Csrf(new Psr17Factory(), $this->createSessionMock($token));
165
        $middleware->setName(self::PARAM_NAME);
166
167
        return $middleware;
168
    }
169
170
    private function generateToken(): string
171
    {
172
        return Random::string();
173
    }
174
175
    private function getBodyRequestParamsByToken(string $token): array
176
    {
177
        return [
178
            self::PARAM_NAME => TokenMask::apply($token),
179
        ];
180
    }
181
}
182