Esempio n. 1
0
def headless_theatre_view(env, get_vars, post_vars, csrf_clerk, session, user):
    page_data = basic_page_data('theatre-headless')
    status = '200 OK'
    given_password = post_vars.get('theatre_password', [''])[0]
    theatre_password = get_property('theatre_password', None)
    if (user is not None or given_password == theatre_password
            or patreon.validate_session(env)):
        page_data['chat_uri'] = turbo_views['chat-headless'].path
        page_data['youtube_stream_id'] = get_property('theatre_stream_id')
        response_body = templates.render('youtube_embed', page_data)
    else:
        callback_view = turbo_views['patreon-theatre-callback']
        redirect_uri = callback_view.uri
        oauth = turbo_session.OAuth2Session(config.patreon.client_id,
                                            redirect_uri=redirect_uri,
                                            scope=config.patreon.scope)
        authorization_url, state = oauth.authorization_url(
            config.patreon.authorize_url,
            turbo_session.generate_state(env, csrf_clerk))
        page_data['patreon_authorization_uri'] = authorization_url
        page_data['form_action'] = turbo_views['theatre-headless'].path
        page_data['login_uri'] = util.build_url(
            turbo_views['login'].path,
            query={'redirect_to': turbo_views['theatre'].path})
        response_body = templates.render('theatre_auth', page_data)
    response_headers = util.basic_response_header(response_body)
    return response_body, response_headers, status
Esempio n. 2
0
def account_view(env, get_vars, post_vars, csrf_clerk, session, user):
    page_data = basic_page_data('account')
    # Reset app_password if requested
    if post_vars.get('reset_app_password', [0])[0] == '1':
        csrf_token = post_vars.get('csrf_token', [''])[0]
        if csrf_clerk.validate(session, csrf_token):
            # silently failing on an invalid token is fine here
            user.reset_app_password()
    status = '200 OK'
    page_data['nav'] = turbo_nav.generate_html('account', user, expanded=True)
    page_data['form_action'] = turbo_views['account'].path
    page_data['username'] = user.username
    page_data['avatar_src'] = user.account.get('avatar', '')
    page_data['app_password'] = user.app_password_plain
    page_data['csrf_token'] = csrf_clerk.register(session)
    discord_member = discord.get_member(user.discord_id)
    discord_user = discord.get_user(discord_member)
    redirect_uri = turbo_views['discord-callback'].uri
    oauth = turbo_session.OAuth2Session(config.discord.client_id,
                                        redirect_uri=redirect_uri,
                                        scope=config.discord.scope)
    authorization_url, state = oauth.authorization_url(
        config.discord.authorize_url,
        turbo_session.generate_state(env, csrf_clerk))
    page_data['discord_username'] = discord.render_username(discord_user)
    page_data['discord_roles'] = discord.render_roles(discord_member)
    page_data['discord_avatar_src'] = discord.get_avatar_url(discord_user)
    page_data['authorization_url'] = authorization_url
    response_body = templates.render('account', page_data)
    response_headers = util.basic_response_header(response_body)
    return response_body, response_headers, status
Esempio n. 3
0
def discord_callback_view(env, get_vars, post_vars, csrf_clerk, session, user):
    redirect_uri = turbo_views['discord-callback'].uri
    authorization_response = redirect_uri + '?' + env['QUERY_STRING']
    discord_user_url = config.discord.api_endpoint + '/users/@me'
    access_level = User.get_access_level(user)
    try:
        oauth = turbo_session.OAuth2Session(config.discord.client_id,
                                            redirect_uri=redirect_uri,
                                            scope=config.discord.scope)
        oauth_state = turbo_session.retrieve_oauth_state(
            get_vars.get('state', [''])[0])
        if oauth_state and csrf_clerk.validate('oauth-authorization',
                                               oauth_state[0]):
            token = oauth.fetch_token(
                config.discord.token_url,
                authorization_response=authorization_response,
                client_secret=config.discord.client_secret)
            discord_user = oauth.get(discord_user_url).json()
            if discord_user is not None and discord_user.get('id') is not None:
                # If people link their discord to another account,
                # the old one should lose its turbo role
                discord_id = int(discord_user['id'])
                if user.discord_id and user.discord_id != discord_id:
                    if not discord.remove_turbo_role(user.discord_id):
                        return error_view(
                            'Unexpected error',
                            'Failed to reassign TURBO status to '
                            'a different Discord account. '
                            'Please try again.')
                user.set_discord_id(discord_id)
                discord.add_turbo_role(discord_id, token)

                redirect_to = str(oauth_state[1])
                if redirect_to.startswith('/'):
                    redirect_to = util.build_url(redirect_to)

                status = '307 Temporary Redirect'
                response_body = ''
                response_headers = [('Location', redirect_to)]
            else:
                return error_view('Unexpected error',
                                  'Failed to retrieve Discord user details.',
                                  access_level=access_level)
        else:
            return error_view('CSRF Verfication failed',
                              'Failed to authorize Discord account due to a '
                              'CSRF verfication error, try again.',
                              access_level=access_level)

    except OAuth2Error as error:
        # Might indicate a "deny" on granting access to the app
        logger.info(f'OAuth 2.0 Error occured: {error}',
                    exc_info=config.debug_mode)
        return error_view('OAuth Error',
                          'Failed to authorize Discord account, try again.',
                          access_level=access_level)
    else:
        # Normal function return without errors
        return response_body, response_headers, status
Esempio n. 4
0
        def decorated_function(env, csrf_clerk):
            get_vars = util.retrieve_get_vars(env)
            post_vars = util.retrieve_post_vars(env)
            session = turbo_session.get_session(env)
            account = turbo_session.retrieve_oauth_account(session)

            # Start OAuth
            cookie_set = int(get_vars.get('cookie_set', [0])[0])
            # Failed to set cookie, tell user to enable cookies
            if(account is None and min_access_level >= ACL.turbo and
               cookie_set == 1):
                return error_view('Login Error',
                                  'Failed to create session. Try to enable '
                                  ' cookies for this site.')

            elif(account is None and min_access_level >= ACL.turbo):
                # Show Auth Error in headless mode
                if(headless):
                    return error_view('Auth Error', 'You are not logged in.',
                                      nav, headless=True)

                redirect_uri = turbo_views['oauth-callback'].uri
                oauth = turbo_session.OAuth2Session(
                    config.mastodon.client_id,
                    redirect_uri=redirect_uri,
                    scope=config.mastodon.scope)
                authorization_url, state = oauth.authorization_url(
                    config.mastodon.authorize_url,
                    turbo_session.generate_state(env, csrf_clerk)
                )

                status = '307 Temporary Redirect'
                response_body = ''
                response_headers = [('Location', str(authorization_url))]

            # Redirect to url without cookie_set parameter
            elif(cookie_set == 1):
                status = '307 Temporary Redirect'
                response_body = ''
                response_headers = [
                    ('Location', util.build_url(env['PATH_INFO']))
                ]

            # Display View
            else:
                user = User.create(account)
                access_level = User.get_access_level(user)
                if access_level < min_access_level:
                    return error_view('Missing Privileges',
                                      'You do not have the required '
                                      'permissions to access this.',
                                      access_level=access_level)
                response_body, response_headers, status = func(
                    env, get_vars, post_vars, csrf_clerk, session, user
                )

            return response_body, response_headers, status
Esempio n. 5
0
def oauth_callback_view(env, csrf_clerk):
    get_vars = util.retrieve_get_vars(env)
    redirect_uri = turbo_views['oauth-callback'].uri
    authorization_response = redirect_uri + '?' + env['QUERY_STRING']
    try:
        oauth = turbo_session.OAuth2Session(
            config.mastodon.client_id,
            redirect_uri=redirect_uri,
            scope=config.mastodon.scope
        )
        oauth_state = turbo_session.retrieve_oauth_state(
            get_vars.get('state', [''])[0]
        )
        if(oauth_state and
           csrf_clerk.validate('oauth-authorization', oauth_state[0])):
            token = oauth.fetch_token(
                config.mastodon.token_url,
                authorization_response=authorization_response,
                client_secret=config.mastodon.client_secret
            )
            session_token = turbo_session.create_session(token)

            if(session_token is not None):
                redirect_to = str(oauth_state[1])
                if redirect_to.startswith('/'):
                    redirect_to = util.build_url(redirect_to,
                                                 query={'cookie_set': 1})

                status = '307 Temporary Redirect'
                response_body = ''
                response_headers = [
                    util.set_cookie_header('TB_SESSION', session_token),
                    ('Location', redirect_to)
                ]
            else:
                return error_view('Internal Error',
                                  'Failed to create session.')
        else:
            return error_view('CSRF Verfication failed',
                              'Failed to authorize account due to a CSRF '
                              'verfication error, try again.')

    except OAuth2Error as error:
        # Might indicate a "deny" on granting access to the app
        util.print_exception('OAuth 2.0 Error occured: ', error)
        return error_view('OAuth Error',
                          'Failed to authorize account, try again.')
    else:
        # Normal function return without errors
        return response_body, response_headers, status
Esempio n. 6
0
def main_view(env, csrf_clerk):
    page_data = basic_page_data('main')
    response_body = 'Template Render Error.'
    response_headers = util.basic_response_header(response_body)
    status = '200 OK'

    session = turbo_session.get_session(env)
    account = turbo_session.retrieve_oauth_account(session)

    # Couldn't auth based on session. Start fresh OAuth 2.0 handshake
    if(account is None):
        if(session is not None):
            redirect_uri = turbo_views['oauth-callback'].uri
            oauth = turbo_session.OAuth2Session(
                config.mastodon.client_id,
                redirect_uri=redirect_uri,
                scope=config.mastodon.scope
            )
            authorization_url, state = oauth.authorization_url(
                config.mastodon.authorize_url,
                turbo_session.generate_state(env, csrf_clerk)
            )

            status = '307 Temporary Redirect'
            response_body = ''
            response_headers = [('Location', str(authorization_url))]

        # Not yet authenticated and no old session
        else:
            page_data['nav'] = turbo_nav.generate_html('main')
            page_data['login_uri'] = turbo_views['login'].path
            response_body = templates.render('main', page_data)
            response_headers = util.basic_response_header(response_body)

    # Display Account Information
    else:
        status = '307 Temporary Redirect'
        response_body = ''
        response_headers = [
            ('Location', turbo_views['account'].uri)
        ]
    return response_body, response_headers, status
Esempio n. 7
0
def patreon_theatre_callback_view(env, csrf_clerk):
    redirect_uri = turbo_views['patreon-theatre-callback'].uri
    authorization_response = redirect_uri + '?' + env['QUERY_STRING']
    get_vars = util.retrieve_get_vars(env)
    try:
        oauth = turbo_session.OAuth2Session(config.patreon.client_id,
                                            redirect_uri=redirect_uri,
                                            scope=config.patreon.scope)
        oauth_state = turbo_session.retrieve_oauth_state(
            get_vars.get('state', [''])[0])
        if oauth_state and csrf_clerk.validate('oauth-authorization',
                                               oauth_state[0]):
            oauth.fetch_token(config.patreon.token_url,
                              authorization_response=authorization_response,
                              client_secret=config.patreon.client_secret)
            patreon_user = patreon.get_current_user(oauth)
            if patreon_user is not None and len(patreon_user) > 0:
                memberships = patreon_user[0].get('memberships', [])
                session_token = None
                for item in memberships:
                    cents = item.get('currently_entitled_amount_cents', 0)
                    campaign_id = item.get('campaign', [{}])[0].get('id', '')
                    if (cents >= config.patreon.theatre_cents
                            and campaign_id == config.patreon.campaign_id):
                        session_token = patreon.create_session()

                if session_token is None:
                    dollars = str(config.patreon.theatre_cents // 100)
                    return error_view(
                        'Insufficient pledge',
                        'We could not verify that you are '
                        'pledging $' + dollars + ' to the '
                        'Video Games AWESOME Patreon.')

                redirect_to = turbo_views['theatre'].uri

                status = '307 Temporary Redirect'
                response_body = ''
                response_headers = [
                    util.set_cookie_header('TB_PATREON_SESSION',
                                           session_token,
                                           max_age=config.expiration_interval),
                    ('Location', redirect_to)
                ]
            else:
                return error_view('Unexpected error',
                                  'Failed to retrieve Patreon user details.')
        else:
            return error_view(
                'CSRF Verfication failed',
                'Failed to authorize Patreon account due to a '
                'CSRF verfication error, try again.')

    except OAuth2Error as error:
        # Might indicate a "deny" on granting access to the app
        logger.info(f'OAuth 2.0 Error occured: {error}',
                    exc_info=config.debug_mode)
        return error_view('OAuth Error',
                          'Failed to authorize Patreon account, try again.')
    else:
        # Normal function return without errors
        return response_body, response_headers, status