Пример #1
0
async def guild_settings(request:Request):
    '''
    Shows the settings for a particular guild
    '''

    # See if they're logged in
    session = await get_session(request)
    if not session.get('user_id'):
        return HTTPFound(location='/')
    guild_id = request.query.get('guild_id')
    if not guild_id:
        return HTTPFound(location='/')

    # Get the guilds they're valid to alter
    all_guilds = session['guild_info']
    guild = [i for i in all_guilds if (i['owner'] or i['permissions'] & 40 > 0) and guild_id == i['id']]
    if not guild:
        return HTTPFound(location='/')
    data = await request.post()
    prefix = data['prefix'][0:30]

    # Get current prefix
    async with request.app['database']() as db:
        await db('UPDATE guild_settings SET prefix=$1 WHERE guild_id=$2', prefix, int(guild_id))
    async with request.app['redis']() as re:
        await re.publish_json('UpdateGuildPrefix', {
            'guild_id': int(guild_id),
            'prefix': prefix,
        })
    return HTTPFound(location=f'/guild_settings?guild_id={guild_id}')
Пример #2
0
async def unblock_user_post_handler(request: Request):
    """Handles when people submit their new colours"""

    # Get data
    try:
        post_data_raw = await request.post()
    except Exception as e:
        raise e

    # Get blocked user
    try:
        blocked_user = int(post_data_raw['user_id'])
    except ValueError:
        return HTTPFound(location='/user_settings')

    # Get logged in user
    session = await aiohttp_session.get_session(request)
    logged_in_user = session['user_id']

    # Remove data
    async with request.app['database']() as db:
        await db(
            "DELETE FROM blocked_user WHERE user_id=$1 AND blocked_user_id=$2",
            logged_in_user, blocked_user)
    async with request.app['redis']() as re:
        await re.publish("BlockedUserRemove", {
            "user_id": logged_in_user,
            "blocked_user_id": blocked_user
        })

    # Redirect back to user settings
    return HTTPFound(location='/user_settings')
Пример #3
0
async def set_gifs_enabled(request:Request):
    """Sets whether or not gifs are enabled for a given guild"""

    # See if they're logged in
    post_data = await request.post()
    guild_id = post_data['guild_id']
    if not guild_id:
        return HTTPFound(location='/')

    # Get the guilds they're valid to alter
    all_guilds = await webutils.get_user_guilds(request)
    if all_guilds is None:
        return HTTPFound(location='/discord_oauth_login')
    guild = [i for i in all_guilds if (i['owner'] or i['permissions'] & 40 > 0) and guild_id == i['id']]
    if not guild:
        return HTTPFound(location='/')

    # Get the maximum members
    try:
        enabled = bool(post_data['enabled'])
    except KeyError:
        enabled = False

    # Get current prefix
    async with request.app['database']() as db:
        await db('INSERT INTO guild_settings (guild_id, gifs_enabled) VALUES ($1, $2) ON CONFLICT (guild_id) DO UPDATE SET gifs_enabled=$2', int(guild_id), enabled is True)
    async with request.app['redis']() as re:
        await re.publish_json('UpdateGifsEnabled', {
            'guild_id': int(guild_id),
            'gifs_enabled': enabled is True,
        })

    # Redirect to page
    location = f'/guild_settings?guild_id={guild_id}&gold=1' if post_data['gold'] else f'/guild_settings?guild_id={guild_id}'
    return HTTPFound(location=location)
Пример #4
0
    async def upload_replay(self, request: Request) -> Response:

        async with aiohttp.ClientSession() as session:

            if has_multipart_content(request):
                reader = await request.multipart()
                data = await reader.next()
            else:
                data = request.content

            if data is not None:
                async with session.post(self.analyse_replay_endpoint,
                                        data=data) as resp1:
                    if is_success(resp1):
                        replay_analysis = await resp1.json()

                        replay_hash = replay_analysis.get("hash", "")

                        if replay_hash:
                            url = self.add_replay_analysis_endpoint + replay_hash
                            async with session.put(
                                    url, json=replay_analysis) as resp2:
                                if is_success(resp2):
                                    return HTTPFound(
                                        self.show_replay_analysis_endpoint +
                                        replay_hash)

        return HTTPFound("index.html?error=true")
Пример #5
0
async def confirm(request):
    token = request.match_info["token"]
    try:
        token_data = get_token_data(
            token, request.app["config"]["application"]["secret_key"])
        id_ = token_data["id"]
        email_address = token_data["email_address"]
    except Exception:
        flash(request, ("danger", _("Le lien est invalide ou a expiré")))
        raise HTTPBadRequest()

    async with request.app["db-pool"].acquire() as conn:
        q = "UPDATE client SET email_address = $1 WHERE id = $2"
        try:
            await conn.execute(q, email_address, id_)
        except Exception:
            flash(
                request,
                ("danger", _("Votre adresse email ne peut pas être modifiée")))
        else:
            flash(request, ("info", _("Votre adresse email a été modifiée")))
        login = await authorized_userid(request)
        if login:
            return HTTPFound(request.app.router["home"].url_for())
        else:
            return HTTPFound(request.app.router["login"].url_for())
Пример #6
0
async def guild_settings(request:Request):
    """General guild settings page"""

    # Validate guild ID
    try:
        guild_id = int(request.match_info['guild_id'])
    except ValueError:
        return HTTPFound(location='/guilds')

    # Check session age
    session = await aiohttp_session.get_session(request)
    if session.new:
        return HTTPFound(location='/discord_oauth_login')

    # Check user permissions
    if session['user_id'] not in request.app['config']['owners']:
        user_guilds = await webutils.get_user_guilds(request)
        guild_info = [i for i in user_guilds if guild_id == i['id'] and discord.Permissions(i['permissions']).manage_messages],
        if not guild_info:
            return HTTPFound(location='/guilds')

    # Get guild object for in case I force my way in here
    try:
        guild_object = await request.app['bot'].fetch_guild(guild_id)
    except discord.Forbidden:
        return HTTPFound(location=request.app['bot'].get_invite_link(guild_id=guild_id, redirect_uri="https://synergy.voxelfox.co.uk/login_redirect/guilds", read_messages=True))

    return {
        'guild': guild_object
    }
Пример #7
0
async def confirm(request):
    token = request.match_info["token"]

    try:
        token_data = get_token_data(
            token, request.app["config"]["application"]["secret_key"])
        id_ = token_data["id"]
    except Exception:
        flash(request, ("danger", _("Le lien est invalide ou a expiré")))
        raise HTTPBadRequest()

    async with request.app["db-pool"].acquire() as conn:
        q = "UPDATE client SET confirmed = true WHERE id = $1 RETURNING id"
        try:
            updated = await conn.fetchval(q, id_)
            if updated is None:
                raise
        except Exception:
            flash(request,
                  ("danger", _("Vous ne pouvez pas être enregistré.")))
            return HTTPFound(request.app.router["register"].url_for())
        else:
            flash(request, (
                "info",
                _("Votre enregistrement est confirmé, vous pouvez vous connecter."
                  )))
            return HTTPFound(request.app.router["login"].url_for())
Пример #8
0
async def login(request:Request):
    '''
    Page the discord login redirects the user to when successfully logged in with Discord
    '''

    # Get the code
    code = request.query.get('code')
    if not code:
        return HTTPFound(location='/')

    # Get the bot
    config = request.app['config']
    oauth_data = config['oauth']

    # Generate the post data
    data = {
        'grant_type': 'authorization_code',
        'code': code, 
        'scope': OAUTH_SCOPE
    }
    data.update(oauth_data)
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    # Make the request
    async with ClientSession(loop=request.loop) as session:

        # Get auth
        token_url = f"https://discordapp.com/api/v6/oauth2/token"
        async with session.post(token_url, data=data, headers=headers) as r:
            token_info = await r.json()

        # Get user
        headers.update({
            "Authorization": f"{token_info['token_type']} {token_info['access_token']}"
        })
        user_url = f"https://discordapp.com/api/v6/users/@me"
        async with session.get(user_url, headers=headers) as r:
            user_info = await r.json()

        # Get guilds
        guilds_url = f"https://discordapp.com/api/v6/users/@me/guilds"
        async with session.get(guilds_url, headers=headers) as r:
            guild_info = await r.json()

    # Save to session
    session = await new_session(request)

    # Update avatar data
    user_info['avatar_link'] = get_avatar(user_info)
    session['user_info'] = user_info

    # Update guild data
    session['guild_info'] = guild_info

    # Redirect to settings
    session['user_id'] = int(user_info['id'])
    return HTTPFound(location=f'/settings')
    async def post(self, request):
        display_region = request.match_info['display_region']
        user_journey = request.match_info['user_journey']
        sub_user_journey = request.match_info['sub_user_journey']

        self.log_entry(
            request, display_region + '/' + user_journey + '/' +
            sub_user_journey + '/select-address')

        if user_journey == 'start':
            session = await get_permitted_session(request)
        else:
            session = await get_existing_session(request, user_journey,
                                                 sub_user_journey)

        attributes = get_session_value(session, 'attributes', user_journey,
                                       sub_user_journey)

        data = await request.post()

        try:
            selected_uprn = data['form-pick-address']
        except KeyError:
            logger.info('no address selected',
                        client_ip=request['client_ip'],
                        client_id=request['client_id'],
                        trace=request['trace'],
                        region_of_site=display_region,
                        journey_requiring_address=user_journey)
            if display_region == 'cy':
                flash(request, ADDRESS_SELECT_CHECK_MSG_CY)
            else:
                flash(request, ADDRESS_SELECT_CHECK_MSG)
            raise HTTPFound(
                request.app.router['CommonSelectAddress:get'].url_for(
                    display_region=display_region,
                    user_journey=user_journey,
                    sub_user_journey=sub_user_journey))

        if selected_uprn == 'xxxx':
            raise HTTPFound(
                request.app.router['CommonRegisterAddress:get'].url_for(
                    display_region=display_region,
                    user_journey=user_journey,
                    sub_user_journey=sub_user_journey))
        else:
            attributes['uprn'] = selected_uprn
            session.changed()
            logger.info('session updated',
                        client_ip=request['client_ip'],
                        client_id=request['client_id'],
                        trace=request['trace'],
                        uprn_selected=selected_uprn,
                        region_of_site=display_region)

        raise HTTPFound(request.app.router['CommonConfirmAddress:get'].url_for(
            display_region=display_region,
            user_journey=user_journey,
            sub_user_journey=sub_user_journey))
Пример #10
0
        async def wrapper(request: Request):
            """This is the wrapper that does all the heavy lifting"""

            # Run function
            data = await func(request)

            # See if we return anything other than data (like redirects)
            if isinstance(data, HTTPFound):
                if data.location == "/discord_oauth_login":
                    session = await aiohttp_session.get_session(request)
                    if 'redirect_on_login' not in session:
                        session['redirect_on_login'] = str(request.url)
            if not isinstance(data, dict):
                return data

            # See if we need to get rid of them
            session = await aiohttp_session.get_session(request)
            login_redirect = session.pop('redirect_on_login', None)
            if login_redirect:
                return HTTPFound(location=login_redirect)

            # Update jinja params
            if data is None:
                data = dict()
            data.update({'session': session})
            if 'user_info' not in data:
                try:
                    data.update({'user_info': session['user_info']})
                except KeyError:
                    data.update({'user_info': None})
            if 'request' not in data:
                data.update({'request': request})

            # Check return relevant info
            if redirect_if_logged_out and session.get('user_id') is None:
                return HTTPFound(location=redirect_if_logged_out)
            elif redirect_if_logged_in and session.get('user_id') is not None:
                return HTTPFound(location=redirect_if_logged_in)

            # Update OpenGraph information
            if 'opengraph' not in data:
                data.update({'opengraph': dict()})
            og_data = data['opengraph'].copy()
            og_data['og:title'] = og_data.get(
                'og:title', 'MarriageBot - A marriage-based Discord bot')
            og_data['og:description'] = og_data.get(
                'og:description',
                'MarriageBot is a Discord bot used for simulations of your family, be it that you want b1nzy as your mom, or Jake as your nephew, MarriageBot can handle it all.'
            )
            og_data['og:type'] = og_data.get('og:type', 'website')
            og_data['og:image'] = og_data.get(
                'og:image',
                'https://marriagebot.xyz/static/images/MarriageBotCircle.150.png'
            )
            og_data['og:locale'] = og_data.get('og:locale', 'en_GB')
            data['opengraph'] = og_data

            return data
Пример #11
0
async def redirect(request: Request):
    """Handles redirects using codes stored in the db"""

    code = request.match_info['code']
    async with request.app['database']() as db:
        data = await db("SELECT location FROM redirects WHERE code=$1", code)
    if not data:
        return HTTPFound(location='/')
    return HTTPFound(location=data[0]['location'])
Пример #12
0
async def set_max_allowed_children(request: Request):
    """Sets the max children for the guild"""

    # See if they're logged in
    session = await aiohttp_session.get_session(request)
    post_data = await request.post()
    if not session.get('user_id'):
        return HTTPFound(location='/')
    guild_id = post_data['guild_id']
    if not guild_id:
        return HTTPFound(location='/')

    # Get the guilds they're valid to alter
    all_guilds = await webutils.get_user_guilds(request)
    if all_guilds is None:
        return HTTPFound(location='/discord_oauth_login')
    guild = [
        i for i in all_guilds
        if (i['owner'] or i['permissions'] & 40 > 0) and guild_id == i['id']
    ]
    if not guild:
        return HTTPFound(location='/')

    # Get the maximum members
    hard_maximum_children = max([
        i['max_children']
        for i in request.app['config']['role_perks'].values()
    ])
    hard_minimum_children = min([
        i['max_children']
        for i in request.app['config']['role_perks'].values()
    ])
    max_children_data = {
        int(i):
        min([max([int(o), hard_minimum_children]), hard_maximum_children])
        for i, o in post_data.items() if i.isdigit() and len(o) > 0
    }  # user ID: amount

    # Get current prefix
    async with request.app['database']() as db:
        await db('DELETE FROM max_children_amount WHERE guild_id=$1',
                 int(guild_id))
        for role_id, amount in max_children_data.items():
            await db(
                'INSERT INTO max_children_amount (guild_id, role_id, amount) VALUES ($1, $2, $3)',
                int(guild_id),
                role_id,
                amount,
            )
    async with request.app['redis']() as re:
        await re.publish('UpdateMaxChildren', {
            'guild_id': int(guild_id),
            'max_children': max_children_data,
        })

    # Redirect to page
    return HTTPFound(location=f'/guild_settings?guild_id={guild_id}&gold=1')
Пример #13
0
async def login_processor(request: Request):
    """
    Page the discord login redirects the user to when successfully logged in with Discord.
    """

    v = await webutils.process_discord_login(request)
    if isinstance(v, Response):
        return HTTPFound(location="/")
    session = await aiohttp_session.get_session(request)
    return HTTPFound(location=session.pop("redirect_on_login", "/"))
    async def post(self, request):
        session = await get_permitted_session(request)
        display_region = request.match_info['display_region']

        if display_region == 'cy':
            locale = 'cy'
        else:
            locale = 'en'

        self.log_entry(request,
                       display_region + '/start/transient/accommodation-type')

        data = await request.post()

        attributes = get_session_value(session, 'attributes', 'start')
        case = get_session_value(session, 'case', 'start')

        try:
            accommodation_type = data['accommodation-type']
            attributes['transientAccommodationType'] = accommodation_type
            session.changed()

            if case['region'] == 'N':
                raise HTTPFound(
                    request.app.router['StartNILanguageOptions:get'].url_for())
            else:
                attributes['language'] = locale
                attributes['display_region'] = display_region
                await self.call_questionnaire(request, case, attributes,
                                              request.app,
                                              session.get('adlocation'))

        except KeyError:
            logger.info('transient accommodation type error',
                        client_ip=request['client_ip'],
                        client_id=request['client_id'],
                        trace=request['trace'],
                        region_of_site=display_region)
            if display_region == 'cy':
                flash(
                    request,
                    FlashMessage.generate_flash_message(
                        "Dewiswch ateb", 'ERROR', 'ACCOMMODATION_TYPE_ERROR',
                        'error-accommodation-type'))
            else:
                flash(
                    request,
                    FlashMessage.generate_flash_message(
                        'Select an answer', 'ERROR',
                        'ACCOMMODATION_TYPE_ERROR',
                        'error-accommodation-type'))
            raise HTTPFound(
                request.app.router['StartTransientAccommodationType:get'].
                url_for(display_region=display_region))
Пример #15
0
async def reddit_login_processor(request: Request):
    """
    Page the discord login redirects the user to when successfully logged in with Reddit.
    """

    session = await aiohttp_session.get_session(request)

    # Validate that
    async with aiohttp.ClientSession() as web_session:
        auth = f"{request.app['config']['reddit_oauth']['client_id']}:{request.app['config']['reddit_oauth']['client_secret']}"
        headers = {
            'Authorization': f'Basic {b64encode(auth.encode()).decode()}',
        }
        params = {
            'code':
            request.query.get('code'),
            'grant_type':
            'authorization_code',
            'redirect_uri':
            request.app['config']['website_base_url'].rstrip('/') +
            '/reddit_login_processor',
        }
        async with web_session.post(
                "https://www.reddit.com/api/v1/access_token",
                data=params,
                headers=headers) as r:
            token_data = await r.json()
            if r.status != 200:
                return HTTPFound(
                    location=session.pop('redirect_on_login', '/'))
        headers = {
            "Authorization": f"bearer {token_data['access_token']}",
            "User-Agent": "Apple.py Discord Bot ([email protected])",
        }
        async with web_session.get("https://oauth.reddit.com/api/v1/me",
                                   headers=headers) as r:
            user_data = await r.json()
            if r.status != 200:
                return HTTPFound(
                    location=session.pop('redirect_on_login', '/'))

    # Store that
    async with request.app['database']() as db:
        await db(
            """INSERT INTO user_settings (user_id, reddit_username, reddit_access_token, reddit_refresh_token) VALUES ($1, $2, $3, $4)
            ON CONFLICT (user_id) DO UPDATE SET reddit_username=excluded.reddit_username, reddit_access_token=excluded.reddit_access_token,
            reddit_refresh_token=excluded.reddit_refresh_token""",
            session['user_id'],
            user_data['name'],
            token_data['access_token'],
            token_data['refresh_token'],
        )

    return HTTPFound(location=session.pop('redirect_on_login', '/'))
    async def post(self, request):
        display_region = request.match_info['display_region']
        user_journey = request.match_info['user_journey']
        sub_user_journey = request.match_info['sub_user_journey']

        self.log_entry(
            request, display_region + '/' + user_journey + '/' +
            sub_user_journey + '/enter-address')

        if user_journey == 'start':
            session = await get_permitted_session(request)
        else:
            session = await get_existing_session(request, user_journey,
                                                 sub_user_journey)

        data = await request.post()

        try:
            postcode = ProcessPostcode.validate_postcode(
                data['form-enter-address-postcode'], display_region)
            logger.info('valid postcode',
                        client_ip=request['client_ip'],
                        client_id=request['client_id'],
                        trace=request['trace'],
                        postcode_entered=postcode,
                        region_of_site=display_region)

        except (InvalidDataError, InvalidDataErrorWelsh) as exc:
            logger.info('invalid postcode',
                        client_ip=request['client_ip'],
                        client_id=request['client_id'],
                        trace=request['trace'])
            if exc.message_type == 'empty':
                flash_message = FlashMessage.generate_flash_message(
                    str(exc), 'ERROR', 'POSTCODE_ENTER_ERROR',
                    'error_postcode_empty')
            else:
                flash_message = FlashMessage.generate_flash_message(
                    str(exc), 'ERROR', 'POSTCODE_ENTER_ERROR',
                    'error_postcode_invalid')
            flash(request, flash_message)
            raise HTTPFound(
                request.app.router['CommonEnterAddress:get'].url_for(
                    display_region=display_region,
                    user_journey=user_journey,
                    sub_user_journey=sub_user_journey))

        session['attributes']['postcode'] = postcode
        session.changed()

        raise HTTPFound(request.app.router['CommonSelectAddress:get'].url_for(
            display_region=display_region,
            user_journey=user_journey,
            sub_user_journey=sub_user_journey))
Пример #17
0
    async def post(self) -> Response:
        response_location = HTTPFound('/zbs/switches')
        form_data = await self.request.post()
        validated_data = self.validate_form_data(form_data)

        if not validated_data:
            return HTTPFound('/zbs')

        login, password = validated_data.get('login', ''), validated_data.get('password', '')

        return await self.authorise(response_location, login, password)
Пример #18
0
async def set_prefix(request: Request):
    """Sets the prefix for a given guild"""

    # See if they're logged in
    session = await aiohttp_session.get_session(request)
    post_data = await request.post()
    if not session.get('user_id'):
        return HTTPFound(location='/')
    guild_id = post_data['guild_id']
    if not guild_id:
        return HTTPFound(location='/')

    # Get the guilds they're valid to alter
    all_guilds = await webutils.get_user_guilds(request)
    if all_guilds is None:
        return HTTPFound(location='/discord_oauth_login')
    guild = [
        i for i in all_guilds
        if (i['owner'] or i['permissions'] & 40 > 0) and guild_id == i['id']
    ]
    if not guild:
        return HTTPFound(location='/')

    # Grab the prefix they gave
    prefix = post_data['prefix'][0:30]
    if len(prefix) == 0:
        if post_data['gold']:
            prefix = request.app['gold_config']['prefix']['default_prefix']
        else:
            prefix = request.app['config']['prefix']['default_prefix']

    # Update prefix in DB
    async with request.app['database']() as db:
        if post_data['gold']:
            key = 'gold_prefix'
        else:
            key = 'prefix'
        await db(
            f'INSERT INTO guild_settings (guild_id, {key}) VALUES ($1, $2) ON CONFLICT (guild_id) DO UPDATE SET {key}=$2',
            int(guild_id), prefix)
    async with request.app['redis']() as re:
        redis_data = {'guild_id': int(guild_id)}
        redis_data[{
            True: 'gold_prefix',
            False: 'prefix'
        }[bool(post_data['gold'])]] = prefix
        await re.publish('UpdateGuildPrefix', redis_data)

    # Redirect to page
    location = f'/guild_settings?guild_id={guild_id}&gold=1' if post_data[
        'gold'] else f'/guild_settings?guild_id={guild_id}'
    return HTTPFound(location=location)
Пример #19
0
async def github_login_processor(request: Request):
    """
    Page the discord login redirects the user to when successfully logged in with Github.
    """

    session = await aiohttp_session.get_session(request)

    # Validate that
    async with aiohttp.ClientSession() as web_session:
        params = {
            'client_id':
            request.app['config']['github_oauth']['client_id'],
            'client_secret':
            request.app['config']['github_oauth']['client_secret'],
            'code':
            request.query.get('code'),
            'redirect_uri':
            request.app['config']['website_base_url'].rstrip('/') +
            '/github_login_processor',
        }
        headers = {
            'Accept': 'application/vnd.github.v3+json',
        }
        async with web_session.post(
                "https://github.com/login/oauth/access_token",
                params=params,
                headers=headers) as r:
            token_data = await r.json()
            if r.status != 200:
                return HTTPFound(
                    location=session.pop('redirect_on_login', '/'))
        headers.update(
            {"Authorization": f"token {token_data['access_token']}"})
        async with web_session.post("https://api.github.com/user",
                                    headers=headers) as r:
            user_data = await r.json()
            if r.status != 200:
                return HTTPFound(
                    location=session.pop('redirect_on_login', '/'))

    # Store that
    async with request.app['database']() as db:
        await db(
            """INSERT INTO user_settings (user_id, github_username, github_access_token) VALUES ($1, $2, $3)
            ON CONFLICT (user_id) DO UPDATE SET github_username=excluded.github_username,
            github_access_token=excluded.github_access_token""",
            session['user_id'],
            user_data['login'],
            token_data['access_token'],
        )

    return HTTPFound(location=session.pop('redirect_on_login', '/'))
Пример #20
0
async def language(request):
    path_items = request.path.split('/')
    if "en" in path_items:
        locale = "en"
    else:
        locale = "fr"

    url = request.headers.get("REFERER")
    if url is None:
        url = request.app.router["home"].url_for()
    resp = HTTPFound(url)
    resp.set_cookie("locale", locale)
    return resp
Пример #21
0
async def guild_responses(request:Request):
    """The guild picker page for the user"""

    # Validate guild ID
    try:
        guild_id = int(request.match_info['guild_id'])
    except ValueError:
        return HTTPFound(location='/guilds')

    # Check session age
    session = await aiohttp_session.get_session(request)
    if session.new:
        return HTTPFound(location='/discord_oauth_login')

    # Check user permissions
    if session['user_id'] not in request.app['config']['owners']:
        user_guilds = await webutils.get_user_guilds(request)
        guild_info = [i for i in user_guilds if guild_id == i['id'] and discord.Permissions(i['permissions']).manage_messages],
        if not guild_info:
            return HTTPFound(location='/guilds')

    # Get guild object for in case I force my way in here
    try:
        guild_object = await request.app['bot'].fetch_guild(guild_id)
    except discord.Forbidden:
        return HTTPFound(location=request.app['bot'].get_invite_link(guild_id=guild_id, redirect_uri="https://synergy.voxelfox.co.uk/login_redirect/guilds", read_messages=True))

    # Get interaction info
    interactions = collections.defaultdict(list)
    metadata = {}
    async with request.app['database']() as db:
        command_responses = await db('SELECT command_name, response FROM command_responses WHERE guild_id=$1 ORDER BY response ASC', guild_id)
        command_metadata = await db('SELECT * FROM command_names WHERE guild_id=$1', guild_id)
    for response in command_responses:
        interactions[response['command_name']].append(response['response'])
    for row in command_metadata:
        metadata[row['command_name']] = {
            'enabled': row['enabled'],
            'nsfw': row['nsfw'],
            'min_mentions': row['min_mentions'],
            'max_mentions': row['max_mentions'],
            'aliases': ','.join(row['aliases']),
        }

    # Send data back to page
    return {
        'guild': guild_object,
        'interactions': interactions,
        'metadata': metadata,
        'highlight': request.query.get('highlight'),
    }
Пример #22
0
async def twitch_login_processor(request: Request):
    """
    Page the discord login redirects the user to when successfully logged in with Twitch.
    """

    session = await aiohttp_session.get_session(request)

    # Validate that
    async with aiohttp.ClientSession() as web_session:
        params = {
            'client_id':
            request.app['config']['twitch_oauth']['client_id'],
            'client_secret':
            request.app['config']['twitch_oauth']['client_secret'],
            'code':
            request.query.get('code'),
            'grant_type':
            'authorization_code',
            'redirect_uri':
            request.app['config']['website_base_url'].rstrip('/') +
            '/twitch_login_processor',
        }
        async with web_session.post("https://id.twitch.tv/oauth2/token",
                                    params=params) as r:
            token_data = await r.json()
            if r.status != 200:
                return HTTPFound(
                    location=session.pop('redirect_on_login', '/'))
        async with web_session.get("https://id.twitch.tv/oauth2/validate",
                                   headers={
                                       "Authorization":
                                       f"Bearer {token_data['access_token']}"
                                   }) as r:
            validate_data = await r.json()
            if r.status != 200:
                return HTTPFound(
                    location=session.pop('redirect_on_login', '/'))

    # Store that
    async with request.app['database']() as db:
        await db(
            """INSERT INTO user_settings (user_id, twitch_user_id, twitch_username, twitch_bearer_token) VALUES ($1, $2, $3, $4)
            ON CONFLICT (user_id) DO UPDATE SET twitch_user_id=excluded.twitch_user_id, twitch_username=excluded.twitch_username,
            twitch_bearer_token=excluded.twitch_bearer_token""",
            session['user_id'],
            validate_data['user_id'],
            validate_data['login'],
            token_data['access_token'],
        )

    return HTTPFound(location=session.pop('redirect_on_login', '/'))
Пример #23
0
async def mailing(request):
    async with request.app["db-pool"].acquire() as conn:
        rows = await conn.fetch("SELECT id, name FROM repository WHERE opened")
        repository_choices = [(row["id"], row["name"]) for row in rows]

        if request.method == "POST":
            form = MailingForm(await request.post(), meta=await generate_csrf_meta(request))
            form.repository_id.choices = repository_choices
            if form.validate():
                data = remove_special_data(form.data)
                subject = data["subject"]
                message = data["message"]
                if data["all_repositories"]:
                    q = (
                        "SELECT first_name, email_address, login FROM client "
                        "WHERE confirmed AND mailing"
                        )
                    rows = await conn.fetch(q)
                else:
                    repository_id = data.get("repository_id")
                    q = (
                        "SELECT first_name, email_address, login FROM client "
                        "WHERE confirmed AND mailing AND repository_id = $1"
                    )
                    rows = await conn.fetch(q, repository_id)
                if not rows:
                    flash(request, ("warning", _("Il n'y a pas de destinataire.")))
                    return HTTPFound(request.app.router["mailing"].url_for())

                if "<first_name>" in message or "<login>" in message:
                    for r in rows:
                        message_ = message.replace("<first_name>", r["first_name"])
                        message_ = message_.replace("<login>", r["login"])
                        await send_text_message(request, r["email_address"], subject, message_)
                else:
                    email_addresses = [r["email_address"] for r in rows]
                    await send_mailing_message(request, email_addresses, subject, message)
                flash(request, ("info", _("Les messages ont été envoyés.")))
                return HTTPFound(request.app.router["mailing"].url_for())
            else:
                flash(request, ("danger", _("Le formulaire contient des erreurs.")))
                return HTTPFound(request.app.router["mailing"].url_for())

        elif request.method == "GET":
            form = MailingForm(meta=await generate_csrf_meta(request))
            form.repository_id.choices = repository_choices
            return {"form": form}

        else:
            raise HTTPMethodNotAllowed()
Пример #24
0
async def handler(request):
    async with request.app["db-pool"].acquire() as conn:
        rows = await conn.fetch(
            "SELECT id, name, latitude, longitude FROM repository WHERE opened"
        )
        repository_choices = [(row["id"], row["name"]) for row in rows]

        if request.method == "POST":
            form = RegisterForm(await request.post(),
                                meta=await generate_csrf_meta(request))
            form.repository_id.choices = repository_choices
            if form.validate():
                data = remove_special_data(form.data)
                del data["password2"]
                data["password_hash"] = sha256_crypt.hash(data.pop("password"))
                try:
                    async with conn.transaction():
                        q = "INSERT INTO client ({}) VALUES ({}) RETURNING *".format(
                            field_list(data), place_holders(data))
                        try:
                            client = await conn.fetchrow(q, *data.values())
                        except UniqueViolationError:
                            flash(request,
                                  ("warning",
                                   _("Votre profil ne peut être créé, cet "
                                     "identifiant est déjà utilisé")))
                            raise  # rollback the transaction : client not created
                        await send_confirmation(
                            request, client["email_address"],
                            {"id": client["id"]}, "confirm_register",
                            _("Confirmation de votre enregistrement"),
                            "register-confirmation")
                        flash(request,
                              ("info",
                               _("Un email de confirmation a été envoyé à {}").
                               format(client["email_address"])))
                        return HTTPFound(request.app.router["login"].url_for())
                except Exception:
                    return HTTPFound(request.app.router["register"].url_for())
            else:
                flash(request,
                      ("danger", _("Le formulaire contient des erreurs.")))
            return {"form": form, "repositories": rows}
        elif request.method == "GET":
            form = RegisterForm(meta=await generate_csrf_meta(request))
            form.repository_id.choices = repository_choices
            return {"form": form, "repositories": rows}
        else:
            raise HTTPMethodNotAllowed()
Пример #25
0
        async def wrapper(request: Request):
            """
            This is the wrapper that does all the heavy lifting.
            """

            # Run function
            data = await func(request)

            # See if we're returning to a redirect
            if isinstance(data, HTTPFound):

                # If we're telling them to login
                if data.location == request.app['config']['login_url']:
                    session = await aiohttp_session.get_session(request)

                    # We can send them back to where they tried to go initially
                    if 'redirect_on_login' not in session:
                        session['redirect_on_login'] = str(request.url)

            # It's not a redirect and it isn't data, I'll just leave it alone
            if not isinstance(data, dict):
                return data

            # See if we need to take them to a new place (already logged in)
            session = await aiohttp_session.get_session(request)
            login_redirect = session.pop('redirect_on_login', None)
            if login_redirect:
                return HTTPFound(location=login_redirect)

            # Update jinja params
            if data is None:
                data = dict()
            data.update({'session': session})
            if 'user_info' not in data:
                try:
                    data.update({'user_info': session['user_info']})
                except KeyError:
                    data.update({'user_info': None})
            if 'request' not in data:
                data.update({'request': request})

            # Check return relevant info
            if redirect_if_logged_out and session.get('user_id') is None:
                return HTTPFound(location=redirect_if_logged_out)
            elif redirect_if_logged_in and session.get('user_id') is not None:
                return HTTPFound(location=redirect_if_logged_in)

            return data
Пример #26
0
    async def logout(self):
        session = await get_session(self.request)

        if 'id' in session:
            del session['id']

        return HTTPFound('/login')
Пример #27
0
    async def post(self) -> dict:
        display_data = {'location': 'login'}

        data = await self.request.post()

        if not check_form_data(data, 'id', 'password'):
            display_data.update({'error': 'No se ha enviado los parámetros necesarios...'})
            return display_data

        id_, password = data['id'], data['password']

        errors = await self.validate(id_, password)

        if not errors:
            id_ = int(id_)

            try:
                await self.auth(id_, password)
            except FailedAuth as e:
                display_data.update({'error': str(e)})
            else:
                await self.init_session(id_)

                raise HTTPFound('/')  # Redirigir al landing page
        else:
            display_data.update({'errors': errors})

        return display_data
Пример #28
0
async def unauthenticated_middleware(request, handler):
    try:
        response = await handler(request)
    except auth.NotAuthenticated:
        raise HTTPFound('/login')
    else:
        return response
Пример #29
0
async def handler(request):
    if request.method == "POST":
        form = EmailForm(await request.post(),
                         meta=await generate_csrf_meta(request))
        if form.validate():
            data = dict(form.data.items())
            email_address = data["email_address"]
            async with request.app["db-pool"].acquire() as conn:
                q = "SELECT id, email_address, login FROM client WHERE email_address = $1"
                client = await conn.fetchrow(q, email_address)
            if client is None:
                flash(request,
                      ("danger",
                       _("Il n'y a pas de profil dont l'adresse email est {}").
                       format(email_address)))
            else:
                await send_text_message(
                    request,
                    client["email_address"],
                    _("Rappel de Votre identifiant"),
                    _("Votre identifiant est {}").format(client["login"]),
                )
                flash(request,
                      ("info", _("Un email de confirmation a été envoyé à {}").
                       format(email_address)))
                return HTTPFound(request.app.router["login"].url_for())
        else:
            flash(request,
                  ("danger", _("Le formulaire contient des erreurs.")))
        return {"form": form}
    elif request.method == "GET":
        form = EmailForm(meta=await generate_csrf_meta(request))
        return {"form": form}
    else:
        raise HTTPMethodNotAllowed()
Пример #30
0
async def colour_settings_post_handler(request: Request):
    """Handles when people submit their new colours"""

    # Grab the colours from their post request
    try:
        colours_raw = await request.post()
    except Exception as e:
        raise e
    colours_raw = dict(colours_raw)

    # Fix up the attributes
    direction = colours_raw.pop("direction")
    colours = {
        i: -1 if o in ['', 'transparent'] else int(o.strip('#'), 16)
        for i, o in colours_raw.items()
    }
    colours['direction'] = direction

    # Save the data to the database
    session = await aiohttp_session.get_session(request)
    user_id = session['user_id']
    async with request.app['database']() as db:
        ctu = await utils.CustomisedTreeUser.get(user_id, db)
        for i, o in colours.items():
            setattr(ctu, i, o)
        await ctu.save(db)

    # Redirect back to user settings
    return HTTPFound(location='/user_settings')