def catch_login(): #TODO: Add state # from docs: https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/ client_id = settings.GITHUB_CLIENT_ID client_secret = settings.GITHUB_CLIENT_SECRET oauth_url = settings.GITHUB_OAUTH_URL user_url = settings.GITHUB_USER_URL payload = { 'client_id': client_id, 'client_secret': client_secret, 'code': request.args.get('code') } headers = { "content-type": "application/json", "accept": "application/json" } if payload.get('code'): response = requests.post(oauth_url, json=payload, headers=headers) # Check if the code has expired body = response.json() if response.status_code == 200: token = response.json().get('access_token') headers = { "Accept": "application/json", "Authorization": f"token {token}" } response = requests.get(user_url, headers=headers).json() username = response.get('login') exists = User.query.filter_by(username=username).first() # Just a login version, skip registration if exists: return exists.encode_auth_token(), 200 user = User(username=username, email=response.get('email'), name=response.get('name')) db.session.add(user) db.session.commit() oauth = OAuth(user=user, token=token, provider="github") db.session.add(oauth) db.session.commit() return user.encode_auth_token(), 201 else: return jsonify({"status": "failed"}), 409 else: return jsonify({}), 400 return jsonify({"error": "fallthrough"}), 400
def google_logged_in(blueprint, token): """ Handle the callback from Google and create a user and log the user in if the user does not exist, if the user exist then just log in the user matching the credentials. """ if not token: flash("Failed to log in with Google.", category="error") return False resp = blueprint.session.get("/oauth2/v1/userinfo") if not resp.ok: msg = "Failed to fetch user info from Google." flash(msg, category="error") return False google_info = resp.json() google_id = google_info['id'] # Find this OAuth token in the database, or create it query = OAuth.query.filter_by( provider=blueprint.name, provider_user_id=google_id, ) try: oauth = query.one() except NoResultFound: oauth = OAuth( provider=blueprint.name, provider_user_id=google_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. login_user(oauth.user) else: # If this OAuth token doesn't have an associated local account, # create a new local user account for this user. We can log # in that account as well, while we're at it. user = User( email=google_info["email"], name=google_info["name"], ) # 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 with Google.") # Disable Flask-Dance's default behavior for saving the OAuth token return False
def twitter_logged_in(blueprint, token): if not token: flash("Failed to log in.", category="error") return False resp = blueprint.session.get( "account/verify_credentials.json?include_email=true") if not resp.ok: msg = "Failed to fetch user info." flash(msg, category="error") return False info = resp.json() user_id = info["id_str"] # 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() except NoResultFound: oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token) if oauth.user: session['user_id'] = oauth.user_id login_user(oauth.user) else: # Create a new local user account for this user unique_id = uuid.uuid4().hex[:8] # generate unique_id for user if Users.query.filter_by(email=info["email"]).first() is not None: flash("This email is already registered with other account.") return redirect(url_for('sign_in')) user = Users(unique_id, None, None, info["screen_name"], info["name"], info["screen_name"], info["email"], None, False) # 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 session['user_id'] = Users.query.filter_by( unique_id=unique_id).first().id login_user(user) # Disable Flask-Dance's default behavior for saving the OAuth token return False
def twitter_logged_in(blueprint, token): if not token: flash("Failed to log in.", category="error") return False resp = blueprint.session.get("account/verify_credentials.json") if not resp.ok: msg = "Failed to fetch user info." flash(msg, category="error") return False info = resp.json() user_id = info["id_str"] # 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() except NoResultFound: oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token) if oauth.user: session['user_id'] = oauth.user_id login_user(oauth.user) flash("Successfully signed in.") else: # Create a new local user account for this user unique_id = uuid.uuid4().hex[:8] user = Users(twitter_name=info["screen_name"], twitter_user_name=info["name"], unique_id=unique_id) # 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 session['user_id'] = Users.query.filter_by( unique_id=unique_id).first().id login_user(user) flash("Successfully signed in.") # Disable Flask-Dance's default behavior for saving the OAuth token return False
def google_logged_in(blueprint, token): 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 = 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() except NoResultFound: oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token) if oauth.user: session['user_id'] = oauth.user_id login_user(oauth.user) else: # Create a new local user account for this user if Users.query.filter_by(email=info["email"]).first() is not None: flash("This email is already registered with other account.") return redirect(url_for('sign_in')) u_name = info["email"].split("@")[0] user = Users(info["email"], info["name"], None, None, u_name, info["email"], None) # 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 session['user_id'] = user.id login_user(user) # Disable Flask-Dance's default behavior for saving the OAuth token return False
def google_logged_in(blueprint, token): 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 = 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() except NoResultFound: oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token) if oauth.user: login_user(oauth.user) flash("Successfully signed in.") else: # Create a new local user account for this user user = User(email=info["email"], profile_pic=info["picture"]) profile = Profile(username=info["email"].split("@")[0]) # 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, profile]) 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
def facebook_logged_in(blueprint, token): if not token: flash("Failed to log in.", category="error") return False resp = blueprint.session.get("/me") if not resp.ok: msg = "Failed to fetch user info." flash(msg, category="error") return False info = resp.json() user_id = 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() except NoResultFound: oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token) if oauth.user: login_user(oauth.user) else: # Create a new local user account for this user user = User(name=info["name"]) # 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) print(login_session.get("current_uri")) # Disable Flask-Dance's default behavior for saving the OAuth token return False
def twitter_logged_in(blueprint, token): if not token: flash("Failed to log in with GitHub.", category="error") return False account_info = blueprint.session.get('account/verify_credentials.json') if account_info.ok: account_info_json = account_info.json() user_id = str(account_info_json['id']) username = account_info_json['screen_name'] query = OAuth.query.filter_by( provider=blueprint.name, provider_user_id=user_id, ) try: oauth = query.one() except NoResultFound: oauth = OAuth( provider=blueprint.name, provider_user_id=user_id, token=token, ) if oauth.user: login_user(oauth.user) flash("Successfully signed in with Twitter.") else: user = User(username=username) oauth.user = user db.session.add_all([user, oauth]) db.session.commit() login_user(user) flash("Successfully signed with Twitter.") else: msg = "Failed to fetch user info from GitHub." flash(msg, category="error") return False
def spotify_logged_in(blueprint, token): if not token: msg = "Failed to log in." flash(msg, category="error") return False resp = blueprint.session.get("/v1/me") if not resp.ok: msg = "Failed to fetch user info." flash(msg, category="error") return False info = resp.json() user_id = info["id"] query = OAuth.query.filter_by(provider=blueprint.name, provider_user_id=user_id) try: oauth = query.one() except NoResultFound: oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token) if oauth.user: login_user(oauth.user) flash("Successfully signed in.") else: user = User(email=info["email"], display_name=info["display_name"]) oauth.user = user db.session.add_all([user, oauth]) db.session.commit() login_user(user) flash("Successfully signed in.") return False
def google_logged_in(blueprint, token): if not token: flash("Failed to log in with Google.", category="error") return resp = blueprint.session.get("/oauth2/v2/userinfo") if not resp.ok: msg = "Failed to fetch user info from Google." flash(msg, category="error") return google_info = resp.json() google_user_id = str(google_info["id"]) # Find this OAuth token in the database, or create it query = OAuth.query.filter_by(provider=blueprint.name, provider_user_id=google_user_id) try: oauth = query.one() except: google_user_login = str(google_info["email"]) oauth = OAuth( provider=blueprint.name, provider_user_id=google_user_id, provider_user_login=google_user_login, token=token, ) # Now, figure out what to do with this token. There are 2x2 options: # user login state and token link state. if current_user.is_anonymous: if oauth.user: # If the user is not logged in and the token is linked, # log the user into the linked user account login_user(oauth.user) else: # If the user is not logged in and the token is unlinked, # create a new local user account and log that account in. # This means that one person can make multiple accounts, but it's # OK because they can merge those accounts later. user = User(email=google_info["email"]) oauth.user = user db.session.add_all([user, oauth]) db.session.commit() login_user(user) else: if oauth.user: # If the user is logged in and the token is linked, check if these # accounts are the same! if current_user != oauth.user: # Account collision! Ask user if they want to merge accounts. url = url_for("auth.merge", username=oauth.user.username) return redirect(url) else: # If the user is logged in and the token is unlinked, # link the token to the current user oauth.user = current_user db.session.add(oauth) db.session.commit() # Indicate that the backend shouldn't manage creating the OAuth object # in the database, since we've already done so! return False
def wrap(*args, **kwargs): kind = None # Grab the session cookie if it exists. cookie = request.cookies.get(current_app.session_cookie_name, None) # Try get the Auth header data. try: auth = request.headers['Authorization'] kind, _, value = auth.partition(' ') if kind == 'Basic': value = base64.standard_b64decode(bytes(value, 'utf8')) id, _, pw = str(value, 'utf8').partition(':') elif kind == 'Google' or kind == 'Facebook': xtra = request.headers['X-Requested-With'] # elif kind == 'Token': except (KeyError, base64.binascii.Error) as ex: # print(type(ex)) return fn(*args, **kwargs) # If there was an Auth header, autheticate with that info, # and create a session. if kind == 'Basic': with db_session: user = select(u for u in User if u.email == id or u.username == id)[:] if len(user) == 1: if Password.verify(pw, user[0].password): sessionize(user=user[0].to_dict()) else: session.clear() elif not user: with db_session: user = User(email=id, password=pw) sessionize(user=user.to_dict()) else: session.clear() elif kind in ('Google', 'Facebook') and xtra == 'Fetch': kind = kind.lower() sec = client_secrets[kind]['web'] sec['provider'] = kind sec['token'] = value try: value = oauth.upgrade_token(**sec) ouser = oauth.get_user(provider=kind, **value) print(ouser) with db_session: user_oauth = select(o for o in OAuth if o.puid == ouser['id'])[:] if len(user_oauth) == 1: print(user_oauth[0].user) user = user_oauth[0].user.to_dict( ('password', 'oauth')) try: user['picture'] =\ ouser['picture']['data']['url'] except TypeError as ex: user['picture'] = ouser.get('picture', '') sessionize(user=user) elif not user_oauth: # with db_session: user = User(name=ouser.get('name')) user_oauth = OAuth( provider=kind, puid=ouser.get('id'), access_token=value.get('access_token', ''), refresh_token=value.get('refresh_token', ''), user=user) commit() user = user.to_dict(('password', 'oauth')) try: user['picture'] =\ ouser['picture']['data']['url'] except TypeError as ex: user['picture'] = ouser.get('picture', '') sessionize(user=user) except oauth.HTTPError as ex: abort(make_response(ex.text, ex.status_code)) elif kind is not None: # An unknown kind or kind 'None' session.clear() return fn(*args, **kwargs)