/** * Create a New API Keypair on the system. * * @param array $data An array with a permissions and allowed_ips key. * * @throws Pterodactyl\Exceptions\DisplayException if there was an error that can be safely displayed to end-users. * @throws Pterodactyl\Exceptions\DisplayValidationException if there was a validation error. * * @return string Returns the generated secret token. */ public function new(array $data) { $validator = Validator::make($data, ['permissions' => 'required|array']); $validator->after(function ($validator) use($data) { if (array_key_exists('allowed_ips', $data) && !empty($data['allowed_ips'])) { foreach (explode("\n", $data['allowed_ips']) as $ip) { $ip = trim($ip); try { Network::parse($ip); array_push($this->allowed, $ip); } catch (\Exception $ex) { $validator->errors()->add('allowed_ips', 'Could not parse IP <' . $ip . '> because it is in an invalid format.'); } } } }); // 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 { $secretKey = str_random(16) . '.' . str_random(15); $key = new Models\APIKey(); $key->fill(['public' => str_random(16), 'secret' => Crypt::encrypt($secretKey), 'allowed_ips' => empty($this->allowed) ? null : json_encode($this->allowed)]); $key->save(); foreach ($data['permissions'] as $permission) { if (in_array($permission, $this->permissions)) { $model = new Models\APIPermission(); $model->fill(['key_id' => $key->id, 'permission' => $permission]); $model->save(); } } DB::commit(); return $secretKey; } catch (\Exception $ex) { throw $ex; } }