Esempio n. 1
0
def test_load_from_config():
    app = Flask(__name__)
    app.secret_key = "anything"
    app.config["DISCORD_OAUTH_CLIENT_ID"] = "foo"
    app.config["DISCORD_OAUTH_CLIENT_SECRET"] = "bar"
    discord_bp = make_discord_blueprint(redirect_to="index")
    app.register_blueprint(discord_bp)

    resp = app.test_client().get("/discord")
    url = resp.headers["Location"]
    client_id = URLObject(url).query.dict.get("client_id")
    assert client_id == "foo"
Esempio n. 2
0
def test_context_local():
    responses.add(responses.GET, "https://google.com")

    # set up two apps with two different set of auth tokens
    app1 = Flask(__name__)
    discord_bp1 = make_discord_blueprint(
        "foo1",
        "bar1",
        redirect_to="url1",
        backend=MemoryBackend({"access_token": "app1"}),
    )
    app1.register_blueprint(discord_bp1)

    app2 = Flask(__name__)
    discord_bp2 = make_discord_blueprint(
        "foo2",
        "bar2",
        redirect_to="url2",
        backend=MemoryBackend({"access_token": "app2"}),
    )
    app2.register_blueprint(discord_bp2)

    # outside of a request context, referencing functions on the `discord` object
    # will raise an exception
    with pytest.raises(RuntimeError):
        discord.get("https://google.com")

    # inside of a request context, `discord` should be a proxy to the correct
    # blueprint session
    with app1.test_request_context("/"):
        app1.preprocess_request()
        discord.get("https://google.com")
        request = responses.calls[0].request
        assert request.headers["Authorization"] == "Bearer app1"

    with app2.test_request_context("/"):
        app2.preprocess_request()
        discord.get("https://google.com")
        request = responses.calls[1].request
        assert request.headers["Authorization"] == "Bearer app2"
Esempio n. 3
0
def test_blueprint_factory():
    discord_bp = make_discord_blueprint(
        client_id="foo",
        client_secret="bar",
        scope=["identify", "email"],
        redirect_to="index",
    )
    assert isinstance(discord_bp, OAuth2ConsumerBlueprint)
    assert discord_bp.session.scope == ["identify", "email"]
    assert discord_bp.session.base_url == "https://discordapp.com/"
    assert discord_bp.session.client_id == "foo"
    assert discord_bp.client_secret == "bar"
    assert discord_bp.authorization_url == "https://discordapp.com/api/oauth2/authorize"
    assert discord_bp.token_url == "https://discordapp.com/api/oauth2/token"
Esempio n. 4
0
def test_blueprint_factory():
    discord_bp = make_discord_blueprint(
        client_id="foo",
        client_secret="bar",
        scope=["identify", "email"],
        redirect_to="index",
    )
    assert isinstance(discord_bp, OAuth2ConsumerBlueprint)
    assert discord_bp.session.scope == ["identify", "email"]
    assert discord_bp.session.base_url == "https://discordapp.com/"
    assert discord_bp.session.client_id == "foo"
    assert discord_bp.client_secret == "bar"
    assert discord_bp.authorization_url == "https://discordapp.com/api/oauth2/authorize"
    assert discord_bp.token_url == "https://discordapp.com/api/oauth2/token"
Esempio n. 5
0
from flask import Flask
from config import Config
from flask_dance.contrib.discord import make_discord_blueprint, discord

app = Flask(__name__)
app.config.from_object(Config)
discord_blueprint = make_discord_blueprint(scope='email')
app.register_blueprint(discord_blueprint, url_prefix='/login')

from app import routes
Esempio n. 6
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
Esempio n. 7
0
from flask import Flask
from config import Config
from flask_dance.contrib.discord import make_discord_blueprint, discord

app = Flask(__name__)
app.config.from_object(Config)
discord_blueprint = make_discord_blueprint(scope=['identify', 'guilds'],
                                           redirect_url='dashboard')
app.register_blueprint(discord_blueprint, url_prefix='/login')

from app import routes
Esempio n. 8
0
    def __init__(self):

        # Set up the app and the database
        self.app = Flask(
            __name__,
            template_folder=TEMPLATES_PATH,
            static_folder=STATIC_PATH,
            static_url_path="/static",
        )
        self.sockets = Sockets(self.app)

        self.db = RethinkDB()
        self.log = logging.getLogger()
        self.app.secret_key = os.environ.get("WEBPAGE_SECRET_KEY",
                                             "super_secret")
        self.app.config["SERVER_NAME"] = os.environ.get(
            "SERVER_NAME", "pythondiscord.local:8080")
        self.app.config["PREFERRED_URL_SCHEME"] = PREFERRED_URL_SCHEME
        self.app.before_request(self.db.before_request)
        self.app.teardown_request(self.db.teardown_request)

        # Load the oauth blueprint
        self.oauth_backend = OauthBackend(self)
        self.oauth_blueprint = make_discord_blueprint(
            DISCORD_OAUTH_ID,
            DISCORD_OAUTH_SECRET,
            DISCORD_OAUTH_SCOPE,
            '/',
            login_url=DISCORD_OAUTH_REDIRECT,
            authorized_url=DISCORD_OAUTH_AUTHORIZED,
            backend=self.oauth_backend)
        self.log.debug(f"Loading Blueprint: {self.oauth_blueprint.name}")
        self.app.register_blueprint(self.oauth_blueprint)
        self.log.debug("")

        # Load the main blueprint
        self.main_blueprint = Blueprint("main", __name__)
        self.log.debug(f"Loading Blueprint: {self.main_blueprint.name}")
        self.load_views(self.main_blueprint, "pysite/views/main")
        self.load_views(self.main_blueprint, "pysite/views/error_handlers")
        self.app.register_blueprint(self.main_blueprint)
        self.log.debug("")

        # Load the subdomains
        self.subdomains = ['api', 'staff']

        for sub in self.subdomains:
            sub_blueprint = Blueprint(sub, __name__, subdomain=sub)
            self.log.debug(f"Loading Blueprint: {sub_blueprint.name}")
            self.load_views(sub_blueprint, f"pysite/views/{sub}")
            try:
                self.app.register_blueprint(sub_blueprint)
            except Exception:
                logging.getLogger(__name__).exception(
                    f"Failed to register blueprint for subdomain: {sub}")

        # Load the websockets
        self.ws_blueprint = Blueprint("ws", __name__)

        self.log.debug("Loading websocket routes...")
        self.load_views(self.ws_blueprint, "pysite/views/ws")
        self.sockets.register_blueprint(self.ws_blueprint, url_prefix="/ws")

        self.app.before_request(
            self.https_fixing_hook)  # Try to fix HTTPS issues
Esempio n. 9
0
 def _make_app(*args, **kwargs):
     app = Flask(__name__)
     app.secret_key = "whatever"
     blueprint = make_discord_blueprint(*args, **kwargs)
     app.register_blueprint(blueprint)
     return app
Esempio n. 10
0
from flask import Flask
from config import Config
from flask_dance.contrib.discord import make_discord_blueprint, discord
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
import stripe

app = Flask(__name__)
app.config.from_object(Config)
discord_blueprint = make_discord_blueprint(scope=['identify', 'email'], redirect_url='index')
app.register_blueprint(discord_blueprint, url_prefix='/login')
db = SQLAlchemy(app)
migrate = Migrate(app, db)
stripe.api_key = app.config['STRIPE_SECRET']

from app import routes, models

db.create_all()
Esempio n. 11
0
from flask import Flask
from flask_dance.contrib.discord import make_discord_blueprint
import config
from blueprints.verification import verification_blueprint

app = Flask(__name__)
with open('.flask_key') as f:
    app.secret_key = f.read()

discord_blueprint = make_discord_blueprint(
    client_id=config.DISCORD_CLIENT_ID,
    client_secret=config.DISCORD_CLIENT_SECRET,
    scope='identify',
    redirect_to='verification.get_verification_form')

app.register_blueprint(discord_blueprint, url_prefix='/oauth')
app.register_blueprint(verification_blueprint, url_prefix='/verification')
Esempio n. 12
0
    def __init__(self):

        # Set up the app and the database
        self.app = Flask(
            __name__,
            template_folder=TEMPLATES_PATH,
            static_folder=STATIC_PATH,
            static_url_path="/static",
        )
        self.sockets = Sockets(self.app)

        self.db = RethinkDB()
        self.log = logging.getLogger(__name__)
        self.app.secret_key = os.environ.get("WEBPAGE_SECRET_KEY",
                                             "super_secret")
        self.app.config["SERVER_NAME"] = os.environ.get(
            "SERVER_NAME", "pythondiscord.local:8080")
        self.app.config["PREFERRED_URL_SCHEME"] = PREFERRED_URL_SCHEME
        self.app.config[
            "WTF_CSRF_CHECK_DEFAULT"] = False  # We only want to protect specific routes

        # Trim blocks so that {% block %} statements in templates don't generate blank lines
        self.app.jinja_env.trim_blocks = True
        self.app.jinja_env.lstrip_blocks = True

        # We make the token valid for the lifetime of the session because of the wiki - you might spend some
        # time editing an article, and it seems that session lifetime is a good analogue for how long you have
        # to edit
        self.app.config["WTF_CSRF_TIME_LIMIT"] = None

        if DEBUG_MODE:
            # Migrate the database, as we would in prod
            when_ready(output_func=self.db.log.info)

        self.app.before_request(self.db.before_request)
        self.app.teardown_request(self.db.teardown_request)

        CSRF.init_app(self.app)  # Set up CSRF protection

        # Load the oauth blueprint
        self.oauth_backend = OAuthBackend(self)
        self.oauth_blueprint = make_discord_blueprint(
            DISCORD_OAUTH_ID,
            DISCORD_OAUTH_SECRET,
            DISCORD_OAUTH_SCOPE,
            login_url=DISCORD_OAUTH_REDIRECT,
            authorized_url=DISCORD_OAUTH_AUTHORIZED,
            redirect_to="main.auth.done",
            backend=self.oauth_backend)
        self.log.debug(f"Loading Blueprint: {self.oauth_blueprint.name}")
        self.app.register_blueprint(self.oauth_blueprint)
        self.log.debug("")

        # Load the main blueprint
        self.main_blueprint = Blueprint("main", __name__)
        self.log.debug(f"Loading Blueprint: {self.main_blueprint.name}")
        self.load_views(self.main_blueprint, "pysite/views/main")
        self.load_views(self.main_blueprint, "pysite/views/error_handlers")
        self.app.register_blueprint(self.main_blueprint)
        self.log.debug("")

        # Load the subdomains
        self.subdomains = ["api", "staff", "wiki"]

        for sub in self.subdomains:
            try:
                sub_blueprint = Blueprint(sub, __name__, subdomain=sub)
                self.log.debug(f"Loading Blueprint: {sub_blueprint.name}")
                self.load_views(sub_blueprint, f"pysite/views/{sub}")
                self.app.register_blueprint(sub_blueprint)
            except Exception:
                logging.getLogger(__name__).exception(
                    f"Failed to register blueprint for subdomain: {sub}")

        # Load the websockets
        self.ws_blueprint = Blueprint("ws", __name__)

        self.log.debug("Loading websocket routes...")
        self.load_views(self.ws_blueprint, "pysite/views/ws")
        self.sockets.register_blueprint(self.ws_blueprint, url_prefix="/ws")

        self.app.before_request(
            self.https_fixing_hook)  # Try to fix HTTPS issues
Esempio n. 13
0
 def _make_app(*args, **kwargs):
     app = Flask(__name__)
     app.secret_key = "whatever"
     blueprint = make_discord_blueprint(*args, **kwargs)
     app.register_blueprint(blueprint)
     return app
Esempio n. 14
0
from mysql.connector import errorcode

BASE_TEMPLATE = 'base.html'

submissions = 'testsubmissions'

app = Flask(__name__)

# Load entire configuration from config.json.
with open('config.json') as fp:
    config = load(fp)
    authorization = {
        'Authorization': 'Bot {}'.format(config['discord']['token'])
    }
    blueprint = make_discord_blueprint(config['discord']['id'],
                                       config['discord']['secret'],
                                       ['guilds.join', 'identify'],
                                       redirect_to='index')
    app.register_blueprint(blueprint)
    app.config.update(SECRET_KEY=config['flask']['secret'])


def get_ldap(kerb):
    f = popen('athrun consult ldaps ' + quote(kerb)).read().split('\n')
    res = {}
    for x in f:
        splt = x.split(' ')
        if len(splt) != 2: continue
        res[splt[0][:-1]] = splt[1]
    return res