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}')
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')
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)
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")
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())
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 }
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())
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))
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
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'])
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')
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))
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))
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)
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)
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', '/'))
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
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'), }
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', '/'))
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()
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()
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
async def logout(self): session = await get_session(self.request) if 'id' in session: del session['id'] return HTTPFound('/login')
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
async def unauthenticated_middleware(request, handler): try: response = await handler(request) except auth.NotAuthenticated: raise HTTPFound('/login') else: return response
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()
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')