Ejemplo n.º 1
0
async def activate_page_autofill(_, lang, code):
    if lang == 'fr':
        register_template = env.get_template('activate/fr.html')
        page = register_template.render(
            VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
            site_key=app.config.GSITE_KEY,
            activation_key=code)
        return response.html(page)
    elif lang == 'es':
        register_template = env.get_template('activate/es.html')
        page = register_template.render(
            VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
            site_key=app.config.GSITE_KEY,
            activation_key=code)
        return response.html(page)
    elif lang == 'pt':
        register_template = env.get_template('activate/pt.html')
        page = register_template.render(
            VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
            site_key=app.config.GSITE_KEY,
            activation_key=code)
        return response.html(page)
    register_template = env.get_template('activate/en.html')
    page = register_template.render(
        VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
        site_key=app.config.GSITE_KEY,
        activation_key=code)
    return response.html(page)
Ejemplo n.º 2
0
async def activate_page(request, lang):
    if lang == 'fr':
        register_template = env.get_template('fr_vanilla_activation.html')
        page = register_template.render(
            play_subdomain=app.config.PLAY_SUBDOMAIN,
            site_key=app.config.GSITE_KEY)
        return response.html(page)
    elif lang == 'es':
        register_template = env.get_template('es_vanilla_activation.html')
        page = register_template.render(
            play_subdomain=app.config.PLAY_SUBDOMAIN,
            site_key=app.config.GSITE_KEY)
        return response.html(page)
    elif lang == 'pt':
        register_template = env.get_template('pt_vanilla_activation.html')
        page = register_template.render(
            play_subdomain=app.config.PLAY_SUBDOMAIN,
            site_key=app.config.GSITE_KEY)
        return response.html(page)
    else:
        register_template = env.get_template('en_vanilla_activation.html')
        page = register_template.render(
            play_subdomain=app.config.PLAY_SUBDOMAIN,
            site_key=app.config.GSITE_KEY)
        return response.html(page)
Ejemplo n.º 3
0
async def edit_player(request, penguin_id):
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request.ctx.session.get('username')
    ).gino.first()
    player = await Penguin.query.where(Penguin.id == int(penguin_id)
                                       ).gino.first()
    if not player:
        template = env.get_template('manager/manage.html')
        penguins = await Penguin.query.order_by(
            Penguin.registration_date.desc()).gino.all()
        penguins = get_paginated_result(penguins)
        page = template.render(
            success_message=f'Could not find a player by the ID: {penguin_id}',
            error_message='',
            penguins=penguins,
            penguin=data)
        return response.html(page)

    latest_ban = await get_latest_ban(penguin_id)
    bans = await get_bans(penguin_id)
    login_history = await get_login_history(penguin_id)
    template = env.get_template('manager/edit-player.html')
    page = template.render(success_message='',
                           error_message='',
                           play_link=app.config.VANILLA_PLAY_LINK,
                           player=player,
                           penguin=data,
                           latest_ban=latest_ban,
                           bans=bans,
                           connection_history=login_history)
    return response.html(page)
Ejemplo n.º 4
0
async def password_reset_page(_, lang):
    template = env.get_template(f'password/request/{lang}.html')
    page = template.render(
        VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
        site_key=app.config.GSITE_KEY
    )
    return response.html(page)
Ejemplo n.º 5
0
async def activate_page_autofill(_, lang, code):
    register_template = env.get_template(f'activate/{lang}.html')
    page = register_template.render(
        VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
        site_key=app.config.GSITE_KEY,
        activation_key=code)
    return response.html(page)
Ejemplo n.º 6
0
async def login_page(_):
    template = env.get_template('manager/login.html')
    page = template.render(
        success_message='',
        error_message='',
        site_key=app.config.GSITE_KEY
    )
    return response.html(page)
Ejemplo n.º 7
0
def _edit_prompt(selector, message):
    prompt_template = env.get_template('html/prompt.html')
    return ({
        'command': 'insert',
        'selector': selector,
        'method': 'replaceWith',
        'data': prompt_template.render(message=message)
    })
Ejemplo n.º 8
0
def _make_error_message(name, message):
    error_template = env.get_template('error.html')
    return ({
        'command': 'insert',
        'selector': f'#{name}-error',
        'method': 'html',
        'data': error_template.render(message=message)
    })
Ejemplo n.º 9
0
async def choose_password_page(_, lang, reset_token):
    reset_key = await app.ctx.redis.get(f'{reset_token}.reset_key')
    if reset_key:
        template = env.get_template(f'password/choose/{lang}.html')
        page = template.render(VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
                               token=reset_token,
                               site_key=app.config.GSITE_KEY)
        return response.html(page)
    return response.json({'message': 'Reset key not found'}, status=404)
Ejemplo n.º 10
0
async def request_password_reset(request, lang):
    username = request.form.get('name', '').lower()
    email = request.form.get('email', '').lower()
    if app.config.GSECRET_KEY:
        gclient_response = request.form.get('recaptcha_response', '')
        async with aiohttp.ClientSession() as session:
            async with session.post(app.config.GCAPTCHA_URL,
                                    data=dict(secret=app.config.GSECRET_KEY,
                                              response=gclient_response,
                                              remoteip=request.ip)) as resp:
                gresult = await resp.json()
                if not gresult['success']:
                    return response.text(
                        'Your captcha score was low, please try again.')

    if not username:
        return response.json([_add_class('name', 'error')],
                             headers={'X-Drupal-Ajax-Token': 1})
    elif not email or '@' not in email:
        return response.json([_add_class('email', 'error')],
                             headers={'X-Drupal-Ajax-Token': 1})

    data = await Penguin.query.where(Penguin.username == username).gino.first()
    if data and data.email == email:
        reset_key = secrets.token_urlsafe(45)
        mail_template = env.get_template(f'emails/password/{lang}.html')
        message = Mail(
            from_email=app.config.FROM_EMAIL,
            to_emails=email,
            subject=i18n.t('password.reset_password_subject', locale=lang),
            html_content=mail_template.render(
                username=username,
                site_name=app.config.SITE_NAME,
                reset_link=
                f'{app.config.VANILLA_PLAY_LINK}/{lang}/penguin/forgot-password/{reset_key}'
            ))
        sg = SendGridAPIClient(app.config.SENDGRID_API_KEY)
        sg.send(message)
        await app.ctx.redis.setex(f'{reset_key}.reset_key',
                                  app.config.AUTH_TTL, data.id)
    return response.json([
        _remove_selector('#edit-name'),
        _remove_selector('#edit-email'),
        _remove_selector('#edit-submit'),
        _edit_title(
            '#forgotpassword h2',
            i18n.t('password.password_title', locale=lang),
        ),
        _edit_prompt(
            '#penguin-forgot-password-form span',
            i18n.t('password.password_prompt', locale=lang),
        )
    ],
                         headers={'X-Drupal-Ajax-Token': 1})
Ejemplo n.º 11
0
def _make_name_suggestion(names, message):
    name_suggestion_template = env.get_template('name_suggestion.html')
    return ({
        'command':
        'insert',
        'selector':
        '#name-error',
        'method':
        'html',
        'data':
        name_suggestion_template.render(names=names, message=message)
    })
Ejemplo n.º 12
0
async def main_page(request):
    data = await Penguin.query.where(func.lower(Penguin.username) == request['session']['username']).gino.first()
    login_history = await Login.query.where(Login.penguin_id == data.id).order_by(Login.date.desc()).limit(5).gino.all()
    template = env.get_template('manager/panel.html')
    page = template.render(
        penguin=data,
        play_link=app.config.VANILLA_PLAY_LINK,
        login_history=login_history,
        success_message='',
        error_message='',
        site_key=app.config.GSITE_KEY
    )
    return response.html(page)
Ejemplo n.º 13
0
async def manage_page(request):
    template = env.get_template('manager/manage.html')
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request.ctx.session.get('username')
    ).gino.first()
    penguins = await Penguin.query.order_by(Penguin.registration_date.desc()
                                            ).gino.all()
    penguins = get_paginated_result(penguins)
    page = template.render(success_message='',
                           error_message='',
                           penguins=penguins,
                           penguin=data)
    return response.html(page)
Ejemplo n.º 14
0
async def search_username(request):
    template = env.get_template('manager/verify.html')
    query_string = request.body.decode('UTF-8')
    post_data = parse_qs(query_string)
    username = post_data.get('username', [None])[0]
    language = post_data.get('language', [None])[0]
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request['session']['username']
    ).gino.first()
    if not language:
        return response.text('You must provide a valid language.')
    elif not username:
        return response.text('You must provide a valid username.')
    if language == 'en':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_en == False) & (Penguin.rejection_en == False)
            & (Penguin.username.ilike(f"%{username}%"))).gino.all()
    elif language == 'de':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_de == False) & (Penguin.rejection_de == False)
            & (Penguin.username.ilike(f"%{username}%"))).gino.all()
    elif language == 'es':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_es == False) & (Penguin.rejection_es == False)
            & (Penguin.username.ilike(f"%{username}%"))).gino.all()
    elif language == 'fr':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_fr == False) & (Penguin.rejection_fr == False)
            & (Penguin.username.ilike(f"%{username}%"))).gino.all()
    elif language == 'pt':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_pt == False) & (Penguin.rejection_pt == False)
            & (Penguin.username.ilike(f"%{username}%"))).gino.all()
    elif language == 'ru':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_ru == False) & (Penguin.rejection_ru == False)
            & (Penguin.username.ilike(f"%{username}%"))).gino.all()
    else:
        language = 'en'
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_en == False) & (Penguin.rejection_en == False)
            & (Penguin.username.ilike(f"%{username}%"))).gino.all()
    unverified_penguins = get_paginated_result(unverified_penguins)
    page = template.render(
        success_message=f"Searched usernames similar to {username}.",
        error_message='',
        unverified_penguins=unverified_penguins,
        penguin=data,
        language=language)
    return response.html(page)
Ejemplo n.º 15
0
async def ban_player(request):
    query_string = request.body.decode('UTF-8')
    post_data = parse_qs(query_string)
    player_id = post_data.get('player', [None])[0]
    hours = post_data.get('hours', [None])[0]
    comment = post_data.get('comment', [None])[0]
    player = await Penguin.query.where(Penguin.id == int(player_id)
                                       ).gino.first()
    moderator = await Penguin.query.where(
        func.lower(Penguin.username) == request['session']['username']
    ).gino.first()
    if not player:
        return response.text('The player ID given does not exist.')
    number_bans = await db.select([db.func.count(Ban.penguin_id)]
                                  ).where(Ban.penguin_id == int(player.id)
                                          ).gino.scalar()
    date_issued = datetime.now()
    date_expires = date_issued + timedelta(hours=int(hours))
    if number_bans >= 3:
        await Penguin.update.values(permaban=True
                                    ).where(Penguin.id == player.id
                                            ).gino.status()
    await Ban.create(penguin_id=player.id,
                     issued=date_issued,
                     expires=date_expires,
                     moderator_id=moderator.id,
                     reason=2,
                     comment=comment,
                     message='')
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request['session']['username']
    ).gino.first()
    latest_ban = await get_latest_ban(player_id)
    bans = await get_bans(player_id)
    login_history = await get_login_history(player_id)
    template = env.get_template('manager/edit-player.html')
    page = template.render(success_message='Sucessfully inserted ban entry.',
                           error_message='',
                           play_link=app.config.VANILLA_PLAY_LINK,
                           player=player,
                           penguin=data,
                           latest_ban=latest_ban,
                           bans=bans,
                           connection_history=login_history)
    return response.html(page)
Ejemplo n.º 16
0
async def create_page(request, lang):
    base64_captchas = []
    captchas = random.sample(all_captchas, min(len(all_captchas), 3))
    captcha_answer = random.choice(captchas)[0]
    captcha_object = [
        captcha for captcha in captchas if captcha_answer in captcha
    ]

    if 'anon_token' not in request.ctx.session:
        anon_token = secrets.token_urlsafe(32)
        request.ctx.session['anon_token'] = anon_token

    request.ctx.session['captcha_answer'] = captchas.index(captcha_object[0])
    request.ctx.session['captcha'] = {'passed': 0}
    request.ctx.session['errors'] = {
        'name': True,
        'pass': True,
        'email': True,
        'terms': True,
        'captcha': True
    }

    request.ctx.session['captcha_answer'] = captchas.index(captcha_object[0])

    for captcha_image in captchas:
        captcha_encoded = lsb.hide(captcha_image[1].copy(),
                                   request.ctx.session['anon_token'])
        buffered = BytesIO()
        captcha_encoded.save(buffered, format='PNG')
        captcha_base64 = base64.b64encode(buffered.getvalue())
        base64_captchas.append(captcha_base64.decode('utf-8'))

    register_template = env.get_template(f'create/{lang}.html')
    page = register_template.render(
        VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
        anon_token=request.ctx.session['anon_token'],
        captcha_1=base64_captchas[0],
        captcha_2=base64_captchas[1],
        captcha_3=base64_captchas[2],
        captcha_answer=i18n.t(f'create.{captcha_answer}', locale=lang),
        site_key=app.config.GSITE_KEY)
    return response.html(page)
Ejemplo n.º 17
0
async def unban_player(request):
    query_string = request.body.decode('UTF-8')
    post_data = parse_qs(query_string)
    player_id = post_data.get('player', [None])[0]
    comment = post_data.get('comment', [None])[0]
    ban = await Ban.query.where((Ban.penguin_id == int(player_id))
                                & (Ban.comment == comment)).gino.first()
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request['session']['username']
    ).gino.first()
    player = await Penguin.query.where(Penguin.id == int(player_id)
                                       ).gino.first()
    latest_ban = await get_latest_ban(player_id)
    bans = await get_bans(player_id)
    login_history = await get_login_history(player_id)
    template = env.get_template('manager/edit-player.html')
    if not ban:
        page = template.render(
            success_message=
            'This ban does not exist based on the comment chosen and penguin ID given.',
            error_message='',
            play_link=app.config.VANILLA_PLAY_LINK,
            player=player,
            penguin=data,
            latest_ban=latest_ban,
            bans=bans,
            connection_history=login_history)
        return response.html(page)
    else:
        await Ban.delete.where((Ban.penguin_id == int(player_id))
                               & (Ban.comment == comment)).gino.status()
        page = template.render(success_message='Successfully removed ban.',
                               error_message='',
                               play_link=app.config.VANILLA_PLAY_LINK,
                               player=player,
                               penguin=data,
                               latest_ban=latest_ban,
                               bans=bans,
                               connection_history=login_history)
        return response.html(page)
Ejemplo n.º 18
0
async def search_player(request):
    template = env.get_template('manager/manage.html')
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request['session']['username']
    ).gino.first()
    query_string = request.body.decode('UTF-8')
    post_data = parse_qs(query_string)
    search_query = post_data.get('search_query', [None])[0]
    search_type = post_data.get('search_type', [None])[0]
    if search_query is None:
        return response.text('You must provide a valid search query.')
    elif search_type is None:
        return response.text('You must provide a valid search type.')
    if search_type == 'id':
        if not search_query.isdigit():
            return response.text('The ID given must be a number.')
        penguins = await Penguin.query.where(
            (Penguin.id == int(search_query))
        ).order_by(Penguin.registration_date.desc()).gino.all()
    elif search_type == 'username':
        penguins = await Penguin.query.where(
            (Penguin.username.ilike(f"%{search_query}%"))
        ).order_by(Penguin.registration_date.desc()).gino.all()
    elif search_type == 'email':
        penguins = await Penguin.query.where(
            (Penguin.email.ilike(f"%{search_query}%"))
        ).order_by(Penguin.registration_date.desc()).gino.all()
    else:
        penguins = await Penguin.query.where(
            (Penguin.username.ilike(f"%{search_query}%"))
        ).order_by(Penguin.registration_date.desc()).gino.all()
    penguins = get_paginated_result(penguins)
    page = template.render(
        success_message=
        f'Searched players based on your search query: {search_query}.',
        error_message='',
        penguins=penguins,
        penguin=data)
    return response.html(page)
Ejemplo n.º 19
0
async def verify_page(request, lang):
    template = env.get_template('manager/verify.html')
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request.ctx.session.get('username')
    ).gino.first()
    if lang == 'de':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_de == False)
            & (Penguin.rejection_de == False)).gino.all()
    elif lang == 'es':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_es == False)
            & (Penguin.rejection_es == False)).gino.all()
    elif lang == 'fr':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_fr == False)
            & (Penguin.rejection_fr == False)).gino.all()
    elif lang == 'pt':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_pt == False)
            & (Penguin.rejection_pt == False)).gino.all()
    elif lang == 'ru':
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_ru == False)
            & (Penguin.rejection_ru == False)).gino.all()
    else:
        lang = 'en'
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_en == False)
            & (Penguin.rejection_en == False)).gino.all()
    unverified_penguins = get_paginated_result(unverified_penguins)
    page = template.render(success_message='',
                           error_message='',
                           unverified_penguins=unverified_penguins,
                           penguin=data,
                           language=lang)
    return response.html(page)
Ejemplo n.º 20
0
async def _validate_registration(request, post_data, lang):
    username = post_data.get('name', [None])[0]
    password = post_data.get('pass', [None])[0]
    email = post_data.get('email', [None])[0]
    color = post_data.get('color', [None])[0]
    if 'username' not in request[
            'session'] or request['session']['username'] != username:
        return response.json({'message': '403 Forbidden'}, status=403)
    elif 'password' not in request[
            'session'] or request['session']['password'] != password:
        return response.json({'message': '403 Forbidden'}, status=403)
    elif 'email' not in request[
            'session'] or request['session']['email'] != email:
        return response.json({'message': '403 Forbidden'}, status=403)
    elif not color.isdigit() or int(color) not in range(1, 16):
        return response.json({'message': '403 Forbidden'}, status=403)

    if app.config.GSECRET_KEY:
        gclient_response = post_data.get('recaptcha_response', [None])[0]
        async with aiohttp.ClientSession() as session:
            async with session.post(app.config.GCAPTCHA_URL,
                                    data=dict(secret=app.config.GSECRET_KEY,
                                              response=gclient_response,
                                              remoteip=request.ip)) as resp:
                gresult = await resp.json()
                if not gresult['success']:
                    return response.text(urlencode({'error': gresult}))

    password = Crypto.hash(password).upper()
    password = Crypto.get_login_hash(password, rndk=app.config.STATIC_KEY)
    password = bcrypt.hashpw(password.encode('utf-8'),
                             bcrypt.gensalt(12)).decode('utf-8')

    if app.config.USERNAME_FORCE_CASE:
        username = username.title()

    penguin = await Penguin.create(username=username.lower(),
                                   nickname=username,
                                   password=password,
                                   email=email,
                                   color=int(color),
                                   approval_en=app.config.APPROVE_USERNAME,
                                   approval_pt=app.config.APPROVE_USERNAME,
                                   approval_fr=app.config.APPROVE_USERNAME,
                                   approval_es=app.config.APPROVE_USERNAME,
                                   approval_de=app.config.APPROVE_USERNAME,
                                   approval_ru=app.config.APPROVE_USERNAME,
                                   active=app.config.ACTIVATE_PLAYER)

    await PenguinItem.create(penguin_id=penguin.id, item_id=int(color))
    await PenguinPostcard.create(penguin_id=penguin.id,
                                 sender_id=None,
                                 postcard_id=125)

    if not app.config.ACTIVATE_PLAYER:
        activation_key = secrets.token_urlsafe(45)
        if lang == 'es':
            mail_template = env.get_template('es_vanilla_email.html')
        elif lang == 'pt':
            mail_template = env.get_template('pt_vanilla_email.html')
        elif lang == 'fr':
            mail_template = env.get_template('fr_vanilla_email.html')
        else:
            mail_template = env.get_template('en_vanilla_email.html')
        message = Mail(from_email=app.config.FROM_EMAIL,
                       to_emails=email,
                       subject=i18n.t('create.activate_mail_subject'),
                       html_content=mail_template.render(
                           penguin=penguin,
                           site_name=app.config.SITE_NAME,
                           activation_code=activation_key,
                           play_subdomain=app.config.PLAY_SUBDOMAIN,
                           activate_link=app.config.ACTIVATE_LINK))
        sg = SendGridAPIClient(app.config.SENDGRID_API_KEY)
        sg.send(message)
        await ActivationKey.create(penguin_id=penguin.id,
                                   activation_key=activation_key)

    return response.redirect(app.config.PLAY_SUBDOMAIN)
Ejemplo n.º 21
0
async def _validate_registration(request, lang):
    username = request.form.get('name', None)
    password = request.form.get('pass', None)
    email = request.form.get('email', None)
    color = request.form.get('color', None)
    if 'username' not in request.ctx.session or request.ctx.session[
            'username'] != username:
        return response.json({'message': '403 Forbidden'}, status=403)
    elif 'password' not in request.ctx.session or request.ctx.session[
            'password'] != password:
        return response.json({'message': '403 Forbidden'}, status=403)
    elif 'email' not in request.ctx.session or request.ctx.session[
            'email'] != email:
        return response.json({'message': '403 Forbidden'}, status=403)
    elif not color.isdigit() or int(color) not in range(1, 17):
        return response.json({'message': '403 Forbidden'}, status=403)
    elif app.config.GSECRET_KEY:
        gclient_response = request.form.get('recaptcha_response', None)
        async with aiohttp.ClientSession() as session:
            async with session.post(app.config.GCAPTCHA_URL,
                                    data=dict(secret=app.config.GSECRET_KEY,
                                              response=gclient_response,
                                              remoteip=request.ip)) as resp:
                gresult = await resp.json()
                if not gresult['success']:
                    return response.text(
                        'Your captcha score was low, please try again.')
    password = Crypto.hash(password).upper()
    password = Crypto.get_login_hash(password, rndk=app.config.STATIC_KEY)
    password = bcrypt.hashpw(password.encode('utf-8'),
                             bcrypt.gensalt(12)).decode('utf-8')

    username = username.strip()

    if app.config.USERNAME_FORCE_CASE:
        username = username.title()

    penguin = await Penguin.create(username=username.lower(),
                                   nickname=username,
                                   password=password,
                                   email=email,
                                   color=int(color),
                                   approval_en=app.config.APPROVE_USERNAME,
                                   approval_pt=app.config.APPROVE_USERNAME,
                                   approval_fr=app.config.APPROVE_USERNAME,
                                   approval_es=app.config.APPROVE_USERNAME,
                                   approval_de=app.config.APPROVE_USERNAME,
                                   approval_ru=app.config.APPROVE_USERNAME,
                                   active=app.config.ACTIVATE_PLAYER)

    await PenguinItem.create(penguin_id=penguin.id, item_id=int(color))
    await PenguinPostcard.create(penguin_id=penguin.id,
                                 sender_id=None,
                                 postcard_id=125)

    if not app.config.ACTIVATE_PLAYER:
        activation_key = secrets.token_urlsafe(45)
        mail_template = env.get_template(
            f'emails/activation/vanilla/{lang}.html')
        message = Mail(
            from_email=app.config.FROM_EMAIL,
            to_emails=email,
            subject=i18n.t('activate.mail_subject', locale=lang),
            html_content=mail_template.render(
                penguin=penguin,
                site_name=app.config.SITE_NAME,
                activation_code=activation_key,
                VANILLA_PLAY_LINK=app.config.VANILLA_PLAY_LINK,
                activate_link=
                f'{app.config.VANILLA_PLAY_LINK}/{lang}/penguin/activate'))
        sg = SendGridAPIClient(app.config.SENDGRID_API_KEY)
        sg.send(message)
        await ActivationKey.create(penguin_id=penguin.id,
                                   activation_key=activation_key)
    return response.redirect(app.config.VANILLA_PLAY_LINK)
Ejemplo n.º 22
0
async def password_request(request):
    old_password = request.form.get('old_password', None)
    password = request.form.get('password', None)
    password_confirm = request.form.get('password_confirm', None)
    template = env.get_template('manager/password.html')
    if app.config.GSECRET_KEY:
        gclient_response = request.form.get('recaptcha_response', None)
        async with aiohttp.ClientSession() as session:
            async with session.post(app.config.GCAPTCHA_URL,
                                    data=dict(secret=app.config.GSECRET_KEY,
                                              response=gclient_response,
                                              remoteip=request.ip)) as resp:
                gresult = await resp.json()
                if not gresult['success']:
                    page = template.render(
                        success_message='',
                        error_message=
                        'Your captcha score was low. Please try again.',
                        site_key=app.config.GSITE_KEY)
                    return response.html(page)

    if not old_password:
        page = template.render(
            success_message='',
            error_message='You must provide your old password.',
            site_key=app.config.GSITE_KEY)
        return response.html(page)
    elif not password or not password_confirm:
        page = template.render(
            success_message='',
            error_message='You must provide a new password.',
            site_key=app.config.GSITE_KEY)
        return response.html(page)
    elif len(password) < 5 or len(password) < 5:
        page = template.render(
            success_message='',
            error_message='Your new password must be more than 5 characters..',
            site_key=app.config.GSITE_KEY)
        return response.html(page)
    elif password != password_confirm:
        page = template.render(success_message='',
                               error_message='Your new passwords must match.',
                               site_key=app.config.GSITE_KEY)
        return response.html(page)
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request.ctx.session.get('username')
    ).gino.first()
    loop = asyncio.get_event_loop()

    old_password = Crypto.hash(old_password).upper()
    old_password = Crypto.get_login_hash(old_password,
                                         rndk=app.config.STATIC_KEY)
    password_correct = await loop.run_in_executor(
        None, bcrypt.checkpw, old_password.encode('utf-8'),
        data.password.encode('utf-8'))

    if not password_correct:
        page = template.render(success_message='',
                               error_message='Your old password is incorrect.',
                               site_key=app.config.GSITE_KEY)
        return response.html(page)

    password = Crypto.hash(password).upper()
    password = Crypto.get_login_hash(password, rndk=app.config.STATIC_KEY)
    password = bcrypt.hashpw(password.encode('utf-8'),
                             bcrypt.gensalt(12)).decode('utf-8')
    await Penguin.update.values(password=password).where(Penguin.id == data.id
                                                         ).gino.status()
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request.ctx.session.get('username')
    ).gino.first()
    login_history = await Login.query.where(Login.penguin_id == data.id
                                            ).order_by(Login.date.desc()
                                                       ).limit(5).gino.all()
    template = env.get_template('manager/panel.html')
    page = template.render(
        penguin=data,
        play_link=app.config.VANILLA_PLAY_LINK,
        login_history=login_history,
        success_message='You have successfully updated your password.',
        error_message='',
        site_key=app.config.GSITE_KEY)
    return response.html(page)
Ejemplo n.º 23
0
async def update_player(request):
    player_id = request.form.get('player', None)
    type = request.form.get('type', None)
    template = env.get_template('manager/edit-player.html')
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request.ctx.session.get('username')
    ).gino.first()
    player = await Penguin.query.where(Penguin.id == int(player_id)
                                       ).gino.first()
    if player is None:
        return response.redirect('/manager/manage')
    latest_ban = await get_latest_ban(player_id)
    bans = await get_bans(player_id)
    login_history = await get_login_history(player_id)
    if type is None:
        page = template.render(
            success_message='',
            error_message='You must provide a valid column to update.',
            play_link=app.config.VANILLA_PLAY_LINK,
            player=player,
            penguin=data,
            latest_ban=latest_ban,
            bans=bans,
            connection_history=login_history)
        return response.html(page)
    if type == 'id':
        id = request.form.get('id', None)
        if not id:
            page = template.render(success_message='',
                                   error_message='You must provide an ID.',
                                   play_link=app.config.VANILLA_PLAY_LINK,
                                   player=player,
                                   penguin=data,
                                   latest_ban=latest_ban,
                                   bans=bans,
                                   connection_history=login_history)
            return response.html(page)
        if not id.isdigit():
            page = template.render(success_message='',
                                   error_message='Value must be an integer.',
                                   play_link=app.config.VANILLA_PLAY_LINK,
                                   player=player,
                                   penguin=data,
                                   latest_ban=latest_ban,
                                   bans=bans,
                                   connection_history=login_history)
            return response.html(page)
        id_exists = await Penguin.query.where(Penguin.id == int(id)
                                              ).gino.first()
        if id_exists:
            page = template.render(
                success_message='',
                error_message=
                'This penguin ID is already taken, please try another one.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        await Penguin.update.values(id=int(id)).where(Penguin.id == player.id
                                                      ).gino.status()
        player = await Penguin.query.where(Penguin.id == int(id)).gino.first()
        page = template.render(success_message='Successfully updated ID.',
                               error_message='',
                               play_link=app.config.VANILLA_PLAY_LINK,
                               player=player,
                               penguin=data,
                               latest_ban=latest_ban,
                               bans=bans,
                               connection_history=login_history)
        return response.html(page)
    elif type == 'username':
        username = request.form.get('username', None)
        if not username:
            page = template.render(
                success_message='',
                error_message='You must provide a username.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        if len(username) < 4 or len(username) > 12:
            page = template.render(
                success_message='',
                error_message=
                'The username length must be between 4-12 characters.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        username_exists = await Penguin.query.where(
            Penguin.username == username).gino.first()
        if username_exists:
            page = template.render(
                success_message='',
                error_message=
                'This username is already taken, please try another one.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        await Penguin.update.values(username=username
                                    ).where(Penguin.id == player.id
                                            ).gino.status()
        player = await Penguin.query.where(Penguin.id == player.id
                                           ).gino.first()
        page = template.render(
            success_message='Successfully updated username.',
            error_message='',
            play_link=app.config.VANILLA_PLAY_LINK,
            player=player,
            penguin=data,
            latest_ban=latest_ban,
            bans=bans,
            connection_history=login_history)
        return response.html(page)
    elif type == 'nickname':
        nickname = request.form.get('nickname', None)
        if not nickname:
            page = template.render(
                success_message='',
                error_message='You must provide a nickname.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        if len(nickname) < 1 or len(nickname) > 30:
            page = template.render(
                success_message='',
                error_message=
                'The nickname length must be at least 1 or more characters and below 30 characters.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        await Penguin.update.values(nickname=nickname
                                    ).where(Penguin.id == player.id
                                            ).gino.status()
        player = await Penguin.query.where(Penguin.id == player.id
                                           ).gino.first()
        page = template.render(
            success_message='Successfully updated nickname.',
            error_message='',
            play_link=app.config.VANILLA_PLAY_LINK,
            player=player,
            penguin=data,
            latest_ban=latest_ban,
            bans=bans,
            connection_history=login_history)
        return response.html(page)
    elif type == 'password':
        password = request.form.get('password', None)
        if not password:
            page = template.render(
                success_message='',
                error_message='You must provide a new password.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        password = Crypto.hash(password).upper()
        password = Crypto.get_login_hash(password, rndk=app.config.STATIC_KEY)
        password = bcrypt.hashpw(password.encode('utf-8'),
                                 bcrypt.gensalt(12)).decode('utf-8')
        await Penguin.update.values(password=password
                                    ).where(Penguin.id == player.id
                                            ).gino.status()
        page = template.render(
            success_message='Successfully updated password.',
            error_message='',
            play_link=app.config.VANILLA_PLAY_LINK,
            player=player,
            penguin=data,
            latest_ban=latest_ban,
            bans=bans,
            connection_history=login_history)
        return response.html(page)
    elif type == 'email':
        email = request.form.get('email', None)
        if not email:
            page = template.render(success_message='',
                                   error_message='You must provide an email.',
                                   play_link=app.config.VANILLA_PLAY_LINK,
                                   player=player,
                                   penguin=data,
                                   latest_ban=latest_ban,
                                   bans=bans,
                                   connection_history=login_history)
            return response.html(page)
        _, email = parseaddr(email)
        if not email or '@' not in email:
            page = template.render(
                success_message='',
                error_message='You must enter a valid email.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        email_count = await db.select([
            db.func.count(Penguin.email)
        ]).where(db.func.lower(Penguin.email) == email.lower()).gino.scalar()
        if email_count >= app.config.MAX_ACCOUNT_EMAIL:
            page = template.render(
                success_message='',
                error_message=
                f'There are more than ${app.config.MAX_ACCOUNT_EMAIL} '
                f'emails under this address. Please try another email address.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        await Penguin.update.values(email=email).where(Penguin.id == player.id
                                                       ).gino.status()
        player = await Penguin.query.where(Penguin.id == player.id
                                           ).gino.first()
        page = template.render(success_message='Successfully updated email.',
                               error_message='',
                               play_link=app.config.VANILLA_PLAY_LINK,
                               player=player,
                               penguin=data,
                               latest_ban=latest_ban,
                               bans=bans,
                               connection_history=login_history)
        return response.html(page)
    elif type == 'coins':
        coins = request.form.get('coins', None)
        if not coins:
            page = template.render(
                success_message='',
                error_message='You must provide an amount of coins.',
                play_link=app.config.VANILLA_PLAY_LINK,
                player=player,
                penguin=data,
                latest_ban=latest_ban,
                bans=bans,
                connection_history=login_history)
            return response.html(page)
        if not coins.isdigit():
            page = template.render(success_message='',
                                   error_message='Value must be an integer.',
                                   play_link=app.config.VANILLA_PLAY_LINK,
                                   player=player,
                                   penguin=data,
                                   latest_ban=latest_ban,
                                   bans=bans,
                                   connection_history=login_history)
            return response.html(page)
        await Penguin.update.values(coins=int(coins)
                                    ).where(Penguin.id == player.id
                                            ).gino.status()
        player = await Penguin.query.where(Penguin.id == player.id
                                           ).gino.first()
        page = template.render(success_message='Updated amount of coins.',
                               error_message='',
                               play_link=app.config.VANILLA_PLAY_LINK,
                               player=player,
                               penguin=data,
                               latest_ban=latest_ban,
                               bans=bans,
                               connection_history=login_history)
        return response.html(page)
    elif type == 'moderator':
        if player.moderator:
            await Penguin.update.values(moderator=False
                                        ).where(Penguin.id == player.id
                                                ).gino.status()
        else:
            await Penguin.update.values(moderator=True
                                        ).where(Penguin.id == player.id
                                                ).gino.status()
        player = await Penguin.query.where(Penguin.id == player.id
                                           ).gino.first()
        page = template.render(success_message='Updated moderator status.',
                               error_message='',
                               play_link=app.config.VANILLA_PLAY_LINK,
                               player=player,
                               penguin=data,
                               latest_ban=latest_ban,
                               bans=bans,
                               connection_history=login_history)
        return response.html(page)
    elif type == 'permaban':
        await Penguin.update.values(permaban=True
                                    ).where(Penguin.id == player.id
                                            ).gino.status()
        player = await Penguin.query.where(Penguin.id == player.id
                                           ).gino.first()
        page = template.render(success_message='Successfully banned user..',
                               error_message='',
                               play_link=app.config.VANILLA_PLAY_LINK,
                               player=player,
                               penguin=data,
                               latest_ban=latest_ban,
                               bans=bans,
                               connection_history=login_history)
        return response.html(page)
    elif type == 'unban':
        await Penguin.update.values(permaban=False
                                    ).where(Penguin.id == player.id
                                            ).gino.status()
        player = await Penguin.query.where(Penguin.id == player.id
                                           ).gino.first()
        page = template.render(success_message='Successfully unbanned user.',
                               error_message='',
                               play_link=app.config.VANILLA_PLAY_LINK,
                               player=player,
                               penguin=data,
                               latest_ban=latest_ban,
                               bans=bans,
                               connection_history=login_history)
        return response.html(page)
    else:
        page = template.render(
            success_message='You must provide a valid column to update.',
            error_message='',
            play_link=app.config.VANILLA_PLAY_LINK,
            player=player,
            penguin=data,
            latest_ban=latest_ban,
            bans=bans,
            connection_history=login_history)
        return response.html(page)
Ejemplo n.º 24
0
async def email_request(request):
    email = request.form.get('email', None)
    email_confirm = request.form.get('email_confirm', None)
    template = env.get_template('manager/email.html')
    if app.config.GSECRET_KEY:
        gclient_response = request.form.get('recaptcha_response', None)
        async with aiohttp.ClientSession() as session:
            async with session.post(app.config.GCAPTCHA_URL,
                                    data=dict(secret=app.config.GSECRET_KEY,
                                              response=gclient_response,
                                              remoteip=request.ip)) as resp:
                gresult = await resp.json()
                if not gresult['success']:
                    page = template.render(
                        success_message='',
                        error_message=
                        'Your captcha score was low. Please try again.',
                        site_key=app.config.GSITE_KEY)
                    return response.html(page)

    elif not email or not email_confirm:
        page = template.render(success_message='',
                               error_message='You must provide your email.',
                               site_key=app.config.GSITE_KEY)
        return response.html(page)
    _, email = parseaddr(email)
    domain = email.rsplit('@', 1)[-1]
    if not email or '@' not in email:
        page = template.render(success_message='',
                               error_message='You must enter a valid email.',
                               site_key=app.config.GSITE_KEY)
        return response.html(page)
    elif app.config.EMAIL_WHITELIST and domain not in app.config.EMAIL_WHITELIST:
        page = template.render(
            success_message='',
            error_message=
            'You must enter an email provider that is whitelisted from out system.',
            site_key=app.config.GSITE_KEY)
        return response.html(page)

    email_count = await db.select([
        db.func.count(Penguin.email)
    ]).where(db.func.lower(Penguin.email) == email.lower()).gino.scalar()

    if email_count >= app.config.MAX_ACCOUNT_EMAIL:
        page = template.render(
            success_message='',
            error_message=f'There are more than ${app.config.MAX_ACCOUNT_EMAIL} '
            f'emails under this address. Please try another email address.',
            site_key=app.config.GSITE_KEY)
        return response.html(page)

    await Penguin.update.values(email=email).where(
        Penguin.username == request['session']['username']).gino.status()
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request['session']['username']
    ).gino.first()
    login_history = await Login.query.where(Login.penguin_id == data.id
                                            ).order_by(Login.date.desc()
                                                       ).limit(5).gino.all()
    template = env.get_template('manager/panel.html')
    page = template.render(
        penguin=data,
        play_link=app.config.VANILLA_PLAY_LINK,
        login_history=login_history,
        success_message='You have successfully updated your email.',
        error_message='',
        site_key=app.config.GSITE_KEY)
    return response.html(page)
Ejemplo n.º 25
0
async def login_request(request):
    username = request.form.get('username', None)
    username = username.lower()
    password = request.form.get('password', None)
    loop = asyncio.get_event_loop()
    template = env.get_template('manager/login.html')
    if app.config.GSECRET_KEY:
        gclient_response = request.form.get('recaptcha_response', None)
        async with aiohttp.ClientSession() as session:
            async with session.post(app.config.GCAPTCHA_URL, data=dict(
                secret=app.config.GSECRET_KEY,
                response=gclient_response,
                remoteip=request.ip
            )) as resp:
                gresult = await resp.json()
                if not gresult['success']:
                    page = template.render(
                        success_message='',
                        error_message='Your captcha score was low. Please try again.',
                        site_key=app.config.GSITE_KEY
                    )
                    return response.html(page)
    if not username:
        page = template.render(
            success_message='',
            error_message='You must provide a username.',
            site_key=app.config.GSITE_KEY
        )
        return response.html(page)
    elif not password:
        page = template.render(
            success_message='',
            error_message='You must provide a password.',
            site_key=app.config.GSITE_KEY
        )
        return response.html(page)

    data = await Penguin.query.where(func.lower(Penguin.username) == username).gino.first()
    if data is None:
        page = template.render(
            success_message='',
            error_message='Your penguin was not found.',
            site_key=app.config.GSITE_KEY
        )
        return response.html(page)

    password = Crypto.hash(password).upper()
    password = Crypto.get_login_hash(password, rndk=app.config.STATIC_KEY)
    password_correct = await loop.run_in_executor(None, bcrypt.checkpw,
                                                  password.encode('utf-8'),
                                                  data.password.encode('utf-8'))
    flood_key = f'{request.ip}.flood'
    if not password_correct:
        if await app.ctx.redis.exists(flood_key):
            async with app.ctx.redis.pipeline(transaction=True) as tr:
                tr.incr(flood_key)
                tr.expire(flood_key, app.config.LOGIN_FAILURE_TIMER)
                failure_count, _ = await tr.execute()
            if failure_count >= app.config.LOGIN_FAILURE_LIMIT:
                page = template.render(
                    success_message='',
                    error_message='Maximum login attempts exceeded. Please try again in an hour.',
                    site_key=app.config.GSITE_KEY
                )
                return response.html(page)
        else:
            await app.ctx.redis.setex(flood_key, app.config.LOGIN_FAILURE_TIMER, 1)
        page = template.render(
            success_message='',
            error_message='You have entered an incorrect password.',
            site_key=app.config.GSITE_KEY
        )
        return response.html(page)

    failure_count = await app.ctx.redis.get(flood_key)
    if failure_count:
        max_attempts_exceeded = int(failure_count) >= app.config.LOGIN_FAILURE_LIMIT
        if max_attempts_exceeded:
            page = template.render(
                success_message='',
                error_message='Maximum login attempts exceeded. Please try again in an hour.',
                site_key=app.config.GSITE_KEY
            )
            return response.html(page)
        else:
            await app.ctx.redis.delete(flood_key)
    if not data.active:
        page = template.render(
            success_message='',
            error_message='Your account has not been activated.',
            site_key=app.config.GSITE_KEY
        )
        return response.html(page)
    if data.permaban:
        page = template.render(
            success_message='',
            error_message='You are banned forever.',
            site_key=app.config.GSITE_KEY
        )
        return response.html(page)
    if not data.moderator:
        page = template.render(
            success_message='',
            error_message='You do not have permission to access this panel.',
            site_key=app.config.GSITE_KEY
        )
        return response.html(page)

    active_ban = await Ban.query.where((Ban.penguin_id == data.id) & (Ban.expires >= datetime.now())).gino.first()
    if active_ban is not None:
        hours_left = round((active_ban.expires - datetime.now()).total_seconds() / 60 / 60)
        page = template.render(
            success_message='',
            error_message=f'You are banned for the next {hours_left} hours.',
            site_key=app.config.GSITE_KEY
        )
        return response.html(page)
    request.ctx.session['username'] = username
    request.ctx.session['logged_in'] = True
    return response.redirect('/manager')
Ejemplo n.º 26
0
async def reject_request(request, penguin_id):
    template = env.get_template('manager/verify.html')
    language = request.form.get('language', None)
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request.ctx.session.get('username')
    ).gino.first()
    penguin = await Penguin.query.where(Penguin.id == int(penguin_id)
                                        ).gino.first()
    if not language:
        return response.text('You must provide a valid language.')
    if not penguin:
        return response.text('You must provide a valid penguin ID.')
    if language == 'en':
        await Penguin.update.values(rejection_en=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_en == False)
            & (Penguin.rejection_en == False)).gino.all()
    elif language == 'de':
        await Penguin.update.values(rejection_de=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_de == False)
            & (Penguin.rejection_de == False)).gino.all()
    elif language == 'es':
        await Penguin.update.values(rejection_es=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_es == False)
            & (Penguin.rejection_es == False)).gino.all()
    elif language == 'fr':
        await Penguin.update.values(rejection_fr=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_fr == False)
            & (Penguin.rejection_fr == False)).gino.all()
    elif language == 'pt':
        await Penguin.update.values(rejection_pt=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_pt == False)
            & (Penguin.rejection_pt == False)).gino.all()
    elif language == 'ru':
        await Penguin.update.values(rejection_ru=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_ru == False)
            & (Penguin.rejection_ru == False)).gino.all()
    else:
        language = 'en'
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_en == False)
            & (Penguin.rejection_en == False)).gino.all()
    unverified_penguins = get_paginated_result(unverified_penguins)
    page = template.render(
        success_message=f"Successfully rejected {penguin.username}'s username.",
        error_message='',
        unverified_penguins=unverified_penguins,
        penguin=data,
        language=language)
    return response.html(page)
Ejemplo n.º 27
0
async def validate_password_email(request):
    session_id = request.form.get('sid')
    username = request.ctx.session.get('username', None)
    color = request.ctx.session.get('color', '0')
    password = request.form.get('password', '')
    password_confirm = request.form.get('password_confirm', '')
    email = request.form.get('email', '')
    lang = request.form.get('lang', 'en')

    if session_id != request.ctx.session.get('sid'):
        return response.text(
            urlencode({'error': i18n.t('create.passwords_match',
                                       locale=lang)}))

    if app.config.GSECRET_KEY:
        gclient_response = request.form.get('gtoken', '')
        async with aiohttp.ClientSession() as session:
            async with session.post(app.config.GCAPTCHA_URL,
                                    data=dict(secret=app.config.GSECRET_KEY,
                                              response=gclient_response,
                                              remoteip=request.ip)) as resp:
                gresult = await resp.json()
                if not gresult['success']:
                    return response.text(urlencode({'error': gresult}))

    if username is None or color is None:
        return response.text(urlencode({'error': ''}))
    elif str(password) != str(password_confirm):
        return response.text(
            urlencode({'error': i18n.t('create.passwords_match',
                                       locale=lang)}))
    elif len(password) < 4:
        return response.text(
            urlencode({'error': i18n.t('create.password_short', locale=lang)}))

    _, email = parseaddr(email)
    domain = email.rsplit('@', 1)[-1]
    if not email or '@' not in email:
        return response.text(
            urlencode({'error': i18n.t('create.email_invalid', locale=lang)}))
    elif app.config.EMAIL_WHITELIST and domain not in app.config.EMAIL_WHITELIST:
        return response.text(
            urlencode({'error': i18n.t('create.email_invalid', locale=lang)}))

    email_count = await db.select([
        db.func.count(Penguin.email)
    ]).where(db.func.lower(Penguin.email) == email.lower()).gino.scalar()
    if email_count >= app.config.MAX_ACCOUNT_EMAIL:
        return response.text(
            urlencode({'error': i18n.t('create.email_invalid', locale=lang)}))

    password = Crypto.hash(password).upper()
    password = Crypto.get_login_hash(password, rndk=app.config.STATIC_KEY)
    password = bcrypt.hashpw(password.encode('utf-8'),
                             bcrypt.gensalt(12)).decode('utf-8')

    username = username.strip()
    if app.config.USERNAME_FORCE_CASE:
        username = username.title()

    penguin = await Penguin.create(username=username.lower(),
                                   nickname=username,
                                   password=password,
                                   email=email,
                                   color=int(color),
                                   approval_en=app.config.APPROVE_USERNAME,
                                   approval_pt=app.config.APPROVE_USERNAME,
                                   approval_fr=app.config.APPROVE_USERNAME,
                                   approval_es=app.config.APPROVE_USERNAME,
                                   approval_de=app.config.APPROVE_USERNAME,
                                   approval_ru=app.config.APPROVE_USERNAME,
                                   active=app.config.ACTIVATE_PLAYER)

    await PenguinItem.create(penguin_id=penguin.id, item_id=int(color))
    await PenguinPostcard.create(penguin_id=penguin.id,
                                 sender_id=None,
                                 postcard_id=125)

    if not app.config.ACTIVATE_PLAYER:
        activation_key = secrets.token_urlsafe(45)

        mail_template = env.get_template(
            f'emails/activation/legacy/{lang}.html')
        message = Mail(
            from_email=app.config.FROM_EMAIL,
            to_emails=email,
            subject=i18n.t('activate.mail_subject', locale=lang),
            html_content=mail_template.render(
                penguin=penguin,
                site_name=app.config.SITE_NAME,
                activate_link=
                f'{app.config.LEGACY_PLAY_LINK}/penguin/activate/{activation_key}'
            ))
        sg = SendGridAPIClient(app.config.SENDGRID_API_KEY)
        sg.send(message)
        await ActivationKey.create(penguin_id=penguin.id,
                                   activation_key=activation_key)

    return response.text(urlencode({'success': 1}))
Ejemplo n.º 28
0
async def approve_request(request, penguin_id):
    template = env.get_template('manager/verify.html')
    query_string = request.body.decode('UTF-8')
    post_data = parse_qs(query_string)
    language = post_data.get('language', [None])[0]
    data = await Penguin.query.where(
        func.lower(Penguin.username) == request['session']['username']
    ).gino.first()
    penguin = await Penguin.query.where(Penguin.id == int(penguin_id)
                                        ).gino.first()
    if not language:
        return response.text('You must provide a valid language.')
    if not penguin:
        return response.text('You must provide a valid penguin ID.')
    if language == 'en':
        await Penguin.update.values(approval_en=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_en == False)
            & (Penguin.rejection_en == False)).gino.all()
    elif language == 'de':
        await Penguin.update.values(approval_de=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_de == False)
            & (Penguin.rejection_de == False)).gino.all()
    elif language == 'es':
        await Penguin.update.values(approval_es=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_es == False)
            & (Penguin.rejection_es == False)).gino.all()
    elif language == 'fr':
        await Penguin.update.values(approval_fr=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_fr == False)
            & (Penguin.rejection_fr == False)).gino.all()
    elif language == 'pt':
        await Penguin.update.values(approval_pt=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_pt == False)
            & (Penguin.rejection_pt == False)).gino.all()
    elif language == 'ru':
        await Penguin.update.values(approval_ru=True
                                    ).where(Penguin.id == penguin.id
                                            ).gino.status()
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_ru == False)
            & (Penguin.rejection_ru == False)).gino.all()
    else:
        language = 'en'
        unverified_penguins = await Penguin.query.where(
            (Penguin.approval_en == False)
            & (Penguin.rejection_en == False)).gino.all()
    unverified_penguins = get_paginated_result(unverified_penguins)
    page = template.render(
        success_message=f"Successfully approved {penguin.username}'s username.",
        error_message='',
        unverified_penguins=unverified_penguins,
        penguin=data,
        language=language)
    return response.html(page)