/**
  * Adds a new database to a given database server.
  * @param int   $server   Id of the server to add a database for.
  * @param array $options  Array of options for creating that database.
  * @return void
  */
 public function create($server, $options)
 {
     $server = Models\Server::findOrFail($server);
     $validator = Validator::make($options, ['db_server' => 'required|exists:database_servers,id', 'database' => 'required|regex:/^\\w{1,100}$/', 'remote' => 'required|regex:/^[0-9%.]{1,15}$/']);
     if ($validator->fails()) {
         throw new DisplayValidationException($validator->errors());
     }
     DB::beginTransaction();
     try {
         $db = new Models\Database();
         $db->fill(['server_id' => $server->id, 'db_server' => $options['db_server'], 'database' => $server->uuidShort . '_' . $options['database'], 'username' => $server->uuidShort . '_' . str_random(7), 'remote' => $options['remote'], 'password' => Crypt::encrypt(str_random(20))]);
         $db->save();
         // Contact Remote
         $dbr = Models\DatabaseServer::findOrFail($options['db_server']);
         $capsule = new Capsule();
         $capsule->addConnection(['driver' => 'mysql', 'host' => $dbr->host, 'port' => $dbr->port, 'database' => 'mysql', 'username' => $dbr->username, 'password' => Crypt::decrypt($dbr->password), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'options' => [\PDO::ATTR_TIMEOUT => 3]]);
         $capsule->setAsGlobal();
         Capsule::statement('CREATE DATABASE ' . $db->database);
         Capsule::statement('CREATE USER \'' . $db->username . '\'@\'' . $db->remote . '\' IDENTIFIED BY \'' . Crypt::decrypt($db->password) . '\'');
         Capsule::statement('GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON ' . $db->database . '.* TO \'' . $db->username . '\'@\'' . $db->remote . '\'');
         Capsule::statement('FLUSH PRIVILEGES');
         DB::commit();
         return true;
     } catch (\Exception $ex) {
         DB::rollback();
         throw $ex;
     }
 }
Beispiel #2
0
 /**
  * Constructor
  *
  * @param string $server The server Short UUID
  */
 public function __construct($uuid)
 {
     $this->server = Server::getByUUID($uuid);
     $this->node = Node::getByID($this->server->node);
     $this->client = Node::guzzleRequest($this->server->node);
     $this->headers = Server::getGuzzleHeaders($uuid);
 }
Beispiel #3
0
 /**
  * Create a new scheduled task for a given server.
  * @param  int      $id
  * @param  array    $data
  *
  * @throws DisplayException
  * @throws DisplayValidationException
  * @return void
  */
 public function create($id, $data)
 {
     $server = Models\Server::findOrFail($id);
     $validator = Validator::make($data, ['action' => 'string|required', 'data' => 'string|required', 'year' => 'string|sometimes', 'day_of_week' => 'string|sometimes', 'month' => 'string|sometimes', 'day_of_month' => 'string|sometimes', 'hour' => 'string|sometimes', 'minute' => 'string|sometimes']);
     if ($validator->fails()) {
         throw new DisplayValidationException(json_encode($validator->errors()));
     }
     if (!in_array($data['action'], $this->actions)) {
         throw new DisplayException('The action provided is not valid.');
     }
     $cron = $this->defaults;
     foreach ($this->defaults as $setting => $value) {
         if (array_key_exists($setting, $data) && !is_null($data[$setting]) && $data[$setting] !== '') {
             $cron[$setting] = $data[$setting];
         }
     }
     // Check that is this a valid Cron Entry
     try {
         $buildCron = Cron::factory(sprintf('%s %s %s %s %s %s', $cron['minute'], $cron['hour'], $cron['day_of_month'], $cron['month'], $cron['day_of_week'], $cron['year']));
     } catch (\Exception $ex) {
         throw $ex;
     }
     $task = new Models\Task();
     $task->fill(['server' => $server->id, 'active' => 1, 'action' => $data['action'], 'data' => $data['data'], 'queued' => 0, 'year' => $cron['year'], 'day_of_week' => $cron['day_of_week'], 'month' => $cron['month'], 'day_of_month' => $cron['day_of_month'], 'hour' => $cron['hour'], 'minute' => $cron['minute'], 'last_run' => null, 'next_run' => $buildCron->getNextRunDate()]);
     return $task->save();
 }
Beispiel #4
0
 /**
  * Returns an array of each server ID that the user has access to.
  *
  * @return array
  */
 public static function accessServers()
 {
     $access = [];
     $union = self::select('server_id')->where('user_id', self::$user->id);
     $select = Server::select('id')->where('owner', self::$user->id)->union($union)->get();
     foreach ($select as &$select) {
         $access = array_merge($access, [$select->id]);
     }
     return $access;
 }
Beispiel #5
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function handle()
 {
     $tasks = Models\Task::where('queued', 0)->where('active', 1)->where('next_run', '<=', Carbon::now()->toAtomString())->get();
     $this->info(sprintf('Preparing to queue %d tasks.', count($tasks)));
     $bar = $this->output->createProgressBar(count($tasks));
     foreach ($tasks as &$task) {
         $bar->advance();
         $this->dispatch(new SendScheduledTask(Models\Server::findOrFail($task->server), $task));
     }
     $bar->finish();
     $this->info("\nFinished queuing tasks for running.");
 }
 /**
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
     Schema::table('servers', function (Blueprint $table) {
         $table->string('image')->after('daemonSecret');
     });
     // Populate the column
     $servers = Server::select('servers.id', 'service_options.docker_image as s_optionImage')->join('service_options', 'service_options.id', '=', 'servers.option')->get();
     foreach ($servers as $server) {
         $server->image = $server->s_optionImage;
         $server->save();
     }
 }
Beispiel #7
0
 public function postInstall(Request $request)
 {
     $server = Models\Server::where('uuid', $request->input('server'))->first();
     if (!$server) {
         return response()->json(['error' => 'No server by that ID was found on the system.'], 422);
     }
     $node = Models\Node::findOrFail($server->node);
     $hmac = $request->input('signed');
     $status = $request->input('installed');
     if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $node->daemonSecret, true)) {
         return response()->json(['error' => 'Signed HMAC was invalid.'], 403);
     }
     $server->installed = $status === 'installed' ? 1 : 2;
     $server->save();
     return response()->json(['message' => 'Recieved!'], 200);
 }
Beispiel #8
0
 /**
  * Handle an incoming request.
  *
  * @param  \Illuminate\Http\Request  $request
  * @param  \Closure  $next
  * @return mixed
  */
 public function handle($request, Closure $next)
 {
     if (!Auth::user()) {
         return redirect()->guest('auth/login');
     }
     $server = Server::getByUUID($request->route()->server);
     if (!$server) {
         return response()->view('errors.404', [], 404);
     }
     if ($server->suspended === 1) {
         return response()->view('errors.suspended', [], 403);
     }
     if ($server->installed !== 1) {
         return response()->view('errors.installing', [], 403);
     }
     return $next($request);
 }
Beispiel #9
0
 public function delete($id)
 {
     $option = Models\ServiceOptions::findOrFail($id);
     $servers = Models\Server::where('option', $option->id)->get();
     if (count($servers) !== 0) {
         throw new DisplayException('You cannot delete an option that has servers attached to it currently.');
     }
     DB::beginTransaction();
     try {
         Models\ServiceVariables::where('option_id', $option->id)->delete();
         $option->delete();
         DB::commit();
     } catch (\Exception $ex) {
         DB::rollBack();
         throw $ex;
     }
 }
Beispiel #10
0
 public function delete($id)
 {
     $service = Models\Service::findOrFail($id);
     $servers = Models\Server::where('service', $service->id)->get();
     $options = Models\ServiceOptions::select('id')->where('parent_service', $service->id);
     if (count($servers) !== 0) {
         throw new DisplayException('You cannot delete a service that has servers associated with it.');
     }
     DB::beginTransaction();
     try {
         Models\ServiceVariables::whereIn('option_id', $options->get()->toArray())->delete();
         $options->delete();
         $service->delete();
         DB::commit();
     } catch (\Exception $ex) {
         DB::rollBack();
         throw $ex;
     }
 }
Beispiel #11
0
 public function getView(Request $request, $id)
 {
     return view('admin.users.view', ['user' => User::findOrFail($id), 'servers' => Server::select('servers.*', 'nodes.name as nodeName', 'locations.long as location')->join('nodes', 'servers.node', '=', 'nodes.id')->join('locations', 'nodes.location', '=', 'locations.id')->where('owner', $id)->get()]);
 }
Beispiel #12
0
 public function toggleTask(Request $request, $uuid, $id)
 {
     $server = Models\Server::getByUUID($uuid);
     $this->authorize('toggle-task', $server);
     $task = Models\Task::findOrFail($id);
     if (!$task || $server->id !== $task->server) {
         return response()->json(['error' => 'No task by that ID was found associated with this server.'], 404);
     }
     try {
         $repo = new Repositories\TaskRepository();
         $resp = $repo->toggle($id);
         return response()->json(['status' => $resp]);
     } catch (\Exception $ex) {
         Log::error($ex);
         return response()->json(['error' => 'A server error occured while attempting to toggle this task.'], 503);
     }
 }
Beispiel #13
0
 public function getOption(Request $request, $service, $option)
 {
     $opt = Models\ServiceOptions::findOrFail($option);
     return view('admin.services.options.view', ['service' => Models\Service::findOrFail($opt->parent_service), 'option' => $opt, 'variables' => Models\ServiceVariables::where('option_id', $option)->get(), 'servers' => Models\Server::select('servers.*', 'users.email as a_ownerEmail')->join('users', 'users.id', '=', 'servers.owner')->where('option', $option)->paginate(10)]);
 }
Beispiel #14
0
 public function deleteSubuser(Request $request, $uuid, $id)
 {
     $server = Models\Server::getByUUID($uuid);
     $this->authorize('delete-subuser', $server);
     try {
         $subuser = Models\Subuser::select('id')->where(DB::raw('md5(id)'), $id)->where('server_id', $server->id)->first();
         if (!$subuser) {
             throw new DisplayException('No subuser by that ID was found on the system.');
         }
         $repo = new SubuserRepository();
         $repo->delete($subuser->id);
         return response('', 204);
     } catch (DisplayException $ex) {
         response()->json(['error' => $ex->getMessage()], 422);
     } catch (\Exception $ex) {
         Log::error($ex);
         response()->json(['error' => 'An unknown error occured while attempting to delete this subuser.'], 503);
     }
 }
Beispiel #15
0
 public function deleteNode(Request $request, $id)
 {
     $node = Models\Node::findOrFail($id);
     $servers = Models\Server::where('node', $id)->count();
     if ($servers > 0) {
         Alert::danger('You cannot delete a node with servers currently attached to it.')->flash();
         return redirect()->route('admin.nodes.view', ['id' => $id, 'tab' => 'tab_delete']);
     }
     $node->delete();
     Alert::success('Node successfully deleted.')->flash();
     return redirect()->route('admin.nodes');
 }
Beispiel #16
0
 public function postSettingsStartup(Request $request, $uuid)
 {
     $server = Models\Server::getByUUID($uuid);
     $this->authorize('edit-startup', $server);
     try {
         $repo = new ServerRepository();
         $repo->updateStartup($server->id, $request->except(['_token']));
         Alert::success('Server startup variables were successfully updated.')->flash();
     } catch (DisplayException $ex) {
         Alert::danger($ex->getMessage())->flash();
     } catch (\Exception $ex) {
         Log::error($ex);
         Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash();
     }
     return redirect()->route('server.settings', ['uuid' => $uuid, 'tab' => 'tab_startup']);
 }
Beispiel #17
0
 public function __construct($server)
 {
     $this->server = $server instanceof Models\Server ? $server : Models\Server::findOrFail($server);
     $this->node = Models\Node::getByID($this->server->node);
     $this->client = Models\Node::guzzleRequest($this->server->node);
 }
Beispiel #18
0
 public function postResetDatabasePassword(Request $request, $uuid)
 {
     $server = Models\Server::getByUUID($uuid);
     $database = Models\Database::where('id', $request->input('database'))->where('server_id', $server->id)->firstOrFail();
     $this->authorize('reset-db-password', $server);
     try {
         $repo = new Repositories\DatabaseRepository();
         $password = str_random(16);
         $repo->modifyPassword($request->input('database'), $password);
         return response($password);
     } catch (\Pterodactyl\Exceptions\DisplayException $ex) {
         return response()->json(['error' => $ex->getMessage()], 503);
     } catch (\Exception $ex) {
         Log::error($ex);
         return response()->json(['error' => 'An unhandled error occured while attempting to modify this database\'s password.'], 503);
     }
 }
Beispiel #19
0
 public function updateSFTPPassword($id, $password)
 {
     $server = Models\Server::findOrFail($id);
     $node = Models\Node::findOrFail($server->node);
     $validator = Validator::make(['password' => $password], ['password' => 'required|regex:/^((?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,})$/']);
     if ($validator->fails()) {
         throw new DisplayValidationException(json_encode($validator->errors()));
     }
     DB::beginTransaction();
     $server->sftp_password = Crypt::encrypt($password);
     try {
         $server->save();
         $client = Models\Node::guzzleRequest($server->node);
         $client->request('POST', '/server/password', ['headers' => ['X-Access-Token' => $node->daemonSecret, 'X-Access-Server' => $server->uuid], 'json' => ['password' => $password]]);
         DB::commit();
         return true;
     } catch (\GuzzleHttp\Exception\TransferException $ex) {
         DB::rollBack();
         throw new DisplayException('There was an error while attmping to contact the remote service to change the password.', $ex);
     } catch (\Exception $ex) {
         DB::rollBack();
         throw $ex;
     }
 }
Beispiel #20
0
 /**
  * Returns listing of user's servers.
  *
  * @param  \Illuminate\Http\Request $request
  * @return \Illuminate\Contracts\View\View
  */
 public function getIndex(Request $request)
 {
     return view('base.index', ['servers' => Models\Server::getUserServers(10)]);
 }
Beispiel #21
0
 /**
  * Update Server Build Configuration
  *
  * Updates server build information on panel and on node.
  *
  * @Patch("/servers/{id}/build")
  * @Versions({"v1"})
  * @Transaction({
  *      @Request({
  *          "default": "192.168.0.1:25565",
  *          "add_additional": [
  *              "192.168.0.1:25566",
  *              "192.168.0.1:25567",
  *              "192.168.0.1:25568"
  *          ],
  *          "remove_additional": [],
  *          "memory": 1024,
  *          "swap": 0,
  *          "io": 500,
  *          "cpu": 0,
  *          "disk": 1024
  *      }, headers={"Authorization": "Bearer <token>"}),
  *      @Response(200, body={"name": "New Name"}),
  *      @Response(422)
  * })
  * @Parameters({
  *      @Parameter("id", type="integer", required=true, description="The ID of the server to modify.")
  * })
  */
 public function build(Request $request, $id)
 {
     try {
         throw new BadRequestHttpException('There was an error while attempting to add this node to the system.');
         $server = new ServerRepository();
         $server->changeBuild($id, $request->all());
         return Models\Server::findOrFail($id);
     } catch (DisplayValidationException $ex) {
         throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
     } catch (DisplayException $ex) {
         throw new ResourceException($ex->getMessage());
     } catch (\Exception $ex) {
         throw new ServiceUnavailableHttpException('Unable to update server on system due to an error.');
     }
 }
Beispiel #22
0
 public function postUpdateServerToggleBuild(Request $request, $id)
 {
     $server = Models\Server::findOrFail($id);
     $node = Models\Node::findOrFail($server->node);
     $client = Models\Node::guzzleRequest($server->node);
     try {
         $res = $client->request('POST', '/server/rebuild', ['headers' => ['X-Access-Server' => $server->uuid, 'X-Access-Token' => $node->daemonSecret]]);
         Alert::success('A rebuild has been queued successfully. It will run the next time this server is booted.')->flash();
     } catch (\GuzzleHttp\Exception\TransferException $ex) {
         Log::warning($ex);
         Alert::danger('An error occured while attempting to toggle a rebuild.')->flash();
     }
     return redirect()->route('admin.servers.view', ['id' => $id, 'tab' => 'tab_manage']);
 }
Beispiel #23
0
 /**
  * Deletes a user on the panel, returns the number of records deleted.
  *
  * @param  integer $id
  * @return integer
  */
 public function delete($id)
 {
     if (Models\Server::where('owner', $id)->count() > 0) {
         throw new DisplayException('Cannot delete a user with active servers attached to thier account.');
     }
     DB::beginTransaction();
     try {
         Models\Permission::where('user_id', $id)->delete();
         Models\Subuser::where('user_id', $id)->delete();
         Models\User::destroy($id);
         DB::commit();
         return true;
     } catch (\Exception $ex) {
         DB::rollBack();
         throw $ex;
     }
 }
Beispiel #24
0
 /**
  * Updates permissions for a given subuser.
  * @param  integer $id  The ID of the subuser row in MySQL. (Not the user ID)
  * @param  array  $data
  * @throws DisplayValidationException
  * @throws DisplayException
  * @return void
  */
 public function update($id, array $data)
 {
     $validator = Validator::make($data, ['permissions' => 'required|array', 'user' => 'required|exists:users,id', 'server' => 'required|exists:servers,id']);
     if ($validator->fails()) {
         throw new DisplayValidationException(json_encode($validator->all()));
     }
     $subuser = Models\Subuser::findOrFail($id);
     $server = Models\Server::findOrFail($data['server']);
     DB::beginTransaction();
     try {
         Models\Permission::where('user_id', $subuser->user_id)->where('server_id', $subuser->server_id)->delete();
         $daemonPermissions = $this->coreDaemonPermissions;
         foreach ($data['permissions'] as $permission) {
             if (array_key_exists($permission, $this->permissions)) {
                 // Build the daemon permissions array for sending.
                 if (!is_null($this->permissions[$permission])) {
                     array_push($daemonPermissions, $this->permissions[$permission]);
                 }
                 $model = new Models\Permission();
                 $model->fill(['user_id' => $data['user'], 'server_id' => $data['server'], 'permission' => $permission]);
                 $model->save();
             }
         }
         // Contact Daemon
         // We contact even if they don't have any daemon permissions to overwrite
         // if they did have them previously.
         $node = Models\Node::getByID($server->node);
         $client = Models\Node::guzzleRequest($server->node);
         $res = $client->request('PATCH', '/server', ['headers' => ['X-Access-Server' => $server->uuid, 'X-Access-Token' => $node->daemonSecret], 'json' => ['keys' => [$subuser->daemonSecret => $daemonPermissions]]]);
         DB::commit();
         return true;
     } catch (\GuzzleHttp\Exception\TransferException $ex) {
         DB::rollBack();
         throw new DisplayException('There was an error attempting to connect to the daemon to update permissions.', $ex);
     } catch (\Exception $ex) {
         DB::rollBack();
         throw $ex;
     }
     return false;
 }