2016-11-16 01:20:32 +00:00
< ? php
/**
* Pterodactyl - Panel
2017-01-24 22:57:08 +00:00
* Copyright ( c ) 2015 - 2017 Dane Everitt < dane @ daneeveritt . com >.
2016-11-16 01:20:32 +00:00
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ), to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
*/
2016-12-14 21:56:25 +00:00
2017-03-10 23:25:12 +00:00
namespace Pterodactyl\Repositories ;
2016-11-16 01:20:32 +00:00
use DB ;
use Uuid ;
2016-12-14 21:56:25 +00:00
use Storage ;
2016-11-16 01:20:32 +00:00
use Validator ;
2017-03-15 01:18:36 +00:00
use Pterodactyl\Models\Pack ;
2016-11-16 01:20:32 +00:00
use Pterodactyl\Services\UuidService ;
use Pterodactyl\Exceptions\DisplayException ;
use Pterodactyl\Exceptions\DisplayValidationException ;
2017-03-10 23:25:12 +00:00
class PackRepository
2016-11-16 01:20:32 +00:00
{
2017-03-15 01:18:36 +00:00
/**
* Creates a new pack on the system .
*
2017-03-19 23:36:50 +00:00
* @ param array $data
2017-03-15 01:18:36 +00:00
* @ return \Pterodactyl\Models\Pack
*
* @ throws \Pterodactyl\Exceptions\DisplayException
* @ throws \Pterodactyl\Exceptions\DisplayValidationException
*/
2016-11-16 01:20:32 +00:00
public function create ( array $data )
{
$validator = Validator :: make ( $data , [
'name' => 'required|string' ,
'version' => 'required|string' ,
2016-11-16 22:22:22 +00:00
'description' => 'sometimes|nullable|string' ,
2017-03-15 01:18:36 +00:00
'selectable' => 'sometimes|required|boolean' ,
'visible' => 'sometimes|required|boolean' ,
'locked' => 'sometimes|required|boolean' ,
'option_id' => 'required|exists:service_options,id' ,
2016-11-16 01:20:32 +00:00
]);
if ( $validator -> fails ()) {
2017-03-15 01:18:36 +00:00
throw new DisplayValidationException ( json_encode ( $validator -> errors ()));
2016-11-16 01:20:32 +00:00
}
if ( isset ( $data [ 'file_upload' ])) {
2016-12-14 21:56:25 +00:00
if ( ! $data [ 'file_upload' ] -> isValid ()) {
2016-11-16 01:20:32 +00:00
throw new DisplayException ( 'The file provided does not appear to be valid.' );
}
2017-01-27 21:47:50 +00:00
if ( ! in_array ( $data [ 'file_upload' ] -> getMimeType (), [ 'application/gzip' , 'application/x-gzip' ])) {
throw new DisplayException ( 'The file provided (' . $data [ 'file_upload' ] -> getMimeType () . ') does not meet the required filetype of application/gzip.' );
2016-11-16 01:20:32 +00:00
}
}
2017-03-15 01:18:36 +00:00
return DB :: transaction ( function () use ( $data ) {
$uuid = new UuidService ();
$pack = new Pack ;
$pack -> uuid = $uuid -> generate ( 'packs' , 'uuid' );
$pack -> fill ([
'option_id' => $data [ 'option_id' ],
2016-11-16 01:20:32 +00:00
'name' => $data [ 'name' ],
'version' => $data [ 'version' ],
'description' => ( empty ( $data [ 'description' ])) ? null : $data [ 'description' ],
'selectable' => isset ( $data [ 'selectable' ]),
2016-12-14 21:56:25 +00:00
'visible' => isset ( $data [ 'visible' ]),
2017-03-15 01:18:36 +00:00
'locked' => isset ( $data [ 'locked' ]),
]) -> save ();
if ( ! $pack -> exists ) {
throw new DisplayException ( 'Model does not exist after creation. Did an event prevent it from saving?' );
}
2016-11-16 01:20:32 +00:00
2016-11-16 22:22:22 +00:00
Storage :: makeDirectory ( 'packs/' . $pack -> uuid );
if ( isset ( $data [ 'file_upload' ])) {
2017-01-25 23:20:41 +00:00
$data [ 'file_upload' ] -> storeAs ( 'packs/' . $pack -> uuid , 'archive.tar.gz' );
2016-11-16 22:22:22 +00:00
}
2017-03-15 01:18:36 +00:00
return $pack ;
});
2016-11-16 22:22:22 +00:00
}
2017-03-15 01:18:36 +00:00
/**
* Creates a new pack on the system given a template file .
*
2017-03-19 23:36:50 +00:00
* @ param array $data
2017-03-15 01:18:36 +00:00
* @ return \Pterodactyl\Models\Pack
*
* @ throws \Pterodactyl\Exceptions\DisplayException
*/
2016-11-16 22:22:22 +00:00
public function createWithTemplate ( array $data )
{
2016-12-14 21:56:25 +00:00
if ( ! isset ( $data [ 'file_upload' ])) {
2016-11-16 22:22:22 +00:00
throw new DisplayException ( 'No template file was found submitted with this request.' );
}
2016-11-16 01:20:32 +00:00
2016-12-14 21:56:25 +00:00
if ( ! $data [ 'file_upload' ] -> isValid ()) {
2016-11-16 22:22:22 +00:00
throw new DisplayException ( 'The file provided does not appear to be valid.' );
}
2016-11-16 01:20:32 +00:00
2016-12-14 21:56:25 +00:00
if ( ! in_array ( $data [ 'file_upload' ] -> getMimeType (), [
2016-11-16 22:22:22 +00:00
'application/zip' ,
'text/plain' ,
2016-12-14 21:56:25 +00:00
'application/json' ,
2016-11-16 22:22:22 +00:00
])) {
throw new DisplayException ( 'The file provided (' . $data [ 'file_upload' ] -> getMimeType () . ') does not meet the required filetypes of application/zip or application/json.' );
}
if ( $data [ 'file_upload' ] -> getMimeType () === 'application/zip' ) {
$zip = new \ZipArchive ;
2016-12-14 21:56:25 +00:00
if ( ! $zip -> open ( $data [ 'file_upload' ] -> path ())) {
2016-11-16 22:22:22 +00:00
throw new DisplayException ( 'The uploaded archive was unable to be opened.' );
}
$isTar = $zip -> locateName ( 'archive.tar.gz' );
2017-01-25 23:20:41 +00:00
if ( ! $zip -> locateName ( 'import.json' ) || ! $isTar ) {
2016-11-16 22:22:22 +00:00
throw new DisplayException ( 'This contents of the provided archive were in an invalid format.' );
}
$json = json_decode ( $zip -> getFromName ( 'import.json' ));
2017-02-05 22:58:17 +00:00
$pack = $this -> create ([
2016-11-16 22:22:22 +00:00
'name' => $json -> name ,
'version' => $json -> version ,
'description' => $json -> description ,
2017-03-15 01:18:36 +00:00
'option_id' => $data [ 'option_id' ],
2016-11-16 22:22:22 +00:00
'selectable' => $json -> selectable ,
'visible' => $json -> visible ,
2017-03-15 01:18:36 +00:00
'locked' => $json -> locked ,
2016-11-16 22:22:22 +00:00
]);
2017-01-25 23:20:41 +00:00
if ( ! $zip -> extractTo ( storage_path ( 'app/packs/' . $pack -> uuid ), 'archive.tar.gz' )) {
2016-11-16 22:22:22 +00:00
$pack -> delete ();
throw new DisplayException ( 'Unable to extract the archive file to the correct location.' );
}
$zip -> close ();
2016-12-14 21:56:25 +00:00
2017-02-05 22:58:17 +00:00
return $pack ;
2016-11-16 22:22:22 +00:00
} else {
$json = json_decode ( file_get_contents ( $data [ 'file_upload' ] -> path ()));
2016-12-14 21:56:25 +00:00
2016-11-16 22:22:22 +00:00
return $this -> create ([
'name' => $json -> name ,
'version' => $json -> version ,
'description' => $json -> description ,
2017-03-15 01:18:36 +00:00
'option_id' => $data [ 'option_id' ],
2016-11-16 22:22:22 +00:00
'selectable' => $json -> selectable ,
'visible' => $json -> visible ,
2017-03-15 01:18:36 +00:00
'locked' => $json -> locked ,
2016-11-16 22:22:22 +00:00
]);
}
2016-11-16 01:20:32 +00:00
}
2017-03-15 01:18:36 +00:00
/**
* Updates a pack on the system .
*
2017-03-19 23:36:50 +00:00
* @ param int $id
* @ param array $data
2017-03-15 01:18:36 +00:00
* @ return \Pterodactyl\Models\Pack
*
2017-03-16 00:52:37 +00:00
* @ throws \Pterodactyl\Exceptions\DisplayException
2017-03-15 01:18:36 +00:00
* @ throws \Pterodactyl\Exceptions\DisplayValidationException
*/
2016-11-16 21:09:28 +00:00
public function update ( $id , array $data )
{
$validator = Validator :: make ( $data , [
2017-03-15 01:18:36 +00:00
'name' => 'sometimes|required|string' ,
2017-03-16 00:52:37 +00:00
'option_id' => 'sometimes|required|exists:service_options,id' ,
2017-03-15 01:18:36 +00:00
'version' => 'sometimes|required|string' ,
'description' => 'sometimes|string' ,
'selectable' => 'sometimes|required|boolean' ,
'visible' => 'sometimes|required|boolean' ,
'locked' => 'sometimes|required|boolean' ,
2016-11-16 21:09:28 +00:00
]);
if ( $validator -> fails ()) {
2017-03-15 01:18:36 +00:00
throw new DisplayValidationException ( json_encode ( $validator -> errors ()));
2016-11-16 21:09:28 +00:00
}
2017-03-16 00:52:37 +00:00
$pack = Pack :: withCount ( 'servers' ) -> findOrFail ( $id );
if ( $pack -> servers_count > 0 && ( isset ( $data [ 'option_id' ]) && ( int ) $data [ 'option_id' ] !== $pack -> option_id )) {
throw new DisplayException ( 'You cannot modify the associated option if servers are attached to a pack.' );
}
2017-03-15 01:18:36 +00:00
$pack -> fill ([
'name' => isset ( $data [ 'name' ]) ? $data [ 'name' ] : $pack -> name ,
2017-03-16 00:52:37 +00:00
'option_id' => isset ( $data [ 'option_id' ]) ? $data [ 'option_id' ] : $pack -> option_id ,
2017-03-15 01:18:36 +00:00
'version' => isset ( $data [ 'version' ]) ? $data [ 'version' ] : $pack -> version ,
2017-02-05 22:58:17 +00:00
'description' => ( empty ( $data [ 'description' ])) ? null : $data [ 'description' ],
2017-03-16 00:52:37 +00:00
'selectable' => isset ( $data [ 'selectable' ]),
'visible' => isset ( $data [ 'visible' ]),
'locked' => isset ( $data [ 'locked' ]),
2017-03-15 01:18:36 +00:00
]) -> save ();
return $pack ;
2016-11-16 21:09:28 +00:00
}
2017-03-15 01:18:36 +00:00
/**
* Deletes a pack and files from the system .
*
* @ param int $id
* @ return void
*
* @ throws \Pterodactyl\Exceptions\DisplayException
*/
2016-12-14 21:56:25 +00:00
public function delete ( $id )
{
2017-03-15 01:18:36 +00:00
$pack = Models\Pack :: withCount ( 'servers' ) -> findOrFail ( $id );
if ( $pack -> servers_count > 0 ) {
throw new DisplayException ( 'Cannot delete a pack from the system if servers are assocaited with it.' );
}
2016-11-18 22:31:57 +00:00
DB :: transaction ( function () use ( $pack ) {
$pack -> delete ();
Storage :: deleteDirectory ( 'packs/' . $pack -> uuid );
});
}
2016-11-16 01:20:32 +00:00
}