Ejemplo n.º 1
0
def test_sqla_delete_token(app, db, blueprint, request):
    class OAuth(OAuthConsumerMixin, db.Model):
        pass

    blueprint.storage = SQLAlchemyStorage(OAuth, db.session)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # Create an existing OAuth token for the service
    existing = OAuth(
        provider="test-service",
        token={
            "access_token": "something",
            "token_type": "bearer",
            "scope": ["blah"],
        },
    )
    db.session.add(existing)
    db.session.commit()
    assert len(OAuth.query.all()) == 1

    assert blueprint.token == {
        "access_token": "something",
        "token_type": "bearer",
        "scope": ["blah"],
    }
    del blueprint.token
    assert blueprint.token == None
    assert len(OAuth.query.all()) == 0
Ejemplo n.º 2
0
def setup_db(app, blueprint, database_path=database_path):
    app.config['SQLALCHEMY_DATABASE_URI'] = database_path
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
    db.app = app
    db.init_app(app)
    migrate = Migrate(app, db)
    print(blueprint)
    blueprint.storage = SQLAlchemyStorage(OAuth, db.session)
Ejemplo n.º 3
0
def test_sqla_storage(app, db, blueprint, request):
    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))

    class OAuth(OAuthConsumerMixin, db.Model):
        user_id = db.Column(db.Integer, db.ForeignKey(User.id))
        user = db.relationship(User)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # for now, we'll assume that Alice is the only user
    alice = User(name="Alice")
    db.session.add(alice)
    db.session.commit()
    # load alice's ID -- this issues a database query
    alice.id

    blueprint.storage = SQLAlchemyStorage(OAuth, db.session, user=alice)

    with record_queries(db.engine) as queries:
        with app.test_client() as client:
            # reset the session before the request
            with client.session_transaction() as sess:
                sess["test-service_oauth_state"] = "random-string"
            # make the request
            resp = client.get(
                "/login/test-service/authorized?code=secret-code&state=random-string",
                base_url="https://a.b.c",
            )
            # check that we redirected the client
            assert resp.status_code == 302
            assert resp.headers["Location"] in (
                "https://a.b.c/oauth_done",
                "/oauth_done",
            )

    assert len(queries) == 3

    # check the database
    alice = User.query.first()
    authorizations = OAuth.query.all()
    assert len(authorizations) == 1
    oauth = authorizations[0]
    assert oauth.user_id == alice.id
    assert oauth.provider == "test-service"
    assert isinstance(oauth.token, dict)
    assert oauth.token == {
        "access_token": "foobar",
        "token_type": "bearer",
        "scope": [""],
    }
Ejemplo n.º 4
0
def test_sqla_overwrite_token(app, db, blueprint, request):
    class OAuth(OAuthConsumerMixin, db.Model):
        pass

    blueprint.storage = SQLAlchemyStorage(OAuth, db.session)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # Create an existing OAuth token for the service
    existing = OAuth(
        provider="test-service",
        token={
            "access_token": "something",
            "token_type": "bearer",
            "scope": ["blah"]
        },
    )
    db.session.add(existing)
    db.session.commit()
    assert len(OAuth.query.all()) == 1

    with record_queries(db.engine) as queries:
        with app.test_client() as client:
            # reset the session before the request
            with client.session_transaction() as sess:
                sess["test-service_oauth_state"] = "random-string"
            # make the request
            resp = client.get(
                "/login/test-service/authorized?code=secret-code&state=random-string",
                base_url="https://a.b.c",
            )
            # check that we redirected the client
            assert resp.status_code == 302
            assert resp.headers["Location"] in (
                "https://a.b.c/oauth_done",
                "/oauth_done",
            )

    assert len(queries) == 2

    # check that the database record was overwritten
    authorizations = OAuth.query.all()
    assert len(authorizations) == 1
    oauth = authorizations[0]
    assert oauth.provider == "test-service"
    assert isinstance(oauth.token, dict)
    assert oauth.token == {
        "access_token": "foobar",
        "token_type": "bearer",
        "scope": [""],
    }
Ejemplo n.º 5
0
def test_sqla_flask_login_misconfigured(app, db, blueprint, request):
    login_manager = LoginManager(app)

    class User(db.Model, UserMixin):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))

    class OAuth(OAuthConsumerMixin, db.Model):
        user_id = db.Column(db.Integer, db.ForeignKey(User.id))
        user = db.relationship(User)

    blueprint.storage = SQLAlchemyStorage(OAuth, db.session, user=current_user)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # configure login manager
    @login_manager.user_loader
    def load_user(userid):
        return User.query.get(userid)

    calls = []

    def callback(*args, **kwargs):
        calls.append((args, kwargs))

    oauth_error.connect(callback)
    request.addfinalizer(lambda: oauth_error.disconnect(callback))

    with app.test_client() as client:
        # reset the session before the request
        with client.session_transaction() as sess:
            sess["test-service_oauth_state"] = "random-string"
        # make the request
        resp = client.get(
            "/login/test-service/authorized?code=secret-code&state=random-string",
            base_url="https://a.b.c",
        )
        # check that we redirected the client
        assert resp.status_code == 302
        assert resp.headers["Location"] in ("https://a.b.c/oauth_done",
                                            "/oauth_done")

    assert len(calls) == 1
    assert calls[0][0] == (blueprint, )
    error = calls[0][1]["error"]
    assert isinstance(error, ValueError)
    assert str(error) == "Cannot set OAuth token without an associated user"
    def __init__(self, name, import_name, db_session, user_model, token_model,
                 final_redirect_view):
        """
        :param db_session: SQLAlchemy session object
        :param user_model: User model class;
            this should be a flask_login.UserMixin or similar
        :param token_model: Token model class;
            this should be a hydra_oauth2.HydraTokenMixin or similar
        :param final_redirect_view: the endpoint to which to redirect the user
            after login/logout has been completed
        """
        super().__init__(
            name,
            import_name,
            login_url='/login',
            authorized_url='/authorized',
            redirect_to=final_redirect_view,
            storage=SQLAlchemyStorage(token_model,
                                      db_session,
                                      user=current_user),

            # hack to disable SSL certificate verification in a dev environment:
            # this is a sneaky way to make flask-dance set the 'verify' kwarg for
            # requests calls made when fetching tokens; it's not the intended use
            # of token_url_params, but hey-ho
            token_url_params={'verify': get_env() != 'development'},
        )

        self.db_session = db_session
        self.user_model = user_model
        self.token_model = token_model

        self.hydra_public_url = None
        self.userinfo_url = None
        self.logout_url = None

        self.from_config['hydra_public_url'] = 'HYDRA_PUBLIC_URL'
        self.from_config['client_id'] = 'OAUTH2_CLIENT_ID'
        self.from_config['client_secret'] = 'OAUTH2_CLIENT_SECRET'
        self.from_config['scope'] = 'OAUTH2_SCOPES'
        self.from_config['audience'] = 'OAUTH2_AUDIENCE'

        self.add_url_rule('/signup', view_func=self.signup)
        self.add_url_rule('/logout', view_func=self.logout)
        self.add_url_rule('/logged_out', view_func=self.logged_out)

        oauth_authorized.connect(self.hydra_logged_in, sender=self)
        oauth_error.connect(self.hydra_error, sender=self)

        self.create_or_update_local_user = None
Ejemplo n.º 7
0
def test_sqla_flask_login_no_user_required(app, db, blueprint, request):
    # need a URL to hit, so that tokens will be loaded, but result is irrelevant
    responses.add(
        responses.GET,
        "https://example.com/noop",
    )

    login_manager = LoginManager(app)

    class User(db.Model, UserMixin):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))

    class OAuth(OAuthConsumerMixin, db.Model):
        user_id = db.Column(db.Integer, db.ForeignKey(User.id))
        user = db.relationship(User)

    blueprint.storage = SQLAlchemyStorage(
        OAuth,
        db.session,
        user=current_user,
        user_required=False,
    )

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # configure login manager
    @login_manager.user_loader
    def load_user(userid):
        return User.query.get(userid)

    # create a simple view
    @app.route("/")
    def index():
        return "success"

    with app.test_request_context("/"):
        # no one is logged in -- this is an anonymous user
        logout_user()
        # this should *not* raise an error
        blueprint.session.get("/noop")
        assert blueprint.session.token == None
Ejemplo n.º 8
0
 def __init__(self, *args, **kwargs):
     super().__init__(
         base_url="https://api.github.com/",
         authorization_url="https://github.com/login/oauth/authorize",
         token_url="https://github.com/login/oauth/access_token",
         session_class=GitHubSession,
         storage=SQLAlchemyStorage(OAuth,
                                   db.session,
                                   user=current_user,
                                   user_required=False,
                                   cache=cache),
         *args,
         **kwargs,
     )
     self.from_config.update({
         "client_id": "GITHUB_OAUTH_CLIENT_ID",
         "client_secret": "GITHUB_OAUTH_CLIENT_SECRET",
         "scope": "GITHUB_SCOPE",
         "members_team_id": "GITHUB_MEMBERS_TEAM_ID",
         "roadies_team_id": "GITHUB_ROADIES_TEAM_ID",
         "admin_access_token": "GITHUB_ADMIN_TOKEN",
         "org_id": "GITHUB_ORG_ID",
     })
Ejemplo n.º 9
0
def test_sqla_flask_login_preload_logged_in_user(app, db, blueprint, request):
    # need a URL to hit, so that tokens will be loaded, but result is irrelevant
    responses.add(
        responses.GET,
        "https://example.com/noop",
    )

    login_manager = LoginManager(app)

    class User(db.Model, UserMixin):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))

    class OAuth(OAuthConsumerMixin, db.Model):
        user_id = db.Column(db.Integer, db.ForeignKey(User.id))
        user = db.relationship(User)

    blueprint.storage = SQLAlchemyStorage(OAuth, db.session, user=current_user)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # create some users, and tokens for some of them
    alice = User(name="Alice")
    alice_token = {"access_token": "alice123", "token_type": "bearer"}
    alice_oauth = OAuth(user=alice, token=alice_token, provider="test-service")
    bob = User(name="Bob")
    bob_token = {"access_token": "bob456", "token_type": "bearer"}
    bob_oauth = OAuth(user=bob, token=bob_token, provider="test-service")
    chuck = User(name="Chuck")
    # chuck doesn't get a token
    db.session.add_all([alice, alice_oauth, bob, bob_oauth, chuck])
    db.session.commit()

    # configure login manager
    @login_manager.user_loader
    def load_user(userid):
        return User.query.get(userid)

    # create a simple view
    @app.route("/")
    def index():
        return "success"

    with app.test_request_context("/"):
        login_user(alice)
        # hit /noop to load tokens
        blueprint.session.get("/noop")
        # now the flask-dance session should have Alice's token loaded
        assert blueprint.session.token == alice_token

    with app.test_request_context("/"):
        # set bob as the logged in user
        login_user(bob)
        # hit /noop to load tokens
        blueprint.session.get("/noop")
        # now the flask-dance session should have Bob's token loaded
        assert blueprint.session.token == bob_token

    with app.test_request_context("/"):
        # now let's try chuck
        login_user(chuck)
        blueprint.session.get("/noop")
        assert blueprint.session.token == None

    with app.test_request_context("/"):
        # no one is logged in -- this is an anonymous user
        logout_user()
        with pytest.raises(ValueError):
            blueprint.session.get("/noop")
Ejemplo n.º 10
0
def test_sqla_flask_login_anon_to_authed(app, db, blueprint, request):
    login_manager = LoginManager(app)

    class User(db.Model, UserMixin):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))

    class OAuth(OAuthConsumerMixin, db.Model):
        user_id = db.Column(db.Integer, db.ForeignKey(User.id))
        user = db.relationship(User)

    blueprint.storage = SQLAlchemyStorage(OAuth, db.session, user=current_user)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # configure login manager
    @login_manager.user_loader
    def load_user(userid):
        return User.query.get(userid)

    # create a user object when OAuth succeeds
    def logged_in(sender, token):
        assert token
        assert blueprint == sender
        resp = sender.session.get("/user")
        user = User(name=resp.json()["name"])
        login_user(user)
        db.session.add(user)
        db.session.commit()
        flask.flash("Signed in successfully")

    oauth_authorized.connect(logged_in, blueprint)
    request.addfinalizer(
        lambda: oauth_authorized.disconnect(logged_in, blueprint))

    # mock out the `/user` API call
    responses.add(
        responses.GET,
        "https://example.com/user",
        body='{"name":"josephine"}',
    )

    with record_queries(db.engine) as queries:
        with app.test_client() as client:
            with client.session_transaction() as sess:
                sess["test-service_oauth_state"] = "random-string"
            # make the request
            resp = client.get(
                "/login/test-service/authorized?code=secret-code&state=random-string",
                base_url="https://a.b.c",
            )
            # check that we redirected the client
            assert resp.status_code == 302
            assert resp.headers["Location"] == "https://a.b.c/oauth_done"

    assert len(queries) == 5

    # check the database
    users = User.query.all()
    assert len(users) == 1
    user = users[0]
    assert user.name == "josephine"

    authorizations = OAuth.query.all()
    assert len(authorizations) == 1
    oauth = authorizations[0]
    assert oauth.provider == "test-service"
    assert oauth.token == {
        "access_token": "foobar",
        "token_type": "bearer",
        "scope": [""],
    }
    assert oauth.user_id == user.id
Ejemplo n.º 11
0
def test_sqla_flask_login(app, db, blueprint, request):
    login_manager = LoginManager(app)

    class User(db.Model, UserMixin):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))

    class OAuth(OAuthConsumerMixin, db.Model):
        user_id = db.Column(db.Integer, db.ForeignKey(User.id))
        user = db.relationship(User)

    blueprint.storage = SQLAlchemyStorage(OAuth, db.session, user=current_user)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # create some users
    u1 = User(name="Alice")
    u2 = User(name="Bob")
    u3 = User(name="Chuck")
    db.session.add_all([u1, u2, u3])
    db.session.commit()

    # configure login manager
    @login_manager.user_loader
    def load_user(userid):
        return User.query.get(userid)

    with record_queries(db.engine) as queries:
        with app.test_client() as client:
            # reset the session before the request
            with client.session_transaction() as sess:
                sess["test-service_oauth_state"] = "random-string"
                # set alice as the logged in user
                sess["user_id"] = u1.id
            # make the request
            resp = client.get(
                "/login/test-service/authorized?code=secret-code&state=random-string",
                base_url="https://a.b.c",
            )
            # check that we redirected the client
            assert resp.status_code == 302
            assert resp.headers["Location"] == "https://a.b.c/oauth_done"

    assert len(queries) == 4

    # lets do it again, with Bob as the logged in user -- he gets a different token
    responses.reset()
    responses.add(
        responses.POST,
        "https://example.com/oauth/access_token",
        body='{"access_token":"abcdef","token_type":"bearer","scope":"bob"}',
    )
    with record_queries(db.engine) as queries:
        with app.test_client() as client:
            # reset the session before the request
            with client.session_transaction() as sess:
                sess["test-service_oauth_state"] = "random-string"
                # set bob as the logged in user
                sess["user_id"] = u2.id
            # make the request
            resp = client.get(
                "/login/test-service/authorized?code=secret-code&state=random-string",
                base_url="https://a.b.c",
            )
            # check that we redirected the client
            assert resp.status_code == 302
            assert resp.headers["Location"] == "https://a.b.c/oauth_done"

    assert len(queries) == 4

    # check the database
    authorizations = OAuth.query.all()
    assert len(authorizations) == 2
    u1_oauth = OAuth.query.filter_by(user=u1).one()
    assert u1_oauth.provider == "test-service"
    assert u1_oauth.token == {
        "access_token": "foobar",
        "token_type": "bearer",
        "scope": [""],
    }
    u2_oauth = OAuth.query.filter_by(user=u2).one()
    assert u2_oauth.provider == "test-service"
    assert u2_oauth.token == {
        "access_token": "abcdef",
        "token_type": "bearer",
        "scope": ["bob"],
    }
    u3_oauth = OAuth.query.filter_by(user=u3).all()
    assert len(u3_oauth) == 0
Ejemplo n.º 12
0
def test_sqla_load_token_for_user(app, db, blueprint, request):
    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))

    class OAuth(OAuthConsumerMixin, db.Model):
        user_id = db.Column(db.Integer, db.ForeignKey(User.id))
        user = db.relationship(User)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    # set token storage
    blueprint.storage = SQLAlchemyStorage(OAuth, db.session)

    # make users and OAuth tokens for several people
    alice = User(name="Alice")
    alice_token = {"access_token": "alice123", "token_type": "bearer"}
    alice_oauth = OAuth(user=alice, token=alice_token, provider="test-service")
    bob = User(name="Bob")
    bob_token = {"access_token": "bob456", "token_type": "bearer"}
    bob_oauth = OAuth(user=bob, token=bob_token, provider="test-service")
    sue = User(name="Sue")
    sue_token = {"access_token": "sue789", "token_type": "bearer"}
    sue_oauth = OAuth(user=sue, token=sue_token, provider="test-service")
    db.session.add_all([alice, bob, sue, alice_oauth, bob_oauth, sue_oauth])
    db.session.commit()

    # by default, we should not have a token for anyone
    sess = blueprint.session
    assert not sess.token
    assert not blueprint.token

    # load token for various users
    blueprint.config["user"] = alice
    assert sess.token == alice_token
    assert blueprint.token == alice_token

    blueprint.config["user"] = bob
    assert sess.token == bob_token
    assert blueprint.token == bob_token

    blueprint.config["user"] = alice
    assert sess.token == alice_token
    assert blueprint.token == alice_token

    blueprint.config["user"] = sue
    assert sess.token == sue_token
    assert blueprint.token == sue_token

    # load for user ID as well
    del blueprint.config["user"]
    blueprint.config["user_id"] = bob.id
    assert sess.token == bob_token
    assert blueprint.token == bob_token

    # try deleting user tokens
    del blueprint.token
    assert sess.token == None
    assert blueprint.token == None

    # shouldn't affect alice's token
    blueprint.config["user_id"] = alice.id
    assert sess.token == alice_token
    assert blueprint.token == alice_token
Ejemplo n.º 13
0
from flask import flash, redirect
from flask_login import current_user, login_user
from flask_dance.contrib.facebook import make_facebook_blueprint
from flask_dance.contrib.github import make_github_blueprint, github
from flask_dance.consumer import oauth_authorized, oauth_error
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
from sqlalchemy.orm.exc import NoResultFound
from .models import db, User, OAuth, Token
import uuid

blueprint = make_facebook_blueprint(storage=SQLAlchemyStorage(
    OAuth, db.session, user=current_user),
                                    scope="email")

github_blueprint = make_github_blueprint(
    storage=SQLAlchemyStorage(OAuth, db.session, user=current_user))


# create/login local user on successful OAuth login
@oauth_authorized.connect_via(github_blueprint)
def github_logged_in(github_blueprint, token):
    if not token:
        flash("Failed to log in.", category="error")
        return False

    resp = github_blueprint.session.get("/user")
    if not resp.ok:
        msg = "Failed to fetch user info."
        flash(msg, category="error")
        return False
Ejemplo n.º 14
0
from flask import flash, redirect
from flask_login import current_user, login_user
from flask_dance.contrib.facebook import make_facebook_blueprint
from flask_dance.consumer import oauth_authorized, oauth_error
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
from sqlalchemy.orm.exc import NoResultFound
from .models import db, Users, OAuth, Token
import uuid


blueprint = make_facebook_blueprint(
    storage=SQLAlchemyStorage(OAuth, db.session, user=current_user), scope="email"
)


# create/login local user on successful OAuth login
@oauth_authorized.connect_via(blueprint)
def facebook_logged_in(blueprint, token):
    if not token:
        flash("Failed to log in.", category="error")
        return False

    resp = blueprint.session.get("/me?fields=name,email")
    if not resp.ok:
        msg = "Failed to fetch user info."
        flash(msg, category="error")
        return False

    info = resp.json()
    user_id = info["id"]
Ejemplo n.º 15
0
from flask_dance.contrib import github
from flask_dance.contrib.github import make_github_blueprint
from flask_login import current_user
from app import db
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
from app.models import OAuth

github_blueprint = make_github_blueprint(client_id='XXXX',
                                         client_secret='XXXXXXXXXXXXXXX')

github_blueprint.storage = SQLAlchemyStorage(OAuth, db.session)

from app.github import views
Ejemplo n.º 16
0
from flask import Flask, redirect, url_for
from flask_dance.contrib.facebook import make_facebook_blueprint, facebook
from flask_login import login_user, current_user
from flask_dance.consumer.storage.sqla import OAuthConsumerMixin, SQLAlchemyStorage
from flask_dance.consumer import oauth_authorized
from sqlalchemy.orm.exc import NoResultFound
from quandromy.database import OAuth
from quandromy import db

facebook_blueprint = make_facebook_blueprint()

facebook_blueprint.storage = SQLAlchemyStorage(OAuth,
                                               db.session,
                                               user=current_user)


@oauth_authorized.connect_via(facebook_blueprint)
def facebook_logged_in(blueprint, token):

    account_info = blueprint.session.get('/me')

    if account_info.ok:
        account_info_json = account_info.json()
        username = account_info_json['name']

        query = User.query.filter_by(username=username)

        try:
            user = query.one()
        except NoResultFound:
            user = User(username=username)
Ejemplo n.º 17
0
#!/usr/bin/env python2
from flask import flash
from flask_login import current_user, login_user
from flask_dance.contrib.github import make_github_blueprint
from flask_dance.consumer import oauth_authorized, oauth_error
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
from sqlalchemy.orm.exc import NoResultFound
from models import db, User, OAuth

blueprint = make_github_blueprint(
    storage=SQLAlchemyStorage(OAuth, db.session, user=current_user))


# create/login local user on successful OAuth login
@oauth_authorized.connect_via(blueprint)
def github_logged_in(blueprint, token):
    if not token:
        flash("Failed to log in.", category="error")
        return False

    resp = blueprint.session.get("/user")
    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,
Ejemplo n.º 18
0
def test_sqla_cache(app, db, blueprint, request):
    cache = Cache(app)

    class OAuth(OAuthConsumerMixin, db.Model):
        pass

    blueprint.storage = SQLAlchemyStorage(OAuth, db.session, cache=cache)

    db.create_all()

    def done():
        db.session.remove()
        db.drop_all()

    request.addfinalizer(done)

    with record_queries(db.engine) as queries:
        with app.test_client() as client:
            # reset the session before the request
            with client.session_transaction() as sess:
                sess["test-service_oauth_state"] = "random-string"
            # make the request
            resp = client.get(
                "/login/test-service/authorized?code=secret-code&state=random-string",
                base_url="https://a.b.c",
            )
            # check that we redirected the client
            assert resp.status_code == 302
            assert resp.headers["Location"] == "https://a.b.c/oauth_done"

    assert len(queries) == 2

    expected_token = {
        "access_token": "foobar",
        "token_type": "bearer",
        "scope": [""],
    }

    # check the database
    authorizations = OAuth.query.all()
    assert len(authorizations) == 1
    oauth = authorizations[0]
    assert oauth.provider == "test-service"
    assert isinstance(oauth.token, dict)
    assert oauth.token == expected_token

    # cache should be invalidated
    assert cache.get("flask_dance_token|test-service|None") is None

    # first reference to the token should generate SQL queries
    with record_queries(db.engine) as queries:
        assert blueprint.token == expected_token
    assert len(queries) == 1

    # should now be in the cache
    assert cache.get("flask_dance_token|test-service|None") == expected_token

    # subsequent references should not generate SQL queries
    with record_queries(db.engine) as queries:
        assert blueprint.token == expected_token
    assert len(queries) == 0
Ejemplo n.º 19
0
    def __init__(self, app):
        authorization = {
            'Authorization': 'Bot {}'.format(app.config['DISCORD_BOT_TOKEN'])
        }
        blueprint = make_discord_blueprint(
            app.config['DISCORD_CLIENT_ID'],
            app.config['DISCORD_CLIENT_SECRET'], ['guilds.join', 'identify'],
            redirect_to='account_discord',
            login_url='/discord/login',
            storage=SQLAlchemyStorage(OAuth, db.session, user=current_user))
        app.register_blueprint(blueprint)

        @app.route('/discord', methods=['GET', 'POST'])
        @login_required
        @AuthController.instance.authorize.in_group('residents')
        def account_discord():
            if request.method == 'POST':
                if '_method' in request.form and request.form['_method'] in [
                        'PUT', 'DELETE'
                ]:
                    if request.form['_method'] == 'PUT':
                        join_guild()
                    elif request.form['_method'] == 'DELETE':
                        r = discord.post(
                            "/api/oauth2/token/revoke",
                            data={
                                'client_id':
                                app.config['DISCORD_CLIENT_ID'],
                                'client_secret':
                                app.config['DISCORD_CLIENT_SECRET'],
                                'token':
                                blueprint.token['access_token']
                            },
                            headers={
                                "Content-Type":
                                "application/x-www-form-urlencoded"
                            })
                        if r.status_code == 200:
                            r = delete('{}{}/members/{}'.format(
                                GUILDS_API,
                                app.config['DISCORD_VERIFICATION_GUILD'],
                                current_user.discord_id),
                                       headers=authorization)
                        if r.status_code == 204:
                            current_user.discord_id = None
                            current_user.discord_username = None
                            current_user.discord_discriminator = None
                            db.session.commit()
                            flash(
                                'Your Discord account has been disconnected successfully. To regain access to the '
                                'Next House Discord server, please connect another account.',
                                FLASH_SUCCESS)
                        else:
                            flash(
                                'An error occurred while disconnecting your Discord account. Please wait a bit and '
                                'try again later. If this issue persists, please contact '
                                '<a href="mailto:[email protected]">[email protected]</a> for assistance.',
                                FLASH_ERROR)
                        del blueprint.token
                else:
                    flash(
                        'The server received an invalid request. Please wait a bit and try again later. If this '
                        'issue persists, please contact '
                        '<a href="mailto:[email protected]">[email protected]</a> for assistance.',
                        FLASH_ERROR)
            return render_template('discord.html',
                                   authorized=discord.authorized)

        @oauth_authorized.connect_via(blueprint)
        def handle_authorized(_, token):
            join_guild()

        def join_guild():
            user = discord.get('/api/users/@me').json()

            if not current_user.discord_id:
                current_user.discord_id = user['id']
            elif current_user.discord_id != user['id']:
                flash(
                    'You re-authenticated with a Discord account different from the account linked to your account. '
                    'To connect a different account, disconnect your existing account first.',
                    FLASH_ERROR)
                return

            current_user.discord_username = user['username']
            current_user.discord_discriminator = user['discriminator']
            db.session.commit()
            r = put('https://discordapp.com/api/guilds/{}/members/{}'.format(
                app.config['DISCORD_VERIFICATION_GUILD'], user['id']),
                    json={
                        'access_token': discord.access_token,
                        'roles': [app.config['DISCORD_VERIFICATION_ROLE']],
                        'nick': current_user.kerberos
                    },
                    headers=authorization)
            if r.status_code == 204:
                r = put(
                    'https://discordapp.com/api/guilds/{}/members/{}/roles/{}'.
                    format(app.config['DISCORD_VERIFICATION_GUILD'],
                           user['id'],
                           app.config['DISCORD_VERIFICATION_ROLE']),
                    headers=authorization)
            if r.status_code not in [201, 204]:
                flash(
                    'There was an error granting you access to the Discord server. Please wait a bit and '
                    'click the "Rejoin" button below to try again. If this issue persists, please contact '
                    '<a href="mailto:[email protected]">[email protected]</a> for assistance.',
                    FLASH_ERROR)
                return
            flash(
                'Success! You now have access to the Next House Discord server.',
                FLASH_SUCCESS)
            return
Ejemplo n.º 20
0
from flask import flash
from flask_login import current_user, login_user
from flask_dance.contrib.twitter import make_twitter_blueprint
from flask_dance.consumer import oauth_authorized, oauth_error
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
from sqlalchemy.orm.exc import NoResultFound
from .models import db, User, OAuth

blueprint = make_twitter_blueprint(storage=SQLAlchemyStorage(
    OAuth, db.session, user=current_user),
                                   redirect_to='tweet_page')


# create/login local user on successful OAuth login
@oauth_authorized.connect_via(blueprint)
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(
Ejemplo n.º 21
0
from flask_dance.consumer import OAuth2ConsumerBlueprint, oauth_authorized
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
from flask_login import current_user, login_user
from sqlalchemy.orm.exc import NoResultFound

from afidsvalidator.model import db, OAuth, User

orcid_blueprint = OAuth2ConsumerBlueprint(
    "orcid",
    __name__,
    base_url="https://api.orcid.org/v3.0",
    token_url="https://orcid.org/oauth/token",
    authorization_url="https://orcid.org/oauth/authorize",
    storage=SQLAlchemyStorage(OAuth,
                              db.session,
                              user=current_user,
                              user_required=True),
    scope="openid",
)
orcid_blueprint.from_config["client_id"] = "ORCID_OAUTH_CLIENT_ID"
orcid_blueprint.from_config["client_secret"] = "ORCID_OAUTH_CLIENT_SECRET"


@oauth_authorized.connect_via(orcid_blueprint)
def orcid_logged_in(blueprint, token):
    """Create/login user on successful ORCID login."""
    if not token:
        return False

    orcid_id = token["orcid"]
Ejemplo n.º 22
0
from flask_dance.contrib.github import make_github_blueprint
from flask_dance.contrib.jira import make_jira_blueprint

from openedx_webhooks import db
from openedx_webhooks.models import OAuth

## JIRA ##

jira_bp = make_jira_blueprint(
    # this *should* pick up the client_key and rsa_key from app.config,
    # but it doesn't seem to be doing so... :(
    consumer_key=os.environ.get("JIRA_OAUTH_CONSUMER_KEY"),
    rsa_key=os.environ.get("JIRA_OAUTH_RSA_KEY"),
    # these are actually necessary
    base_url="https://openedx.atlassian.net",
    storage=SQLAlchemyStorage(OAuth, db.session),
)


@oauth_authorized.connect_via(jira_bp)
def jira_logged_in(blueprint, token):
    if token:
        flash("Successfully signed in with JIRA")
    else:
        flash("You denied the request to sign in with JIRA")


@oauth_error.connect_via(jira_bp)
def jira_error(blueprint, message, response=None):
    flash(message, category="error")
Ejemplo n.º 23
0
    pr_count = db.Column(db.Integer, default=0)
    commit_count = db.Column(db.Integer, default=0)
    pr_open = db.Column(db.Integer, default=0)
    line_add = db.Column(db.Integer, default=0)
    line_delete = db.Column(db.Integer, default=0)

    def __init__(self, username, name, user_link):
        self.username = username
        self.name = name
        self.user_link = user_link

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

github_bp.backend = SQLAlchemyStorage(OAuth, db.session, user=current_user, user_required=False)

print(__name__=="__main__")

message = ['event has started', 'main-stream projects']

@app.route("/")
def home():
    return render_template("index.html", data=current_user, msg = message)

# stats routes 
@app.route("/stats")
def stats():
    all_info = userInfo.query.order_by(desc(userInfo.pr_count)).all()
    return render_template("stats.html", data=current_user, info=all_info, ignoreList=ignoreList)
Ejemplo n.º 24
0
from backend.dao.postgres_db import DBSession
from backend.util.response.error import ErrorResponse
from backend.util.safe_url import is_safe_url
from backend.controller import ErrorHandler

bplogin = make_google_blueprint(
    login_url="google_login",
    client_id=os.getenv("OAUTH_CLIENT_ID"),
    client_secret=os.getenv("OAUTH_CLIENT_SECRET"),
    scope=[
        "https://www.googleapis.com/auth/userinfo.profile",
        "https://www.googleapis.com/auth/userinfo.email", "openid"
    ],
    offline=True,
    redirect_url="",
    storage=SQLAlchemyStorage(OAuth, DBSession(), user=current_user))


@oauth_authorized.connect_via(bplogin)
def user_logged_in(blueprint, token):
    if not token:
        return redirect(url_for("frontend.index", error="token"))
    else:
        response = blueprint.session.get("/oauth2/v1/userinfo")

        if not response.ok:
            return redirect(url_for("frontend.index", error="error"))
        else:
            try:
                user_service = UserService()
Ejemplo n.º 25
0
    def __repr__(self):
        return "PropertyItem('{self.title},{self.date_posted}')".format(self)

    @property
    def serialize(self):
        """Return object data in easily serializeable format"""
        return {
            'id': self.id,
            'property_type': self.property_type.type,
            'title': self.title,
            'date_posted': self.date_posted,
            'description': self.description,
            'rent': self.rent,
            'rooms': self.rooms,
            'size': self.size,
        }


# Google OAuth blueprint
google_blueprint = make_google_blueprint(scope=[
    "openid", "https://www.googleapis.com/auth/userinfo.profile",
    "https://www.googleapis.com/auth/userinfo.email"
])

app.register_blueprint(google_blueprint, url_prefix="/google_login")
google_blueprint.storage = SQLAlchemyStorage(OAuth,
                                             db.session,
                                             user=current_user,
                                             user_required=False)
Ejemplo n.º 26
0
class MyModelView(ModelView):
    def is_accessible(self):
        return current_user.is_authenticated


class OAuth(OAuthConsumerMixin, db.Model):
    """ Flask Dance OAUTH table """
    user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    user = db.relationship(User)


from flask_dance.contrib.twitter import make_twitter_blueprint, twitter
from flask_dance.contrib.google import make_google_blueprint, google

twitter_blueprint.storage = SQLAlchemyStorage(OAuth,
                                              db.session,
                                              user=current_user)

google_blueprint.storage = SQLAlchemyStorage(OAuth,
                                             db.session,
                                             user=current_user)


class Bar(db.Model):
    """Bars Profile Table"""

    __tablename__ = 'bars'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    bar_name = db.Column(db.String(100), nullable=False, unique=False)
    address = db.Column(db.String(100), nullable=False, unique=True)
Ejemplo n.º 27
0
from flask_dance.contrib.google import make_google_blueprint
from flask_login import LoginManager, current_user, login_user
from flask import current_app, flash
from sqlalchemy.orm.exc import NoResultFound

from .models import User, OAuth, db
from .. import app

google_blueprint = make_google_blueprint(
    client_id=current_app.config["GOOGLE_CLIENT_ID"],
    client_secret=current_app.config["GOOGLE_CLIENT_SECRET"],
    scope=["profile", "email"],
)

google_blueprint.backend = SQLAlchemyStorage(OAuth,
                                             db.session,
                                             user=current_user)

app.register_blueprint(google_blueprint, url_prefix="/login")

login_manager = LoginManager()
login_manager.login_view = "google.login"


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)


@oauth_authorized.connect_via(google_blueprint)
def google_logged_in(blueprint, token):
Ejemplo n.º 28
0
def load_user(user_id):
    twitter_blueprint.storage = SQLAlchemyStorage(OAuth, db.session)
    return User.query.get(int(user_id))
Ejemplo n.º 29
0
github_blueprint = make_github_blueprint(client_id = 'YOUR CLIENT ID', client_secret = 'YOUR CLIENT SECRET')

google_blueprint = make_google_blueprint(client_id= "YOUR CLIENT ID", client_secret= "YOUR CLIENT SECRET",  scope=[
        "openid",
        "https://www.googleapis.com/auth/userinfo.email",
        "https://www.googleapis.com/auth/userinfo.profile",
    ]
)

facebook_blueprint = make_facebook_blueprint(client_id= "YOUR CLIENT ID", client_secret= "YOUR CLIENT SECRET", scope = [
    "email"
    ]
)

github_bp = make_github_blueprint(storage = SQLAlchemyStorage(OAuth, db.session, user = current_user))

google_bp = make_google_blueprint(storage = SQLAlchemyStorage(OAuth, db.session, user = current_user))

facebook_bp = make_facebook_blueprint(storage = SQLAlchemyStorage(OAuth, db.session, user = current_user))

@oauth_authorized.connect_via(github_blueprint)
def github_logged_in(blueprint, token):
    if not token:
        flash("Failed to log in with GitHub.", category = "error")
        return
    resp = blueprint.session.get("/user")
    if not resp.ok:
        msg = "Failed to fecth user info from GitHub."
        flash(msg, category= "error")
        return
Ejemplo n.º 30
0
# conn = psycopg2.connect(os.environ.get('DATABASE_URL'), sslmode='require')
sqldb.init_app(app)
login_manager = LoginManager(app)
dbInterface = Database(current_user)
migrate = Migrate(app, sqldb, render_as_batch=True)
manager = Manager(app)
manager.add_command('db', MigrateCommand)

scope = "user-read-recently-played"
blueprint = make_spotify_blueprint(
    client_id=os.environ.get('SPOTIPY_CLIENT_ID'),
    client_secret=os.environ.get('SPOTIPY_CLIENT_SECRET'),
    scope=["user-read-recently-played", "user-read-email", "user-top-read"],
    redirect_url="/discover",
    storage=SQLAlchemyStorage(OAuth,
                              sqldb.session,
                              user=current_user,
                              user_required=False))
app.register_blueprint(blueprint=blueprint, url_prefix='/log_in')

SEASONS = {
    1: 'Winter',
    2: 'Winter',
    3: 'Spring',
    4: 'Spring',
    5: 'Spring',
    6: 'Summer',
    7: 'Summer',
    8: 'Summer',
    9: 'Fall',
    10: 'Fall',
    11: 'Fall',