From e0ec61b95c8e3900a14370040ac26d7c1479e9c3 Mon Sep 17 00:00:00 2001 From: Mark Tearle <mtearle@ucc.asn.au> Date: Sun, 7 Feb 2021 13:55:44 +0800 Subject: [PATCH] Implement register API call --- .htaccess | 4 +++ quovadis/quovadis.php | 82 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 .htaccess diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..60350af --- /dev/null +++ b/.htaccess @@ -0,0 +1,4 @@ +RewriteEngine on +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^.*$ /quovadis/index.php [L,QSA] diff --git a/quovadis/quovadis.php b/quovadis/quovadis.php index 665a208..39141ac 100644 --- a/quovadis/quovadis.php +++ b/quovadis/quovadis.php @@ -8,6 +8,7 @@ require_once('config.php'); use Ramsey\Uuid\Uuid; use RestService\RestService; use GuzzleHttp\Client; +use Leaf\Http\Response; function check_username($username) { // returns true if we get some info about the username @@ -29,13 +30,20 @@ function get_desec_txt($config, $name) { $restService = new RestService(); $path = "/api/v1/domains/" . $config['QV_DOMAIN'] . "/rrsets/" . $name . "/TXT/"; $auth_string = "Token ". $config['QV_DESEC_API']; - - $response = $restService - ->setEndpoint('https://desec.io') - ->setRequestHeaders([ - 'Authorization' => $auth_string - ]) - ->get($path, [], [], false); + + try { + $response = $restService + ->setEndpoint('https://desec.io') + ->setRequestHeaders([ + 'Authorization' => $auth_string + ]) + ->get($path, [], [], false); + } catch (Exception $e) { + if( $e->getMessage() == "Not Found" ) { + return ""; + } + throw new Exception($e->getMessage(), $e->getCode()); + } $result = json_decode($response->getBody(), true); if (array_key_exists('records', $result)) { @@ -45,9 +53,14 @@ function get_desec_txt($config, $name) { } } -function check_api_key($api_key) { +function encrypt_api_key($api_key) { + return bin2hex(password_hash($api_key, PASSWORD_DEFAULT)); +} + +function check_api_key($config, $username, $api_key) { // API keys need to be alpha numeric - return 1; + $hash = hex2bin(get_desec_txt($config, $username)); + return password_verify($api_key, $hash); } function check_challenge($challenge) { @@ -71,7 +84,6 @@ function check_challenge($challenge) { // function update_desec_txt($config, $name, $txt) { - $path = "/api/v1/domains/" . $config['QV_DOMAIN'] . "/rrsets/" . $name . "/TXT/"; $auth_string = "Token ". $config['QV_DESEC_API']; $headers = [ 'Authorization' => $auth_string, @@ -79,7 +91,13 @@ function update_desec_txt($config, $name, $txt) { ]; - + if (get_desec_txt($config, $name) == "") { + $method = 'POST'; + $path = "/api/v1/domains/" . $config['QV_DOMAIN'] . "/rrsets/"; + } else { + $method = 'PUT'; + $path = "/api/v1/domains/" . $config['QV_DOMAIN'] . "/rrsets/" . $name . "/TXT/"; + } $val = [ 'subname' => $name, @@ -98,7 +116,7 @@ function update_desec_txt($config, $name, $txt) { ]); try { - $response = $client->request('PUT', $path, [ 'headers'=>$headers, 'body'=>$body ]); + $response = $client->request($method, $path, [ 'headers'=>$headers, 'body'=>$body ]); } catch (ClientException $e) { throw new Exception($e->getResponse()->getReasonPhrase(), $e->getResponse()->getStatusCode()); } catch (BadResponseException $e) { @@ -115,16 +133,37 @@ function update_desec_txt($config, $name, $txt) { } } +// Send email to user with API key + +function email_api_key($username, $api_key) { + $headers = array( + 'From' => 'quovadis@ucc.asn.au', + 'Reply-To' => 'wheel@ucc.asn.au', + 'X-Mailer' => 'PHP/' . phpversion() + ); + + // The message + $message = "Quovadis\r\n\r\nUCC DNS Helper\r\nYour API key is: $api_key"; + + // In case any of our lines are larger than 70 characters, we should use wordwrap() + $message = wordwrap($message, 70, "\r\n"); + + // Send + mail($username . '@ucc.asn.au', 'Quoavadis API Key', $message, $headers); +} + // Instantiate Leaf -$leaf = new Leaf\App; +$leaf = new Leaf\App(); +#$response = new Leaf\Http\Response(); // Add routes $leaf->get('/', function () use($leaf) { $config=get_config(); $s = update_desec_txt($config, "mtearle-test", "test flight"); $r = get_desec_txt($config, "mtearle-test"); + $r2 = get_desec_txt($config, "mtearle"); // since the response object is directly tied to the leaf instance - $html = '<h5>My first Leaf app</h5>' . $r . " --- ". $s; + $html = '<h5>My first Leaf app</h5>' . $r . " --- ". $s . "----" . $r2; $leaf->response()->markup($html); }); @@ -138,11 +177,20 @@ $leaf->post('/register', function () use($leaf) { // * UCC username // // Will email to your UCC email address an API key to use with the service + $config=get_config(); + $username = $leaf->request->get('username'); // Check username is valid if ( !check_username($username) ) { - $leaf->response->respond(["message" => $username." not valid"]); + $leaf->response->json(["message" => $username." not valid"],200); + return; + } + + // Check there is no existing API key registered for the user + $a = get_desec_txt($config, $username); + if ( $a <> "" ) { + $leaf->response->json(["message" => $username." already registered"],200); return; } @@ -150,10 +198,12 @@ $leaf->post('/register', function () use($leaf) { $api_key = Uuid::uuid4()->toString(); // Stick API key encrypted into the DNS + $u = update_desec_txt($config, $username, encrypt_api_key($api_key)); // Email API key + email_api_key($username, $api_key); - $leaf->response->respond(["message" => $username." has been added and email sent"]); + $leaf->response->json(["message" => $username." has been added and email sent"],200); }); $leaf->post('/update-api-key', function () use($leaf) { -- GitLab