Passed
Push — master ( 69e236...41c6f3 )
by Cesar
11:22 queued 07:21
created

AccessCode::getResponseAccessCode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 4
c 1
b 0
f 1
dl 0
loc 7
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
namespace MagicLink;
4
5
use Illuminate\Contracts\Encryption\DecryptException;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Facades\Hash;
8
9
trait AccessCode
10
{
11
    abstract protected function getAccessCode();
12
13
    abstract protected function getMagikLinkId();
14
15
    protected $cookieName = 'magic-link-access-code';
16
17
    public function getResponseAccessCode()
18
    {
19
        $responseFromForm = $this->getResponseAccessCodeFromForm();
20
21
        return $responseFromForm
22
            ? $responseFromForm
23
            : $this->getResponseAccessCodeFromCookie();
24
    }
25
26
    /**
27
     * Check if access code is right.
28
     */
29
    private function checkAccessCode(?string $accessCode): bool
30
    {
31
        if ($accessCode === null) {
32
            return false;
33
        }
34
35
        return Hash::check($accessCode, $this->getAccessCode());
36
    }
37
38
    /**
39
     * The action was protected with an access code.
40
     */
41
    private function protectedWithAccessCode(): bool
42
    {
43
        return ! is_null($this->getAccessCode() ?? null);
44
    }
45
46
    private function getResponseAccessCodeFromForm()
47
    {
48
        $accessCode = $this->getAccessCodeFromForm();
49
50
        if (
51
            $this->protectedWithAccessCode()
52
            && $accessCode
53
            && $this->checkAccessCode($accessCode)
54
        ) {
55
            return redirect(request()->url())->withCookie(
56
                cookie(
57
                    $this->cookieName,
58
                    encrypt($this->getMagikLinkId().'|'.$accessCode),
59
                    0,
60
                    '/'
61
                )
62
            );
63
        }
64
65
        return null;
66
    }
67
68
    private function getResponseAccessCodeFromCookie()
69
    {
70
        if ($this->protectedWithAccessCode()) {
71
            if ($this->getAccessCodeFromCookie()) {
72
                if ($this->checkAccessCode($this->getAccessCodeFromCookie())) {
73
                    return null;
74
                }
75
            }
76
77
            return response()->view('magiclink::ask-for-access-code-form', [], 403);
78
        }
79
80
        return null;
81
    }
82
83
    private function getAccessCodeFromForm()
84
    {
85
        return request()->get('access-code');
86
    }
87
88
    private function getAccessCodeFromCookie()
89
    {
90
        $accessCodeCookies = request()->cookie($this->cookieName);
91
92
        if (! $accessCodeCookies) {
93
            return null;
94
        }
95
96
        try {
97
            $cookie = Arr::last((array) $accessCodeCookies);
98
99
            [$magiclinkId, $accessCode] = explode('|', decrypt($cookie));
100
101
            if ($magiclinkId === $this->getMagikLinkId()) {
102
                return $accessCode;
103
            }
104
        } catch (DecryptException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
105
        }
106
107
        return null;
108
    }
109
}
110