/** * 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; } }
public function addAllocations($id, array $allocations) { $node = Models\Node::findOrFail($id); DB::beginTransaction(); try { foreach ($allocations as $rawIP => $ports) { $parsedIP = Network::parse($rawIP); foreach ($parsedIP as $ip) { foreach ($ports as $port) { if (!is_int($port) && !preg_match('/^(\\d{1,5})-(\\d{1,5})$/', $port)) { throw new DisplayException('The mapping for ' . $port . ' is invalid and cannot be processed.'); } if (preg_match('/^(\\d{1,5})-(\\d{1,5})$/', $port, $matches)) { foreach (range($matches[1], $matches[2]) as $assignPort) { $alloc = Models\Allocation::firstOrNew(['node' => $node->id, 'ip' => $ip, 'port' => $assignPort]); if (!$alloc->exists) { $alloc->fill(['node' => $node->id, 'ip' => $ip, 'port' => $assignPort, 'assigned_to' => null]); $alloc->save(); } } } else { $alloc = Models\Allocation::firstOrNew(['node' => $node->id, 'ip' => $ip, 'port' => $port]); if (!$alloc->exists) { $alloc->fill(['node' => $node->id, 'ip' => $ip, 'port' => $port, 'assigned_to' => null]); $alloc->save(); } } } } } DB::commit(); return true; } catch (\Exception $ex) { DB::rollBack(); throw $ex; } }
/** * @dataProvider getTestCountData */ public function testCount($data, $expected) { $this->assertEquals($expected, count(Network::parse($data))); }
/** * @expectedException Exception * @expectedExceptionMessage Exclude subnet not within target network */ public function testExcludeException() { Network::parse('192.0.2.0/28')->exclude('192.0.3.0/24'); }