How Gmail makes it? - python

I am developing service similar to banatag. During new feature developmnet I found unexplainable behaviour of Gmail(as I think).
I'll try to explain my question in picture:
Create tag(image that I will request). Now nobody requests it
Add it by URL to email. Url of image http://eggplant-tag.appspot.com/request?FT1R3WECWNTM2ZGUDXRMA8VOXJ4F6TI4
There are two new AJAX requests from page, but there aren't to my domain
Looking for my service. There is request from my IP, with Google User-Agent
What does request this image(tag)?
I see two possibilities:
page make AJAX requests to my service, that's why I see my IP. But in this case, why I couldn't see this request in Network tab of Developer Console?
Google Image Proxy service requests to my service, but why in this case there is my IP in request?
My IP:
[UPD]
Add part of class that handles requests to image(tag):
...
request.remoteAddress = str(self.request.remote_addr)# save remote address
request.put()
...
self.response.write(simpleImageData) #write to body binary data of 1x1 transparent image
self.response.headers[ 'Content-Type' ] = 'image/png'
self.response.headers[ 'Cache-Control' ] = 'no-cache, no-store, must-revalidate'
self.response.headers[ 'Pragma' ] = 'no-cache'
self.response.headers[ 'Expires' ] = '0'
[UPD 2]
I used wireshark to found requests to my service, but there are not any. That's why main question is how Google User Content simulate my IP address?

The workings of Google Image Proxy have been thoroughly analyzed on the web, e.g at https://litmus.com/blog/gmail-adds-image-caching-what-you-need-to-know and https://blog.filippo.io/how-the-new-gmail-image-proxy-works-and-what-this-means-for-you/ -- and the googleusercontent site is the cache/cdn used (among other things) by GIP.
The only relevance of Google App Engine might be how you've configured your app.yaml which you don't show us, i.e, is that image served as a static file, or via logic in your application code -- and, if the latter, does your code have any logging calls when it serves the image. From the limited data you show, I'd guess the former (so the file lives on, and is served by, Google's static file servers, not next to your app's code on your own instances), which would remove any mystery...

I deployed my app on my notebook, then I tried to repeat my actions.
Result confirmed my guess that Google Proxy and App Engine works together, and when Google proxy server requests my app, I see my IP.
In my experiment I saw IP of Google proxy.

Related

React app can't reach to backend python application on localhost on same server

I have a public cloud VM which has public IP say 160.159.158.157 (this has a domain registered against it).
I have a Django application (backend) which is CORS-enabled and serves data through port 8080.
I have a React app running on the same VIM on a different port (3000), which is accessing the Django app and is supposed to produce a report.
The problem is that, when I use http://<domain-name>:8080/api/ or http://<public-ip>:8080/api/, my application is working fine,
but when I try to fetch data from localhost like http://localhost:8080/api/ or http://127.0.0.1:8080/api/, the React app fails to fetch data with the following error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8080/api/. (Reason: CORS request did not succeed). Status code: (null).
Here's what I've tried:
axios.get(baseURL, { headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
}
but it didn't work. What should I do?
Looks like you've gotten confused where those headers need to be. You're setting them on the request to the backend, but they need to be set on the response from the backend. After all, it wouldn't be very good security if someone making a request could simply say "yeah, I'm ok, you should trust me".
The problem is going to be somewhere in your backend Django app, so double check the CORS config over there.

Implementing Google Directory API users watch with Python

I'm having some trouble understanding and implementing the Google Directory API's users watch function and push notification system (https://developers.google.com/admin-sdk/reports/v1/guides/push#creating-notification-channels) in my Python GAE app. What I'm trying to achieve is that any user (admin) who uses my app would be able to watch user changes within his own domain.
I've verified the domain I want to use for notifications and implemented the watch request as follows:
directoryauthdecorator = OAuth2Decorator(
approval_prompt='force',
client_id='my_client_id',
client_secret='my_client_secret',
callback_path='/oauth2callback',
scope=['https://www.googleapis.com/auth/admin.directory.user'])
class PushNotifications(webapp.RequestHandler):
#directoryauthdecorator.oauth_required
def get(self):
auth_http = directoryauthdecorator.http()
service = build("admin", "directory_v1", http=auth_http)
uu_id=str(uuid.uuid4())
param={}
param['customer']='my_customer'
param['event']='add'
param['body']={'type':'web_hook','id':uu_id,'address':'https://my-domain.com/pushNotifications'}
watchUsers = service.users().watch(**param).execute()
application = webapp.WSGIApplication(
[
('/pushNotifications',PushNotifications),
(directoryauthdecorator.callback_path, directoryauthdecorator.callback_handler())],
debug=True)
Now, the receiving part is what I don't understand. When I add a user on my domain and check the app's request logs I see some activity, but there's no usable data. How should I approach this part?
Any help would be appreciated. Thanks.
The problem
It seems like there's been some confusion in implementing the handler. Your handler actually sets up the notifications channel by sending a POST request to the Reports API endpoint. As the docs say:
To set up a notification channel for messages about changes to a particular resource, send a POST request to the watch method for the resource.
source
You should only need to send this request one time to set up the channel, and the "address" parameter should be the URL on your app that will receive the notifications.
Also, it's not clear what is happening with the following code:
param={}
param['customer']='my_customer'
param['event']='add'
Are you just breaking the code in order to post it here? Or is it actually written that way in the file? You should actually preserve, as much as possible, the code that your app is running so that we can reason about it.
The solution
It seems from the docs you linked - in the "Receiving Notifications" section, that you should have code inside the "address" specified to receive notifications that will inspect the POST request body and headers on the notification push request, and then do something with that data (like store it in BigQuery or send an email to the admin, etc.)
Managed to figure it out. In the App Engine logs I noticed that each time I make a change, which is being 'watched', on my domain I get a POST request from Google's API, but with a 302 code. I discovered that this was due to the fact I had login: required configured in my app.yaml for the script, which was handling the requests and the POST request was being redirected to the login page, instead of the processing script.

How to detect url callback request

I have a locally-run app that makes API calls to a website (tumblr.com). This involves setting some OAuth credentials; one step along the way requires extracting a key from a callback url that the server directs the browser to. So what I currently have the user do is:
Open an authorization link in a browser, which prompts them to authorize the OAuth application on the website
Click through the authorization page on the website (“Yes, I allow xxxxx app to access certain info associated with my account”)
Clicking Authorize app makes a request to the localhost which includes a parameter in the url. Meaning that tumblr will redirect the browser to the page http://localhost/?oauth_token={TOKEN}&oauth_verifier={VERIFIER}#_=_. I assume that causes a request to be made to the local machine when it does that.
The user is expected to isolate the key parameter in the url from the browser’s navigation bar, and paste it in the application.
So is there any way I can bypass steps 3 and 4 and simply have the app pick up the callback request instead of expecting the user to copy and paste it from the browser? I’m afraid I don’t know much about how to handle network requests in python.
To be clear, what I need to do is get the {VERIFIER} string.
okay first thing first, for http requests, a good python module is requests
http://docs.python-requests.org/en/master/
Then, your app gives a callback address to tumblr so that tumblr can tell to your app client info, or login error.
Now, your point 3 isn't clear.
"Clicking authorize app makes a request to localhost"
Actually clicking "authorize app" for the user makes a request to tumblr saying he accepts.
Then tumblr makes a request to your callback url passing the infos.
The callback url should probably be your server address, there you must have a script listening for tumblr, which will give you your special parameter to call their api...
In addition :
So when the users click "authorize app" there is a request to tumblr, which redirects the user to the callback url (adding oauth token and verifier).
Now, obviously, you can't ask for every user to have an http server running on their computer.
So you must set the callback url to your server.
So if you set it to "myserver.com/tumblr" for instance, the user will get redirected to your webpage, and you'll get on your server, and for that user session, the oauths token and verifier.
and...
Assuming your app is client only I'd say there are two options.
Either have your users enter manually their API keys.
Or either embed a webserver into your app.
In the case of the embedded webserver, I'd suggest flask for its simplicity.
Simply have your webserver listen on a given port and set the callback url to that server:port.
This way you'll get the client tokens directly.

401 Unauthorized making REST Call to Azure API App using Bearer token

I created 2 applications in my Azure directory, 1 for my API Server and one for my API client. I am using the Python ADAL Library and can successfully obtain a token using the following code:
tenant_id = "abc123-abc123-abc123"
context = adal.AuthenticationContext('https://login.microsoftonline.com/' + tenant_id)
token = context.acquire_token_with_username_password(
'https://myapiserver.azurewebsites.net/',
'myuser',
'mypassword',
'my_apiclient_client_id'
)
I then try to send a request to my API app using the following method but keep getting 'unauthorized':
at = token['accessToken']
id_token = "Bearer {0}".format(at)
response = requests.get('https://myapiserver.azurewebsites.net/', headers={"Authorization": id_token})
I am able to successfully login using myuser/mypass from the loginurl. I have also given the client app access to the server app in Azure AD.
Although the question was posted a long time ago, I'll try to provide an answer. I stumbled across the question because we had the exact same problem here. We could successfully obtain a token with the adal library but then we were not able to access the resource I obtained the token for.
To make things worse, we sat up a simple console app in .Net, used the exact same parameters, and it was working. We could also copy the token obtained through the .Net app and use it in our Python request and it worked (this one is kind of obvious, but made us confident that the problem was not related to how I assemble the request).
The source of the problem was in the end in the oauth2_client of the adal python package. When I compared the actual HTTP requests sent by the .Net and the python app, a subtle difference was that the python app sent a POST request explicitly asking for api-version=1.0.
POST https://login.microsoftonline.com/common//oauth2/token?api-version=1.0
Once I changed the following line in oauth2_client.py in the adal library, I could access my resource.
Changed
return urlparse('{}?{}'.format(self._token_endpoint, urlencode(parameters)))
in the method _create_token_url, to
return urlparse(self._token_endpoint)
We are working on a pull request to patch the library in github.
For the current release of Azure Python SDK, it support authentication with a service principal. It does not support authentication using an ADAL library yet. Maybe it will in future releases.
See https://azure-sdk-for-python.readthedocs.io/en/latest/resourcemanagement.html#authentication for details.
See also Azure Active Directory Authentication Libraries for the platforms ADAL is available on.
#Derek,
Could you set your Issue URL on Azure Portal? If I set the wrong Issue URL, I could get the same error with you. It seems that your code is right.
Base on my experience, you need add your application into Azure AD and get a client ID.(I am sure you have done this.) And then you can get the tenant ID and input into Issue URL textbox on Azure portal.
NOTE:
On old portal(manage.windowsazure.com),in the bottom command bar, click View Endpoints, and then copy the Federation Metadata Document URL and download that document or navigate to it in a browser.
Within the root EntityDescriptor element, there should be an entityID attribute of the form https://sts.windows.net/ followed by a GUID specific to your tenant (called a "tenant ID"). Copy this value - it will serve as your Issuer URL. You will configure your application to use this later.
My demo is as following:
import adal
import requests
TenantURL='https://login.microsoftonline.com/*******'
context = adal.AuthenticationContext(TenantURL)
RESOURCE = 'http://wi****.azurewebsites.net'
ClientID='****'
ClientSect='7****'
token_response = context.acquire_token_with_client_credentials(
RESOURCE,
ClientID,
ClientSect
)
access_token = token_response.get('accessToken')
print(access_token)
id_token = "Bearer {0}".format(access_token)
response = requests.get(RESOURCE, headers={"Authorization": id_token})
print(response)
Please try to modified it. Any updates, please let me know.

HTTP 403 'Rate Limit Exceeded' ERROR in Google Blogger v3 API

I have a python script which uses Google Blogger API with oauth 2.0. Now the problem is that there is a function blogger.posts.insert. It is returning an error "HTTP 403 'Rate Limited Exceeded'".
Can anybody tell me how to fix this?
I also tried to do the same in python and the error is still there..
Note: blogger.posts.update function works perfectly!
credentials = storage.get()
http = httplib2.Http()
http = credentials.authorize(http)
service = build('blogger', 'v3', http=http)
TheBlogID = 'somethingHERE'
print "fetching posts, please wait!"
posts = service.posts()
thisposties = posts.list(blogId=TheBlogID).execute()
posts.insert(blogId=TheBlogID, # THIS IS THE PROBLEM
body=body,
isDraft=False, fetchImages=False, fetchBody=True).execute()
EDIT: Also I must tell you that just a few minutes ago I created credentials by selectingWeb Application here : https://console.developers.google.com/apis/credentials? but it stopped working after adding 50 posts and so I switched to other. Also I tried to create a new credential with Web Application but the redirect URL for urn:ietf:wg:oauth:2.0:oob is denying so currently I am using other as credential for oauth 2.0 and getting this error when trying to insert ...
I also tried from here: https://developers.google.com/apis-explorer/#p/blogger/v3/ Same ERROR... I'm assuming this is some bug with google API...
I was right, there is a bug with Google Blogger API when using the insert to add posts so this is how I fixed it:
I started Apache using XAMP and apache was running on port 80 ( can be different for you so check it in XAMP control panel ).
I created a Web Application here: https://console.developers.google.com/apis/credentials?
When creating a new web application I made sure to set the redirect URL to http://localhost:80/oauth2callback ( My apache is running on port 80 that is why it is localhost:80 ) You must also add this redirect URL to python code.
Create a new directory in XAMP C:\xampp\htdocs\ oauth2callback
Create an empty index.php in C:\xampp\htdocs\oauth2callback
Go to 192.168.1.1 and do port forwarding for port where apache is running BOTH TCP and UDP for port 80 ( since apache is running on this port for me )
Now simply run your python code and when you get the auth URL then simply open it in your browser and you will be asked to confirm it then do it. You will be redirected to your C:\xampp\htdocs\oauth2callback\index.php and now ignore the blank white screen and simply look at your browser address bar, you will see code=CODEHERE. Now copy that code and simply give it as input for python and then you will be able to use insert
Enjoy :)
I know this is pretty insane but this is how I was able to fix it.
NOTE: MAXMIMUM UPLOAD RATE FOR POSTS IS 50 POSTS/DAY.

Categories

Resources