401 and 403 Errors with google base API - python

I built a wiki using Google App engine and the Data APIs. The wiki pages are stored as Google Base 'Reference Articles.' I want users to be able to view, edit, and delete the items, so when a request is made to the server, client login uses my username and password, and retrieves or edits the data on the user's behalf. The login code:
client = gdata.base.service.GBaseService()
client.ssl = False
gdata.alt.appengine.run_on_appengine(client)
#EMAIL, API_KEY and PASSWORD are constants stored on the server
client.email = EMAIL
client.password = PASSWORD
client.api_key = API_KEY
client.ProgrammaticLogin()
q = gdata.base.service.BaseQuery()
q.feed = '/base/feeds/items/' + self.base_id
item = base_client.GetItem(q.ToUri())
This works fine for me, but if I log out of my google account, it returns the following error:
'status': 401L, 'body': '<HTML>\n<HEAD>\n<TITLE>Authorization required</TITLE>
All I want is for the users to be able to CRUD my data stored on Base. What am I doing wrong?
Thanks in advance

It sounds like logging out in your client is invalidating all sessions for your account. Your best bet is probably to create a role account specifically for your app to use.

Related

how to make flask route available to svelte and not end user

I have a flask server that has API like route - #app.route("/api/v1.0/name/<string:name>", methods=["GET"])
this go and query a firestore DB i have set up in GCP.
I have set up my frontend to be in svelte. it's still not much, just a field to enter a name, and a button to search for it in my db.
when running my webapp (I first run python .\server.py then run npm run dev which allows me to see my web page and interact with it. everything works correctly.
my issue is that i don't want users from the internet to be able to send the query directly:
www.mywebsite.com/api/v1.0/name/alice which currently is a valid route and i can actually get that way to query my DB directly.
these are the three routes i have in the flask server:
def index():
return send_from_directory("../client/public", "index.html")
#app.route("/<path:path>")
def home(path):
return send_from_directory("../client/public", path)
#app.route("/api/v1.0/name/<string:name>", methods=["GET"])
def get_by_name(name):
"""
retrieve by name value
"""
docs = db.collection(collection_name.where("name", "==", f"{name}").stream()
return_string = ""
for doc in docs:
if doc:
return_string += f"{doc.info}"
if not return_string:
return "No such name"
return return_string
and this is my svelte.app file:
<script>
export let db_result;
let name_query = "";
function getNameFromDB() {
fetch("/api/v1.0/name/" + name_query)
.then(d => d.text())
.then(d => (db_result = d));
}
</script>
<input bind:value={name_query}>
<button on:click={getNameFromDB}>show this name info</button>
{#if db_result}
<p>"name info: " {db_result}</p>
{/if}
I'm not sure where this solution should be, in the flask server? in svelte app? maybe set up a rule in the firestore if that is possible?
You need to add authentication to your firestore DB. You can see the docs for this here: https://firebase.google.com/docs/firestore/use-rest-api#authentication_and_authorization
The relevant is copied below:
For authentication, the Cloud Firestore REST API accepts either a Firebase Authentication ID token or a Google Identity OAuth 2.0 token. The token you provide affects your request's authorization:
Use Firebase ID tokens to authenticate requests from your application's users. For these requests, Cloud Firestore uses Cloud Firestore Security Rules to determine if a request is authorized.
Use a Google Identity OAuth 2.0 token and a service account to authenticate requests from your application, such as requests for database administration. For these requests, Cloud Firestore uses Cloud Identity and Access Management (IAM) to determine if a request is authorized.
Best of luck!

How to authenticate to Firebase using Python?

I am building a Web App with Python and I would like to authenticate users.
The pyrebase package seems to be outdated and it generates dependency errors so I cannot use it.
I know that there is a function from the firebase-admin API that works like this:
from firebase import auth
email = example#example.com
user = auth.get_user_by_email(email)
But what if this user has a password? I would like to check if the both the email and the password are provided correctly. Thanks in advance.
The Firebase Admin SDK does not have the concept of a current user, so there's no API to "sign in" a user based on their credentials.
Since you're building a web app, the usual flow is to use the Firebase JavaScript SDK in your client-side code to sign the user in. If needed you can then send the ID token from the client to your Python code on the server, and perform user-based operations there.
Firebase Admin SDK doesn’t provide an API to validate and/or authenticate a user by their password.
However, Firebase provides the Firebase Auth REST API for this purpose. To use the REST API, you need to obtain your Web API Key from the Firebase console.
To Locate the Web API Key
Navigate to Project Settings from Firebase console, then find Web API Key on the General tab. The Web Api key is auto generated whenever you add app to your firebase project. You can also go to an app settings to find apiKey from firebaseConfig
Implement Authentication
Suppose you want to implement user sign in
def sign_in_with_email_and_password(email, password, return_secure_token=True):
payload = json.dumps({"email":email, "password":password, "return_secure_token":return_secure_token})
FIREBASE_WEB_API_KEY = 'the web API key here'
rest_api_url = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword"
r = requests.post(rest_api_url,
params={"key": FIREBASE_WEB_API_KEY},
data=payload)
return r.json()
References
https://betterprogramming.pub/user-management-with-firebase-and-python-749a7a87b2b6
https://firebase.google.com/docs/projects/api-keys
https://firebase.google.com/docs/reference/rest/auth

Microsoft Graph Authentication

I’m building an application in Python which can retrieve data from Azure AD. This data can require either Application permissions or Delegated permissions. I had a success retrieving data which needs only Application permissions. However, in order to retrieve data which needs delegated permission, I am trying to use OAuth2. Is it possible to get authenticated with Microsoft Graph using OAuth2 but not having the user sign in using the web page, but instead supplying the user credentials through the Python script itself?
Note: I want to use Microsoft Graph API (v1.0 and beta) and not Azure AD Graph API.
Assuming you have registered and configured (api permissions) your azure app and you have copied the apps "client id" and "client secret" you can define a class that holds your session.
The following code works for my app:
import json
import requests
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import BackendApplicationClient
class SharepointSession(object):
""" Base Class without credentials, use real credentials in derived Classes
or instances
"""
api_uri = "https://graph.microsoft.com"
api_version = "v1.0"
scope = ["https://graph.microsoft.com/.default"]
directory_id = "" # - tenant id
token_url = "https://login.microsoftonline.com/{}/oauth2/v2.0/token"
sites_url = "{}/{}/sites".format(api_uri, api_version)
site = document_name = app_name = client_id = client_secret = ""
site_id = None
doc_id = None
def __init__(self):
""" """
def getTokenizedSession(self):
"""
OAuth2 to get access token
First set up a backend client, mind to set grant_type
build a OAuth2 Session with the client
get access token
Mind: python 3.x oauthlib requires scope params on more calls than py 2.x
"""
client = BackendApplicationClient(
client_id=self.client_id, scope=self.scope, grant_type="client_credentials")
session = OAuth2Session(client=client, scope=self.scope)
# fill access token
token = session.fetch_token(token_url=self.token_url.format(self.directory_id),
client_id=self.client_id,
scope=self.scope,
client_secret=self.client_secret)
self.session = session
self.token = token
return session, token
def getSiteId(self):
# get the site id
ae = "{}/myonline.sharepoint.com:/sites/{}:".format(
self.sites_url, self.site)
rt = self.session.get(ae)
response = json.loads(rt.text)
self.site_id = response.get("id")
return self.site_id
def someOtherMethod(self):
""" ... """
Now you can instantiate the session class with the credentials copied from your azure app registration i.e. "directory id" (same as tenant id), "client id" and "client secret"
like this:
mysp_session = SharepointSession()
mysp_session.directory_id = "XXXXXXXX-XXXX-YYYY-ZZZZ-XXXXXXXXX"
mysp_session.site = "MySitename"
mysp_session.document_name = "Testlist"
mysp_session.client_id = r"xxxxxxxxxxxxxxxxxxxxxxx"
mysp_session.client_secret = r"xxxxxxxxxxxxxxxxxxxxxxx"
# connect
session, token = mysp_session.getTokenizedSession()
# do your business logic
mysp_session.getSiteId()
....
mysp_session.someOtherMethod()
hope that helps
Yes, this is possible - but keep in mind that there are two Azure AD endpoints for application registration!
Try registering an application on the AAD V2.0 endpoint (apps.dev.microsoft.com), and then use a 'password' grant_type in your request.
Here are the steps you need:
Register your app on the AAD v2.0 endpoint, and generate a password (take
note of this)
Assign your required permissions (in this case, delegated)
As a callback URL I'd suggest using postman's Oauth2 callback URL first so you can debug what you're doing: https://www.getpostman.com/oauth2/callback
Important! If any of those permissions require admin consent, you MUST consent to them first to make the app available. This requires the admin user to sign in once.
Once consent has been given, here's a what your request needs to get a bearer token as a prototype:
POST https://login.microsoftonline.com/common/oauth2/token
Request body (application/x-www-form-urlencoded):
grant_type=[password]
username=[user email address]
password=[user password]
resource=https://graph.microsoft.com
client_id=[your newly registered application ID]
client_secret=[application password you noted during registration]
If successful, you'll get the bearer & refresh token as a response.
Hope this helps,
Ben
You need an Azure AD application to be able to authenticate with Graph API. A native Azure AD app and the flow and considerations described here work for ADAL.net. I use it to provision Microsoft Teams unattended: http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/
I guess for Python you should have a look at ADAL for Python: https://github.com/introp-software/azure-activedirectory-library-for-python-old/blob/master/README.md
I think that the username/password auth is only possible with a native Azure AD app and not the web/web api types.

How to apply Spotify API authentication on my current code which uses Spotify Search API?

Earlier I was using Spotify's Search API
without any kind of authentication. But just last week or so, they made their API usage with Authentication only.
So since the past 2-3 days I've not been able to figure how this authorization works for Search API where I as a developer can let users access responses from Search API without having them to login with their Spotify accounts.
Can someone help me with this authorization stuff(The docs from Spotify don't solve my problem :< )
So here's the python code that I was earlier using -
import requests
import json
def Spotify(keyword):
url = "https://api.spotify.com/v1/search?q="+keyword+"&type=track&limit=1"
headers = {
'accept': "application/json",
'access_token':''
}
r = requests.get(url=url,headers=headers).text
jsonwa = json.loads(r)
name = jsonwa["tracks"]["items"][0]["name"]
artists = jsonwa["tracks"]["items"][0]["artists"][0]["name"]
song_preview_url = jsonwa["tracks"]["items"][0]["preview_url"]
image = jsonwa["tracks"]["items"][0]["album"]["images"][1]["url"]
return_this = []
return_this.append(name)
return_this.append(artists)
return_this.append(song_preview_url)
return_this.append(image)
print return_this
return return_this
song = "hello"
Spotify(song)
Per the web authorization docs:
All requests to the Spotify Web API require authorization
You'll need your users to grant permission for your app in order to get an access token. The user must be logged in to gran permission.
Once your app is granted permission by the user, you can use the refresh_token from that point on, and the user shouldn't need to grant permission again unless they revoke permission for example. You'll need to manage the access_token expiration.

Django users post to twitter

I use Django-social-auth to authenticate the users of a Django project. So I guess I have all the necessary information about a Twitter user to make a post on their behalf on their Twitter account. So do I really need to install a new app? or with the info at hand how would I do that? Isn't it just a matter of posting to a Twitter API with the relevant info?
You could just extract the code into your own project and that will work. But the benefits of using an open source library is that there's a good chance when Twitter or Social Network X changes it's API, the library, if popular, would get updated as opposed to you needing to make the change.
So if you use Django Social Auth you can do:
import urllib
import settings
import oauth2 as oauth
try:
twitter_user = user.social_auth.get(provider='twitter')
except:
return
if not twitter_user.tokens:
return
access_token = twitter_user.tokens['oauth_token']
access_token_secret = twitter_user.tokens['oauth_token_secret']
token = oauth.Token(access_token,access_token_secret)
consumer_key = settings.TWITTER_CONSUMER_KEY
consumer_secret = settings.TWITTER_CONSUMER_SECRET
consumer = oauth.Consumer(consumer_key,consumer_secret)
client = oauth.Client(consumer,token)
data = {'status':'Your tweet goes here'}
request_uri = 'https://api.twitter.com/1/statuses/update.json'
resp, content = client.request(request_uri, 'POST', urllib.urlencode(data))
Yes, I believe if you have the User's twitter account details that are necessary, then you can write an (django) app which will do so. You can use something like python-twitter to post to twitter.
You should be able to find more information regarding Twitter's api here.

Categories

Resources