Example #1
0
 /**
  * Creates a user on the panel. Returns the created user's ID.
  *
  * @param  string       $email
  * @param  string|null  $password An unhashed version of the user's password.
  * @return bool|integer
  */
 public function create($email, $password = null, $admin = false)
 {
     $validator = Validator::make(['email' => $email, 'password' => $password, 'root_admin' => $admin], ['email' => 'required|email|unique:users,email', 'password' => 'nullable|regex:((?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,})', 'root_admin' => 'required|boolean']);
     // Run validator, throw catchable and displayable exception if it fails.
     // Exception includes a JSON result of failed validation rules.
     if ($validator->fails()) {
         throw new DisplayValidationException($validator->errors());
     }
     DB::beginTransaction();
     try {
         $user = new Models\User();
         $uuid = new UuidService();
         $user->uuid = $uuid->generate('users', 'uuid');
         $user->email = $email;
         $user->password = Hash::make(is_null($password) ? str_random(30) : $password);
         $user->language = 'en';
         $user->root_admin = $admin ? 1 : 0;
         $user->save();
         // Setup a Password Reset to use when they set a password.
         $token = str_random(32);
         DB::table('password_resets')->insert(['email' => $user->email, 'token' => $token, 'created_at' => Carbon::now()->toDateTimeString()]);
         $user->notify(new AccountCreated($token));
         DB::commit();
         return $user->id;
     } catch (\Exception $ex) {
         DB::rollBack();
         throw $ex;
     }
 }
Example #2
0
 /**
  * Creates a new subuser on the server.
  * @param  integer $id     The ID of the server to add this subuser to.
  * @param  array  $data
  * @throws DisplayValidationException
  * @throws DisplayException
  * @return integer          Returns the ID of the newly created subuser.
  */
 public function create($sid, array $data)
 {
     $server = Models\Server::findOrFail($sid);
     $validator = Validator::make($data, ['permissions' => 'required|array', 'email' => 'required|email']);
     if ($validator->fails()) {
         throw new DisplayValidationException(json_encode($validator->errors()));
     }
     DB::beginTransaction();
     try {
         // Determine if this user exists or if we need to make them an account.
         $user = Models\User::where('email', $data['email'])->first();
         if (!$user) {
             $password = str_random(16);
             try {
                 $repo = new UserRepository();
                 $uid = $repo->create($data['email'], $password);
                 $user = Models\User::findOrFail($uid);
             } catch (\Exception $ex) {
                 throw $ex;
             }
         }
         $uuid = new UuidService();
         $subuser = new Models\Subuser();
         $subuser->fill(['user_id' => $user->id, 'server_id' => $server->id, 'daemonSecret' => (string) $uuid->generate('servers', 'uuid')]);
         $subuser->save();
         $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' => $user->id, 'server_id' => $server->id, '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]]]);
         $email = $data['email'];
         Mail::queue('emails.added-subuser', ['serverName' => $server->name, 'url' => route('server.index', $server->uuidShort)], function ($message) use($email) {
             $message->to($email);
             $message->from(Settings::get('email_from', env('MAIL_FROM')), Settings::get('email_sender_name', env('MAIL_FROM_NAME', 'Pterodactyl Panel')));
             $message->subject(Settings::get('company') . ' - Added to Server');
         });
         DB::commit();
         return $subuser->id;
     } catch (\GuzzleHttp\Exception\TransferException $ex) {
         DB::rollBack();
         throw new DisplayException('There was an error attempting to connect to the daemon to add this user.', $ex);
     } catch (\Exception $ex) {
         DB::rollBack();
         throw $ex;
     }
     return false;
 }
Example #3
0
 public function update($id, array $data)
 {
     $node = Models\Node::findOrFail($id);
     // Validate Fields
     $validator = $validator = Validator::make($data, ['name' => 'regex:/^([\\w .-]{1,100})$/', 'location' => 'numeric|min:1|exists:locations,id', 'public' => 'numeric|between:0,1', 'fqdn' => 'string|unique:nodes,fqdn,' . $id, 'scheme' => 'regex:/^(http(s)?)$/', 'memory' => 'numeric|min:1', 'memory_overallocate' => 'numeric|min:-1', 'disk' => 'numeric|min:1', 'disk_overallocate' => 'numeric|min:-1', 'daemonBase' => 'regex:/^([\\/][\\d\\w.\\-\\/]+)$/', 'daemonSFTP' => 'numeric|between:1,65535', 'daemonListen' => 'numeric|between:1,65535', 'reset_secret' => 'sometimes|accepted']);
     // Run validator, throw catchable and displayable exception if it fails.
     // Exception includes a JSON result of failed validation rules.
     if ($validator->fails()) {
         throw new DisplayValidationException($validator->errors());
     }
     // Verify the FQDN
     if (isset($data['fqdn'])) {
         // Verify the FQDN if using SSL
         if (isset($data['scheme']) && $data['scheme'] === 'https' || !isset($data['scheme']) && $node->scheme === 'https') {
             if (filter_var($data['fqdn'], FILTER_VALIDATE_IP)) {
                 throw new DisplayException('A fully qualified domain name is required to use secure comunication on this node.');
             }
         }
         // Verify FQDN is resolvable, or if not using SSL that the IP is valid.
         if (!filter_var(gethostbyname($data['fqdn']), FILTER_VALIDATE_IP)) {
             throw new DisplayException('The FQDN (or IP Address) provided does not resolve to a valid IP address.');
         }
     }
     // Should we be nulling the overallocations?
     if (isset($data['memory_overallocate'])) {
         $data['memory_overallocate'] = $data['memory_overallocate'] < 0 ? null : $data['memory_overallocate'];
     }
     if (isset($data['disk_overallocate'])) {
         $data['disk_overallocate'] = $data['disk_overallocate'] < 0 ? null : $data['disk_overallocate'];
     }
     // Set the Secret
     if (isset($data['reset_secret'])) {
         $uuid = new UuidService();
         $data['daemonSecret'] = (string) $uuid->generate('nodes', 'daemonSecret');
         unset($data['reset_secret']);
     }
     // Store the Data
     return $node->update($data);
 }
Example #4
0
 /**
  * [updateDetails description]
  * @param  integer  $id
  * @param  array    $data
  * @return boolean
  */
 public function updateDetails($id, array $data)
 {
     $uuid = new UuidService();
     $resetDaemonKey = false;
     // Validate Fields
     $validator = Validator::make($data, ['owner' => 'email|exists:users,email', 'name' => 'regex:([\\w -]{4,35})']);
     // Run validator, throw catchable and displayable exception if it fails.
     // Exception includes a JSON result of failed validation rules.
     if ($validator->fails()) {
         throw new DisplayValidationException($validator->errors());
     }
     DB::beginTransaction();
     try {
         $server = Models\Server::findOrFail($id);
         $owner = Models\User::findOrFail($server->owner);
         // Update daemon secret if it was passed.
         if (isset($data['reset_token']) && $data['reset_token'] === true || isset($data['owner']) && $data['owner'] !== $owner->email) {
             $oldDaemonKey = $server->daemonSecret;
             $server->daemonSecret = $uuid->generate('servers', 'daemonSecret');
             $resetDaemonKey = true;
         }
         // Update Server Owner if it was passed.
         if (isset($data['owner']) && $data['owner'] !== $owner->email) {
             $newOwner = Models\User::select('id')->where('email', $data['owner'])->first();
             $server->owner = $newOwner->id;
         }
         // Update Server Name if it was passed.
         if (isset($data['name'])) {
             $server->name = $data['name'];
         }
         // Save our changes
         $server->save();
         // Do we need to update? If not, return successful.
         if (!$resetDaemonKey) {
             DB::commit();
             return true;
         }
         // If we need to update do it here.
         $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], 'exceptions' => false, 'json' => ['keys' => [(string) $oldDaemonKey => [], (string) $server->daemonSecret => $this->daemonPermissions]]]);
         if ($res->getStatusCode() === 204) {
             DB::commit();
             return true;
         } else {
             throw new DisplayException('Daemon returned a a non HTTP/204 error code. HTTP/' + $res->getStatusCode());
         }
     } catch (\Exception $ex) {
         DB::rollBack();
         Log::error($ex);
         throw new DisplayException('An error occured while attempting to update this server\'s information.');
     }
 }