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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
        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)