Flask + SQLAlchemy + Google Ads API : How to properly update refresh token? - python

# create/login local user on successful OAuth login
#oauth_authorized.connect_via(google)
def google_logged_in(blueprint, token):
#
# Token is accessible in this scope with token=xyz
#
# One Time Commit to unlock the database
# db.session.commit()
##########################################
if not token:
flash("Failed to log in.", category="error")
return False
resp = blueprint.session.get("/oauth2/v1/userinfo")
if not resp.ok:
msg = "Failed to fetch user info."
flash(msg, category="error")
return False
info = resp.json()
user_id = str(info["id"])
# Find this OAuth token in the database, or create it
query = OAuth.query.filter_by(provider=blueprint.name, provider_user_id=user_id)
try:
oauth = query.one()
db.session.commit()
except NoResultFound:
oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token)
if oauth.user:
# If this OAuth token already has an associated local account,
# log in that local user account.
# Note that if we just created this OAuth token, then it can't
# have an associated local account yet.
#
try:
update=OAuth.query.filter_by(provider=blueprint.name, provider_user_id=user_id)
update.token=token
db.session.commit()
except:
print('cannot update login token')
login_user(oauth.user)
flash("Successfully signed in.")
else:
# Create a new local user account for this user
user = User(email=info["email"],image_url=info["picture"])
# Associate the new local user account with the OAuth token
oauth.user = user
# Save and commit our database models
db.session.add_all([user, oauth])
db.session.commit()
# Log in the new local user account
login_user(user)
flash("Successfully signed in.")
# Disable Flask-Dance's default behavior for saving the OAuth token
return False
What I am trying to do is following:
Flowchart of my Process
I am database noob so i am not sure if I am doing what I want.
The problem is that my database locks after my token expires so something is not working with this part:
if oauth.user:
# If this OAuth token already has an associated local account,
# log in that local user account.
# Note that if we just created this OAuth token, then it can't
# have an associated local account yet.
#
try:
update=OAuth.query.filter_by(provider=blueprint.name, provider_user_id=user_id)
update.token=token
db.session.commit()
except:
print('cannot update login token')
login_user(oauth.user)
flash("Successfully signed in.")
But I couldnt find out where the problem is.
Docs didnt help and following SO posts didnt help either:
How do I unlock a SQLite database?
SQLAlchemy and SQLite: database is locked
https://www.reddit.com/r/flask/comments/36g2g7/af_sqlite_database_locking_problem/
Can someone get my ass out of existential chrisis and SQL dumbness?
Edit:
After the token has expired I now only get the message:
oauthlib.oauth2.rfc6749.errors.InvalidGrantError: (invalid_grant) Token has been expired or revoked.
I fixed a little bit when i replaced
query = OAuth.query.filter_by(provider=blueprint.name, provider_user_id=user_id)
with
query = db.session.query(OAuth).filter_by(provider=blueprint.name, provider_user_id=user_id)
but I seem not to write the new token to the database since I still get:
oauthlib.oauth2.rfc6749.errors.InvalidGrantError: (invalid_grant) Token has been expired or revoked.
So now my question how do I properly update refresh token?

I did not catch an error in:
update=db.session.query(OAuth).filter_by(provider=blueprint.name, provider_user_id=user_id) update.token=token
because of try statement(i know its noobish). I than updated my code like this:
if oauth.user:
# If this OAuth token already has an associated local account,
# log in that local user account.
# Note that if we just created this OAuth token, then it can't
# have an associated local account yet.
#
#try:
print('Trying to update the token')
update=db.session.query(OAuth).filter_by(provider=blueprint.name, provider_user_id=user_id)
update.token=token
db.session.commit()
print('User has been updated:', update.token==token)
#except:
# print('cannot update login token')
login_user(oauth.user)
flash("Successfully signed in.")
Found out that
AttributeError: 'BaseQuery' object has no attribute 'token'
googled it quickly and found out that i need to use the first() like that:
update=db.session.query(OAuth).filter_by(provider=blueprint.name, provider_user_id=user_id).first()
Thanks to myself for being such noob and still get an answer to my question.

Related

mongodb python get users of database

I want to create an admin application to monitor data collection. For this the user registration process is based on the database access i.e, when we create a new database user through MongoDB atlas, they will immediately be able to log into the admin application with their database username and password. How do I get a mongo document/response containing the list of database users and their hashed passwords using python?
I made a function that accepts the Mongo database user's username and password and uses that to connect to a Mongo client. I then attempt to perform a basic read operation (read operation requires the least user privilege) If the read op is successful then it means the username and password provides are authentic and I return true, else check if the operation failed because of a failed authentication and return false.
from pymongo import MongoClient
from pymongo.errors import OperationFailure
def check_dbuser(username, password):
""" Attempts to connect to mongo atlas using the username and password. It then attempts a basic operation which is
to list the database names of the cluster. If the operation works, the username and password are authentic and
return True.
Else if there is an OperationFailure we check that the error is due to failed authentication and return False
"""
auth = False
failed_message = 'bad auth Authentication failed.' # this is the err message returned on a failed authentication
uri = f'mongodb+srv://{username}:{password}#cluster-connection-string'
client = MongoClient(uri)
try:
client.list_database_names()
except OperationFailure as e:
assert(e.details['errmsg'] == failed_message) # assert that the error message is that of an authentication failure
else:
auth = True
return auth

Unable to validate The credentials using pysnow

I need to validate if servicenow login credentials are correct or not.
I am using pysnow
def validate_conn(self, data):
instance = data['url']
user = data['uname']
password = data['pwd']
try:
pysnow.client.Client(instance=instance, host=None, user=user, password='xfgdfgdf', raise_on_empty=None,
request_params=None, session=None)
print("valid")
except:
print("invalid")
return data['pwd']
In the above code I gave the invalid password so it have to come to the except block but i am getting valid as output. I need to validate if credentials are valid or not
The ServiceNow Web Services API does not provide a mechanism to validate credentials. One way to validate credentials from a Web Services client is to attempt to read a record that you know exists. One record that must exist is your own user record from sys_user.
The following code attempts to read your own user record from sys_user. If you are unable to read this record, then something must be wrong.
try:
client = pysnow.Client(instance=instance, user=user, password=password)
response = (client
.resource(api_path='/table/sys_user')
.get(query={'user_name': user})
.one())
print('credentials are valid')
except:
print('credentials are not valid')

How can I handle HTTP login flow/logic

I'm developing an application that requires the user to login. It's a terminal browser to navigate, and use, a popular email client.
I am struggling with the logic flow of actually logging the user in without things getting messy. I will try to explain what I'm trying to achieve in psedueo code, and then demonstrate what I've currently done.
username = 'joe#example.com'
password = 'itsasecret'
# User has logged in before using our application. Instead of
# logging in via HTTP, just inject the cookies into the session.
if userExistsInDatabase:
session.addCookies(db.getCookies(username))
# Check the session is still valid. Just because we load
# the cookie from the database doesn't mean it's valid as
# the account could be blocked, or session could have expired
if session.checkIfSessionIsValid():
print 'Logged In'
else:
# Login failed, now we need to do a HTTP request
# incase the session has died
if session.login(username, password):
# Login success
else:
# Login Failed
else:
# No session exists in DB, try to log in and add user to db
if session.login(username, password):
# Login success
else:
# Login Failed
I hope that code explains it better than I could in words. But, the problem I am having is everything is getting messy and fast, and it's a pain to have to repeat this code whenever I need to use it.
This is something I do regular on a lot of my projects, because most HTTP sites, at least the large ones, have a similar sort of login flow.
Any advice? If you need more info, please ask.
Assuming the supporting code make proper use of exceptions, you can solve this with less code duplication:
class Session():
def reconnect(self, username):
try:
cookie = db.getCookies(username)
except LookupError:
raise UserDoesNotExist
else:
self.addCookies(cookie)
if not self.checkIfSessionIsValid():
raise InvalidSession
def login(self, ...):
if not do_the_login(...):
raise LoginError
try:
try:
session.reconnect(...)
except (InvalidSession, UserDoesNotExist):
session.login(...)
except LoginError:
# failed
# at this point, either an unhandled exception terminated
# this code path or we are logged in.

Does the ouath verifier token remain unique for every request

I am trying to make an application to sign in user using twitter.
I want to identify the users that have at some point in the past already logged in the application so I save the oauth verifier token received at the call back in the database and every time I am logging in a user I match the verifier that I receive at the call back if I have a token for this particular user and then fetch the access token and access token secret from the database.
courtesy this post
This is the code I am using:
Please let me know if there is anything wrong with this, I am already confused why is the code breaking.
verifier= request.args['oauth_verifier']
this_user = user_exists(verifier) #checks if a user is returned for the verification token
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
if this_user is None:
auth, error = authenticate_user(auth) #handles the oauth
clean_up(auth) #saves in db and logs in the user
else:
try:
auth.set_access_token(this_user[access_token], this_user[access_token_secret])
clean_up(auth)
except tweepy.TweepError:
auth, error = authenticate_user(auth)
if type(error) is None:
clean_up(auth)
else:
flash('Oops! That shouldn\'t have happened! ):')
return redirect(url_for('index'))
return redirect(url_for('profile'))
Any help would be highly appreciated.
Thanks! (:

Does OAuth2Decorator store user Credentials and renew Tokens?

I'm working with the OAuth2Decorator() and Pytgon I'm in that stage where i'm still unsure of something about the App Engine. The documentation is not providing any info or I simply can't follow it. So:
Does OAuth2Decorator() store user Crediantials?
Does OAuth2Decorator() retrieve new tokens automatically?
Conside this following example.:
decorator = OAuth2Decorator(...)
service = build("drive", "v2")
class AppHandler(BaseHandler):
#decorator.oauth_aware
def get(self):
if decorator.has_credentials():
init = service.files().list().execute(decorator.http())
items = init['items']
context = {'data': getitems(items)}
self.render_response('index.html',**context)
else:
url = decorator.authorize_url()
self.redirect(url)
The credentials get stored as CredentialsModel in the datastore.
Provided the access that's requested is 'offline' (I believe this is the default), then there will be a 'refresh token' stored alongside the temporary access-token. If a request is made with a credentials-wrapped Http client, then upon receiving a response that indicates the access token has expired, the client make a request to get a new access token automatically, and then the original request will be retried with the new access token, which will then be stored in place of the expired one.

Categories

Resources