GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

FileRepository::saveFileContents()   B
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 12
nc 5
nop 2
1
<?php
2
/**
3
 * Pterodactyl - Panel
4
 * Copyright (c) 2015 - 2017 Dane Everitt <[email protected]>.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in all
14
 * copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 * SOFTWARE.
23
 */
24
25
namespace Pterodactyl\Repositories\Daemon;
26
27
use Exception;
28
use GuzzleHttp\Client;
29
use Pterodactyl\Models\Server;
30
use Pterodactyl\Exceptions\DisplayException;
31
use Pterodactyl\Repositories\HelperRepository;
32
33
class FileRepository
34
{
35
    /**
36
     * The Eloquent Model associated with the requested server.
37
     *
38
     * @var \Pterodactyl\Models\Server
39
     */
40
    protected $server;
41
42
    /**
43
     * Constructor.
44
     *
45
     * @param  string  $uuid
46
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
47
     */
48
    public function __construct($uuid)
49
    {
50
        $this->server = Server::byUuid($uuid);
51
    }
52
53
    /**
54
     * Get the contents of a requested file for the server.
55
     *
56
     * @param  string  $file
57
     * @return array
58
     *
59
     * @throws \GuzzleHttp\Exception\RequestException
60
     * @throws \Pterodactyl\Exceptions\DisplayException
61
     */
62
    public function returnFileContents($file)
63
    {
64
        if (empty($file)) {
65
            throw new Exception('Not all parameters were properly passed to the function.');
66
        }
67
68
        $file = (object) pathinfo($file);
69
        $file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/';
70
71
        $res = $this->server->guzzleClient()->request('GET', '/server/file/stat/' . rawurlencode($file->dirname . $file->basename));
72
73
        $stat = json_decode($res->getBody());
74 View Code Duplication
        if ($res->getStatusCode() !== 200 || ! isset($stat->size)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
            throw new DisplayException('The daemon provided a non-200 error code on stat lookup: HTTP\\' . $res->getStatusCode());
76
        }
77
78
        if (! in_array($stat->mime, HelperRepository::editableFiles())) {
79
            throw new DisplayException('You cannot edit that type of file (' . $stat->mime . ') through the panel.');
80
        }
81
82
        if ($stat->size > 5000000) {
83
            throw new DisplayException('That file is too large to open in the browser, consider using a SFTP client.');
84
        }
85
86
        $res = $this->server->guzzleClient()->request('GET', '/server/file/f/' . rawurlencode($file->dirname . $file->basename));
87
88
        $json = json_decode($res->getBody());
89 View Code Duplication
        if ($res->getStatusCode() !== 200 || ! isset($json->content)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
90
            throw new DisplayException('The daemon provided a non-200 error code: HTTP\\' . $res->getStatusCode());
91
        }
92
93
        return [
94
            'file' => $json,
95
            'stat' => $stat,
96
        ];
97
    }
98
99
    /**
100
     * Save the contents of a requested file on the daemon.
101
     *
102
     * @param  string  $file
103
     * @param  string  $content
104
     * @return bool
105
     *
106
     * @throws \GuzzleHttp\Exception\RequestException
107
     * @throws \Pterodactyl\Exceptions\DisplayException
108
     */
109
    public function saveFileContents($file, $content)
110
    {
111
        if (empty($file)) {
112
            throw new Exception('A valid file and path must be specified to save a file.');
113
        }
114
115
        $file = (object) pathinfo($file);
116
        $file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/';
117
118
        $res = $this->server->guzzleClient()->request('POST', '/server/file/save', [
119
            'json' => [
120
                'path' => rawurlencode($file->dirname . $file->basename),
121
                'content' => $content,
122
            ],
123
        ]);
124
125
        if ($res->getStatusCode() !== 204) {
126
            throw new DisplayException('An error occured while attempting to save this file. ' . $res->getBody());
127
        }
128
129
        return true;
130
    }
131
132
    /**
133
     * Returns a listing of all files and folders within a specified directory on the daemon.
134
     *
135
     * @param  string  $directory
136
     * @return object
137
     *
138
     * @throws \GuzzleHttp\Exception\RequestException
139
     * @throws \Pterodactyl\Exceptions\DisplayException
140
     */
141
    public function returnDirectoryListing($directory)
142
    {
143
        if (empty($directory)) {
144
            throw new Exception('A valid directory must be specified in order to list its contents.');
145
        }
146
147
        try {
148
            $res = $this->server->guzzleClient()->request('GET', '/server/directory/' . rawurlencode($directory));
149
        } catch (\GuzzleHttp\Exception\ClientException $ex) {
150
            $json = json_decode($ex->getResponse()->getBody());
151
152
            throw new DisplayException($json->error);
153
        } catch (\GuzzleHttp\Exception\ServerException $ex) {
154
            throw new DisplayException('A remote server error was encountered while attempting to display this directory.');
155
        } catch (\GuzzleHttp\Exception\ConnectException $ex) {
156
            throw new DisplayException('A ConnectException was encountered: unable to contact daemon.');
157
        } catch (\Exception $ex) {
158
            throw $ex;
159
        }
160
161
        $json = json_decode($res->getBody());
162
163
        // Iterate through results
164
        $files = [];
165
        $folders = [];
166
        foreach ($json as &$value) {
167
            if ($value->directory) {
168
                // @TODO Handle Symlinks
169
                $folders[] = [
170
                    'entry' => $value->name,
171
                    'directory' => trim($directory, '/'),
172
                    'size' => null,
173
                    'date' => strtotime($value->modified),
174
                    'mime' => $value->mime,
175
                ];
176
            } elseif ($value->file) {
177
                $files[] = [
178
                    'entry' => $value->name,
179
                    'directory' => trim($directory, '/'),
180
                    'extension' => pathinfo($value->name, PATHINFO_EXTENSION),
181
                    'size' => HelperRepository::bytesToHuman($value->size),
0 ignored issues
show
Deprecated Code introduced by
The method Pterodactyl\Repositories...ository::bytesToHuman() has been deprecated.

This method has been deprecated.

Loading history...
182
                    'date' => strtotime($value->modified),
183
                    'mime' => $value->mime,
184
                ];
185
            }
186
        }
187
188
        return (object) [
189
            'files' => $files,
190
            'folders' => $folders,
191
        ];
192
    }
193
}
194