diff --git a/app/Server/SubdomainRepository/DatabaseSubdomainRepository.php b/app/Server/SubdomainRepository/DatabaseSubdomainRepository.php index d540eeb..eaf3d00 100644 --- a/app/Server/SubdomainRepository/DatabaseSubdomainRepository.php +++ b/app/Server/SubdomainRepository/DatabaseSubdomainRepository.php @@ -135,7 +135,7 @@ class DatabaseSubdomainRepository implements SubdomainRepository { $deferred = new Deferred(); - $this->database->query('DELETE FROM subdomains WHERE id = :id AND user_id = :user_id', [ + $this->database->query('DELETE FROM subdomains WHERE (id = :id OR subdomain = :id) AND user_id = :user_id', [ 'id' => $subdomainId, 'user_id' => $userId, ]) diff --git a/app/Server/UserRepository/DatabaseUserRepository.php b/app/Server/UserRepository/DatabaseUserRepository.php index 62ce315..02bf64a 100644 --- a/app/Server/UserRepository/DatabaseUserRepository.php +++ b/app/Server/UserRepository/DatabaseUserRepository.php @@ -53,7 +53,7 @@ class DatabaseUserRepository implements UserRepository ]; if ($searchQuery !== '') { - $query .= "WHERE name LIKE '%".$searchQuery."%' "; + $query .= "WHERE name LIKE '%" . $searchQuery . "%' "; $bindings['search'] = $searchQuery; } @@ -104,7 +104,7 @@ class DatabaseUserRepository implements UserRepository ->then(function (Result $result) use ($deferred) { $user = $result->rows[0] ?? null; - if (! is_null($user)) { + if (!is_null($user)) { $user = $this->getUserDetails($user); } @@ -136,7 +136,7 @@ class DatabaseUserRepository implements UserRepository ->then(function (Result $result) use ($deferred) { $user = $result->rows[0] ?? null; - if (! is_null($user)) { + if (!is_null($user)) { $user = $this->getUserDetails($user); } @@ -150,15 +150,38 @@ class DatabaseUserRepository implements UserRepository { $deferred = new Deferred(); - $this->database->query(" + $this->getUserByToken($data['auth_token']) + ->then(function ($existingUser) use ($data, $deferred) { + if (is_null($existingUser)) { + $this->database->query(" INSERT INTO users (name, auth_token, can_specify_subdomains, can_specify_domains, can_share_tcp_ports, max_connections, created_at) VALUES (:name, :auth_token, :can_specify_subdomains, :can_specify_domains, :can_share_tcp_ports, :max_connections, DATETIME('now')) ", $data) - ->then(function (Result $result) use ($deferred) { - $this->database->query('SELECT * FROM users WHERE id = :id', ['id' => $result->insertId]) - ->then(function (Result $result) use ($deferred) { - $deferred->resolve($result->rows[0]); - }); + ->then(function (Result $result) use ($deferred) { + $this->database->query('SELECT * FROM users WHERE id = :id', ['id' => $result->insertId]) + ->then(function (Result $result) use ($deferred) { + $deferred->resolve($result->rows[0]); + }); + }); + } else { + $this->database->query(" + UPDATE users + SET + name = :name, + can_specify_subdomains = :can_specify_subdomains, + can_specify_domains = :can_specify_domains, + can_share_tcp_ports = :can_share_tcp_ports, + max_connections = :max_connections + WHERE + auth_token = :auth_token + ", $data) + ->then(function (Result $result) use ($existingUser, $deferred) { + $this->database->query('SELECT * FROM users WHERE id = :id', ['id' => $existingUser['id']]) + ->then(function (Result $result) use ($deferred) { + $deferred->resolve($result->rows[0]); + }); + }); + } }); return $deferred->promise(); @@ -181,10 +204,10 @@ class DatabaseUserRepository implements UserRepository $deferred = new Deferred(); $authTokenString = collect($authTokens)->map(function ($token) { - return '"'.$token.'"'; + return '"' . $token . '"'; })->join(','); - $this->database->query('SELECT * FROM users WHERE auth_token IN ('.$authTokenString.')') + $this->database->query('SELECT * FROM users WHERE auth_token IN (' . $authTokenString . ')') ->then(function (Result $result) use ($deferred) { $users = collect($result->rows)->map(function ($user) { return $this->getUserDetails($user); diff --git a/tests/Feature/Server/ApiTest.php b/tests/Feature/Server/ApiTest.php index 879963e..8422026 100644 --- a/tests/Feature/Server/ApiTest.php +++ b/tests/Feature/Server/ApiTest.php @@ -65,6 +65,97 @@ class ApiTest extends TestCase $this->assertSame([], $users[0]->sites); } + /** @test */ + public function it_can_specify_a_token_when_creating_a_user() + { + /** @var Response $response */ + $this->await($this->browser->post('http://127.0.0.1:8080/api/users', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ], json_encode([ + 'name' => 'Marcel', + 'token' => 'my-token' + ]))); + + /** @var Response $response */ + $response = $this->await($this->browser->get('http://127.0.0.1:8080/api/users', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ])); + + $body = json_decode($response->getBody()->getContents()); + $users = $body->paginated->users; + + $this->assertCount(1, $users); + $this->assertSame('Marcel', $users[0]->name); + $this->assertSame('my-token', $users[0]->auth_token); + $this->assertSame([], $users[0]->sites); + } + + /** @test */ + public function it_updates_users_instead_of_creating_new_ones() + { + /** @var Response $response */ + $this->await($this->browser->post('http://127.0.0.1:8080/api/users', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ], json_encode([ + 'name' => 'Marcel', + 'token' => 'my-token' + ]))); + + /** @var Response $response */ + $response = $this->await($this->browser->get('http://127.0.0.1:8080/api/users', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ])); + + $body = json_decode($response->getBody()->getContents()); + $users = $body->paginated->users; + + $this->assertCount(1, $users); + $this->assertSame('Marcel', $users[0]->name); + $this->assertSame('my-token', $users[0]->auth_token); + $this->assertSame(0, $users[0]->can_specify_subdomains); + $this->assertSame(0, $users[0]->can_specify_domains); + $this->assertSame(0, $users[0]->can_share_tcp_ports); + $this->assertSame([], $users[0]->sites); + + $this->await($this->browser->post('http://127.0.0.1:8080/api/users', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ], json_encode([ + 'name' => 'Marcel Changed', + 'token' => 'my-token', + 'can_specify_subdomains' => 1, + 'can_specify_domains' => 1, + 'can_share_tcp_ports' => 1, + ]))); + + /** @var Response $response */ + $response = $this->await($this->browser->get('http://127.0.0.1:8080/api/users', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ])); + + $body = json_decode($response->getBody()->getContents()); + $users = $body->paginated->users; + + $this->assertCount(1, $users); + $this->assertSame('Marcel Changed', $users[0]->name); + $this->assertSame('my-token', $users[0]->auth_token); + $this->assertSame(1, $users[0]->can_specify_subdomains); + $this->assertSame(1, $users[0]->can_specify_domains); + $this->assertSame(1, $users[0]->can_share_tcp_ports); + $this->assertSame([], $users[0]->sites); + } + /** @test */ public function it_can_specify_tokens_when_creating_a_user() { @@ -288,6 +379,51 @@ class ApiTest extends TestCase $this->assertCount(0, $subdomains); } + /** @test */ + public function it_can_delete_subdomains_by_name() + { + /** @var Response $response */ + $response = $this->await($this->browser->post('http://127.0.0.1:8080/api/users', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ], json_encode([ + 'name' => 'Marcel', + 'can_specify_subdomains' => 1, + ]))); + + $user = json_decode($response->getBody()->getContents())->user; + + $response = $this->await($this->browser->post('http://127.0.0.1:8080/api/subdomains', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ], json_encode([ + 'subdomain' => 'reserved', + 'auth_token' => $user->auth_token, + ]))); + + $this->await($this->browser->delete('http://127.0.0.1:8080/api/subdomains/reserved', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ], json_encode([ + 'auth_token' => $user->auth_token, + ]))); + + /** @var Response $response */ + $response = $this->await($this->browser->get('http://127.0.0.1:8080/api/users/1', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ])); + + $body = json_decode($response->getBody()->getContents()); + $subdomains = $body->subdomains; + + $this->assertCount(0, $subdomains); + } + /** @test */ public function it_can_not_reserve_an_already_reserved_subdomain() {