External Web Server can't communicate with EC2 flask API - amazon-web-services

I'm really out of my element here when it comes to networking.
I have an EC2 server running linux, which has an active flask API running.
I have a PHP function on a shared hostgator server:
function sendAPI($threadid, $teamid) {
$url = "http://ec2-...amazonaws.com:9999/api2?id1=" . $teamid . "&thread=" . $threadid;
$ch = curl_init();
$optArray = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true
);
curl_setopt_array($ch, $optArray);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
Similar function works without issue with the telegram API server:
function sendMessage($chatID, $messaggio, $token) {
$url = "https://api.telegram.org/bot" . $token . "/sendMessage?chat_id=" . $chatID;
$url = $url . "&text=" . urlencode($messaggio);
$ch = curl_init();
$optArray = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true
);
curl_setopt_array($ch, $optArray);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
When navigating to http://ec2-...amazonaws.com:9999/api2?id1=1&thread=1 from my own web browser, the API picks up the request successfully.
Inbound rules on EC2 instance:
Note, website IP, also the same IP is listed in CPanel:
Domain Name: novociv.org Top Level Domain: ORG (Organization) DNS
Lookup IP Address: 108.167.142.88
From my limited knowledge of networking, this should all work correctly. However, when the PHP function is called it returns a null result and the EC2 server does not react. I don't know how to troubleshoot from here because I don't know where to find any error messages. I would guess that the EC2 is simply blocking traffic from the external server, but I don't know what's wrong (if anything) with my inbound rules since the EC2 successfully picks up requests from my laptop.

It turns out that hostgator does not have port 9999 open by default. The problem can be solved by either requesting hostgator open port 9999 on this server, or else by moving the flask application to a different port which is already open.

Related

Service account API error when getting the access token

I am testing google people API for our web application.
Steps:
I created new project in the google console (https://console.cloud.google.com/)
I enabled People API
I created needed Credentials - web client for my application and API key
I created service account with p12 key for server to server queries and enabled "Google Workspace Domain-wide Delegation"
I configured OAuth consent screen with scopes needed to authorize to google and get access to people API: /auth/userinfo.email /auth/userinfo.profile /auth/contacts /auth/contacts.readonly
Then my PHP script using "Google API PHP client" make redirect link to consent screen and return code for access token with Web client:
<?php
$client = new Google_Client();
$client->setAccessType('online'); // default: offline
$client->setApplicationName('My Project xxxxx');
$client->setClientId('999999999999-qwertysdfhwe9uriiiiiiiiiiiiiiiii.apps.googleusercontent.com');
$client->setClientSecret('GOCSPX-hhhhhhhhhhhhhhhhhhhhhhhhhhhh');
$client->setDeveloperKey('AIzafffffffffffffffffffffffffffffffffff'); // API key
$client->setState('subdomain.myapp.com');
$scriptUri = 'https://oauth.myapp.com/auth.php';
$client->setRedirectUri($scriptUri);
$client->addScope('https://www.googleapis.com/auth/userinfo.email');
$client->addScope('https://www.googleapis.com/auth/userinfo.profile');
$client->addScope('https://www.googleapis.com/auth/contacts');
$auth_url = $client->createAuthUrl();
header('Location: '.$auth_url);
?>
This code redirects to google Authentication screen, then I login with google and approve scopes. Google redirects me back to my app and now I have access token and aproved scopes and email of authenticated user.
The next step I have huge trouble - server - to - server query to get access token for people API
function base64_url_encode($input) {
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}
$iat = time();
$url = "https://www.googleapis.com/oauth2/v4/token";
$scope = 'https://www.googleapis.com/auth/contacts';
$jwt_data = array(
'iss' => '111111111111111111111', // My service account ID
'aud' => $url,
'scope' => $scope,
'exp' => $iat + 3600,
'iat' => $iat,
'sub' => 'user#gmail.com', // Email of the user that was autenticated in first step
);
openssl_pkcs12_read(file_get_contents('keyfile.p12'), $certs, 'notasecret');
$header = array('typ' => 'JWT', 'alg' => 'RS256');
$signing_input = base64_url_encode(json_encode($header)) . '.' . base64_url_encode(json_encode($jwt_data));
openssl_sign($signing_input, $signature, $certs['pkey'], 'SHA256');
$jwt = $signing_input . '.' . base64_url_encode($signature);
$data = array(
"grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion" => $jwt
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);
$google_contacts_api_tokens_collection[$use_mailbox] = $response;
return $response;
And this code google returns the error that I can not fix, and I have no any ideas.
The text of error:
"Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
Your code is trying to impersonate a user via a service account. This requires enabling Domain Wide Delegation. In a round-about way, the error message means the service account does not have permission because delegation is not enabled.
Perform Google Workspace Domain-Wide Delegation of Authority
If the user is not part of Google Workspace, then you cannot impersonate the user.
Yes, but I already tried this and it does not help. I configured scopes for service account in the Google Workspace, and also checked the "Enable Google Workspace Domain-wide Delegation" checkbox in google console. In Google Workspace I used digital Client ID of my service account.
And also I discovered one strange moment:
Web client always returns good access token, but when I request service account access token it works well only for google console project owner ('sub' => 'project.owner#gmail.com'). And if I request service account access token for another user ('sub' => 'project.testuser#gmail.com') Google also returns the same error: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.

Chrome web app using firebase returns mismatchsenderid error

I apologise as this question has been asked many times, but none of the responses have been helpful in resolving my issue.
I am using firebase with my web app and attempting to send notifications via php or terminal curl command. Have tried both with same error:
{"multicast_id":4984414565388562908,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}
I am getting the API key and sender id straight from firebase from the same place. Copying and pasting, no typos. Checked about 50 times... 100% sure the sender id matches the API key as i am copying and pasting from the same screen.
I am getting the endpoint from the Chrome console:
Again, copied and pasted with no typos.
My PHP file:
<?php
// API access key from Google API's Console
define( 'API_ACCESS_KEY', '**API_KEY**' );
$registrationIds = array('**SUBSCRIPTION_ID**');
// prep the bundle
$msg = array
(
'message' => $_GET["message"],
'title' => $_GET["title"],
'subtitle' => $_GET["subtitle"],
'tickerText' => $_GET["ticker"],
'vibrate' => 1,
'sound' => 1,
'largeIcon' => 'http://a4.mzstatic.com/au/r30/Purple4/v4/d2/8b/e4/d28be43c-9a6a-4b91-1981-a108ba5cec84/icon175x175.png',
'smallIcon' => 'http://www.uidownload.com/files/303/56/11/small-arrow-left-fast-rewind-icon.png',
'click_action' => 'https://aiatsis.gov.au'
);
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result;
?>
My Manifest file:
{
"name": "Webpush",
"gcm_sender_id": "**SENDER_ID**"
}
The curl terminal command i am using is:
curl --header "Authorization: key=**API_KEY**" --header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d "{\"registration_ids\":[\"**SUBSCRIPTION_ID**\"]}"
I have no idea why this is not working. I have tried:
Checking the Key matches the sender id about 150 times.
Deleting my firebase project and starting again with new API key and Sender ID (yes i generated a new endpoint subscription id after i did this).
As mentioned, tried both php and terminal push requests.
I have run out of options. And as mentioned several times already the API key matches the corresponding sender ID. I am 100% sure of this. As far as my understanding of the "MismatchSenderId" error, they are trying to tell me that the API key and sender ID do not match. They do match.
The sender ID matches the API key
The Subscription ID was generated using the correct sender ID
Does anyone have any idea why this is happening?
In the manifest file, que gmc_sender_id is the same for everyone.
Change that to: "gcm_sender_id": "103953800507".

Unable to send emails using mailgun

I have followed the instructions of the mailgun, including dots and commas. I installed composer successfully. My domain name is also verified so I wanted to use API for sending emails.
I created a simple application for testing if emails are going or not.
here is the code of sample php application:
<?php
require 'vendor/autoload.php';
use Mailgun\Mailgun;
$mg = new Mailgun("key-********************************");
$domain = "https://api.mailgun.net/v3/mailgun.************.com/messages";
$mg->sendMessage($domain,
array(
'from' => 'noreply#********.com',
'to' => '********#hotmail.com',
'subject' => 'The mailgun is awesome!',
'text' => 'It is so simple to send a message.'));
echo "done";
?>
I get internal server error 500 when I run this file.
When I change the $domain to "mailgun.*****.com" I get emails but in junk folder
I am confused what is happening here.. no apparent fault..
May be some expert will be able to help me out here..
The $domain has to be the same as entered in your settings.
i.e. the domain is mg.domain.com in your mailgun account,
your $domain is domain.com.
Also your from has to be [anything]#domain.com, to be accepted.

Protecting Amazon S3 Files for User-Specific display

My server would communicate with S3. There are two possibilities as far as I understand:
1) Load the file to my server and send it to the user, keeping S3 access only to my server's IP
2) Redirect to S3 while handling authentication on my server
I've understood(I think) how to do #1 from:
Does Amazon S3 support HTTP request with basic authentication
But is there any way to accomplish #2? I want to avoid the latency of first loading the file to my server and then sending it to the user.
I'm not sure how to keep the S3 url protected from public access in #2. Someone might go through my authentication, get a download link, but that link will be publicly accessible.
I'm new to S3 in general, so bear with me if I've misunderstood anything.
Edit: I've looked into signed links with expiration times, but they can still be accessed by others. I would also prefer to use my own authentication so I can allow access to a link only while a user is signed in.
You should try below code, which your server produce an URL which will expire in say 60 seconds, for users to directly download the file from S3 server.
First: Download HMAX.php from here:
http://pear.php.net/package/Crypt_HMAC/redirected
<?php
require_once('Crypt/HMAC.php');
echo getS3Redirect("/test.jpg") . "\n";
function getS3Redirect($objectName)
{
$S3_URL = "http://s3.amazonaws.com";
$keyId = "your key";
$secretKey = "your secret";
$expires = time() + 60;
$bucketName = "/your bucket";
$stringToSign = "GET\n\n\n$expires\n$bucketName$objectName";
$hasher =& new Crypt_HMAC($secretKey, "sha1");
$sig = urlencode(hex2b64($hasher->hash($stringToSign)));
return "$S3_URL$bucketName$objectName?AWSAccessKeyId=$keyId&Expires=$expires&Signature=$sig";
}
function hex2b64($str)
{
$raw = ";
for ($i=0; $i < strlen($str); $i+=2)
{
$raw .= chr(hexdec(substr($str, $i, 2)));
}
return base64_encode($raw);
}
?>
Take a try.

Box API newbie connection problems

I'm trying to connect to the box-api to read the files of my user in my folder. I've created the folder and uploaded the files, then i went to the OAuth2 interface to obtain an API Key. It has given the api key to me so i pasted it in the code:
public function indexAction()
{
try {
$uri = "https://api.box.com/2.0/folders/0/items?limit=100&offset=0";
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Curl',
'curloptions' => array(CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPHEADER=>array("Authorization: Bearer MYKEY"),
CURLOPT_SSL_VERIFYPEER, false,
CURLOPT_USERPWD, "user:password"),
);
$client = new Zend_Http_Client($uri, $config);
$response = $client->request();
$text= $response->getBody();
} catch (Zend_Exception $e) {
echo "Message: " . $e->getMessage() . "\n";
// Other code to recover from the error
}
}
Following this tutorial on youtube.
The error i'm getting is the following:
Message: Error in cURL request: unable to use client certificate (no key found or wrong pass phrase?)
I registered the application with the name "test". What have I done wrong? What am I missing?
You might try passing the request without the CURLOPT_SSL_VERIFYPEER and CURLOPT_USERPWD options. I don't think those are strictly necessary -- to my knowledge Box doesn't do any client certificate validation -- and they may be causing the problem.
The use of Zend http client by itself is better than using the curl adapter.Besides the username and password are not required to authenticate. You can perform the operation only after you have received th access token from the authorization procedure of Oauth2 of Box-API. The zend http client call that can be used is the following:
$client = new Zend_Http_Client('https://api.box.com/2.0/folders/0');
$client->setMethod(Zend_Http_Client::GET);
$client->setHeaders('Authorization: Bearer '.$access_token);
$response = $client->request()->getBody();
My 2 cents.