ClientCertificateRepository::getFirstOrGenerate()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 31
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 31
ccs 0
cts 14
cp 0
rs 9.0444
c 0
b 0
f 0
cc 6
nc 6
nop 0
crap 42
1
<?php
2
3
namespace Gameap\Repositories;
4
5
use Gameap\Exceptions\GameapException;
6
use Gameap\Exceptions\Repositories\InvalidCertificateException;
7
use Gameap\Http\Requests\ClientCertificatesRequest;
8
use Gameap\Models\ClientCertificate;
9
use Gameap\Services\Daemon\CertificateService;
10
use Illuminate\Support\Facades\Storage;
11
12
class ClientCertificateRepository extends Repository
13
{
14
    public const STORAGE_CERTS_PATH = 'certs/client';
15
16
    /**
17
     * ClientCertificateRepository constructor.
18
     * @param ClientCertificate $clientCertificate
19
     */
20 9
    public function __construct(ClientCertificate $clientCertificate)
21
    {
22 9
        $this->model = $clientCertificate;
23 9
    }
24
25
    /**
26
     * @param int $perPage
27
     *
28
     * @return mixed
29
     */
30 3
    public function getAll($perPage = 20)
31
    {
32 3
        return ClientCertificate::orderBy('id')->paginate($perPage);
33
    }
34
35
    /**
36
     * @param $id
37
     * @return mixed
38
     */
39
    public function findById($id) {
40
        return ClientCertificate::findOrFail($id);
41 3
    }
42
43 3
    /**
44
     * @param ClientCertificatesRequest $request
45 3
     *
46 3
     * @return ClientCertificate
47 3
     * @throws GameapException
48
     */
49
    public function store(ClientCertificatesRequest $request)
50
    {
51 3
        $attributes = $request->all();
52 3
        
53 3
        if ($request->hasFile('certificate')) {
54
            $attributes['certificate'] = $request->file('certificate')->store(
55
                self::STORAGE_CERTS_PATH,
56
                'local'
57 3
            );
58 3
        }
59
60
        if ($request->hasFile('private_key')) {
61
            $attributes['private_key'] = $request->file('private_key')->store(
62
                self::STORAGE_CERTS_PATH,
63
                'local'
64
            );
65
        }
66
67
        
68
        if (!openssl_x509_check_private_key(Storage::get($attributes['certificate']), Storage::get($attributes['private_key']))) {
69
            throw new InvalidCertificateException(__('client_certificates.private_key_not_correspond'));
0 ignored issues
show
Bug introduced by
It seems like __('client_certificates....te_key_not_correspond') can also be of type array and array; however, parameter $message of Gameap\Exceptions\Reposi...xception::__construct() does only seem to accept string, 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

69
            throw new InvalidCertificateException(/** @scrutinizer ignore-type */ __('client_certificates.private_key_not_correspond'));
Loading history...
70
        }
71
72
        $info = CertificateService::certificateInfo($attributes['certificate']);
73
74
        $attributes['expires']          = $info['expires'];
75
        $attributes['fingerprint']      = CertificateService::fingerprintString($attributes['certificate'], 'sha1');
0 ignored issues
show
Unused Code introduced by
The call to Gameap\Services\Daemon\C...ce::fingerprintString() has too many arguments starting with 'sha1'. ( Ignorable by Annotation )

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

75
        /** @scrutinizer ignore-call */ 
76
        $attributes['fingerprint']      = CertificateService::fingerprintString($attributes['certificate'], 'sha1');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
76
        $attributes['private_key_pass'] = '';
77
        
78
        return ClientCertificate::create($attributes);
79
    }
80
81
    /**
82
     * @param ClientCertificate $clientCertificate
83
     * @param ClientCertificatesRequest $request
84
     */
85
    public function update(ClientCertificate $clientCertificate, array $request): void
86
    {
87
        $attributes = $request->all();
88
89
        if ($request->hasFile('certificate')) {
90
            $attributes['gdaemon_server_cert'] = $request->file('certificate')->store(
91
                self::STORAGE_CERTS_PATH,
92
                'local'
93
            );
94
        }
95
96
        if ($request->hasFile('gdaemon_server_cert')) {
97
            $attributes['gdaemon_server_cert'] = $request->file('private_key')->store(
98
                self::STORAGE_CERTS_PATH,
99
                'local'
100
            );
101
        }
102
        
103
        $clientCertificate->update($attributes);
104
    }
105
106
    /**
107
     * @param ClientCertificate $clientCertificate
108
     * @throws \Exception
109
     */
110
    public function destroy(ClientCertificate $clientCertificate): void
111
    {
112
        if (Storage::disk('local')->exists($clientCertificate->certificate)) {
113
            // TODO: Not working =(
114
            // Storage::disk('local')->delete('certs/client/' . $clientCertificate->certificate);
115
116
            $file = Storage::disk('local')
117
                ->getDriver()
118
                ->getAdapter()
119
                ->applyPathPrefix($clientCertificate->certificate);
120
121
            unlink($file);
122
        }
123
124
        if (Storage::disk('local')->exists($clientCertificate->private_key)) {
125
            $file = Storage::disk('local')
126
                ->getDriver()
127
                ->getAdapter()
128
                ->applyPathPrefix($clientCertificate->private_key);
129
130
            unlink($file);
131
        }
132
133
        $clientCertificate->delete();
134
    }
135
136
    /**
137
     * @param ClientCertificate $clientCertificate
138
     */
139
    public function certificateInfo(ClientCertificate $clientCertificate)
140
    {
141
        return CertificateService::certificateInfo($clientCertificate->certificate);
142
    }
143
144
    /**
145
     * @param int $id
146
     * @return ClientCertificate
147
     */
148
    public function getFirstOrGenerate()
149
    {
150
        $clientCertificate = ClientCertificate::select()->first();
151
152
        if (empty($clientCertificate)) {
153
            $attributes        = $this->generate();
154
            $clientCertificate = ClientCertificate::create($attributes);
155
        } else {
156
            // Fix. If client certificate exists in database but not exists certificates files.
157
            // Delete invalid files. Generate new certificates.
158
            if (!Storage::exists($clientCertificate->certificate) || !Storage::exists($clientCertificate->private_key)) {
159
                if (Storage::exists($clientCertificate->certificate)) {
160
                    Storage::delete($clientCertificate->certificate);
161
                }
162
163
                if (Storage::exists($clientCertificate->private_key)) {
164
                    Storage::delete($clientCertificate->private_key);
165
                }
166
167
                $attributes = $this->generate();
168
169
                $clientCertificate->fingerprint      = $attributes['fingerprint'];
170
                $clientCertificate->expires          = $attributes['expires'];
171
                $clientCertificate->certificate      = $attributes['certificate'];
172
                $clientCertificate->private_key      = $attributes['private_key'];
173
                $clientCertificate->private_key_pass = $attributes['private_key_pass'];
174
                $clientCertificate->save();
175
            }
176
        }
177
178
        return $clientCertificate;
179
    }
180
181
    /**
182
     * Generate certificate
183
     * Return array with paths to certificates
184
     *
185
     * @return array
186
     */
187
    private function generate()
188
    {
189
        $timestamp       = time();
190
        $certificateName = self::STORAGE_CERTS_PATH . "/client_{$timestamp}.crt";
191
        $privateKeyName  = self::STORAGE_CERTS_PATH . "/client_{$timestamp}.key";
192
193
        CertificateService::generate($certificateName, $privateKeyName);
194
        $info = CertificateService::certificateInfo($certificateName);
195
196
        return [
197
            'fingerprint'      => CertificateService::fingerprintString($certificateName),
198
            'expires'          => $info['expires'],
199
            'certificate'      => $certificateName,
200
            'private_key'      => $privateKeyName,
201
            'private_key_pass' => '',
202
        ];
203
    }
204
}
205