コード例 #1
0
ファイル: handlers.py プロジェクト: franekmagiera/pastecan
async def post_paste(request):
    # Creates a new paste.

    body = await request.json()
    _verify_body(body)

    body['title'] = body['title'] or 'Untitled'
    date = datetime.now()
    user_id, _ = _get_claims(request.cookies, request.app['jwt_key'],
                             request.app['jwt_algorithm'])

    if body['exposure'] == 'Private' and user_id is None:
        raise web.HTTPBadRequest(
            'Cannot create a private paste while not logged in')

    async with request.app['db_engine'].acquire() as conn:
        async with transaction_context(conn) as tc_conn:
            await tc_conn.execute(pastes_table.insert().values(date=date,
                                                               user_id=user_id,
                                                               **body))
            new_id = await tc_conn.execute('SELECT LAST_INSERT_ID();')

    new_id = await new_id.scalar()

    return web.json_response({'id': new_id})
コード例 #2
0
ファイル: handlers.py プロジェクト: franekmagiera/pastecan
async def delete_paste(request):
    paste_id = request.match_info['id']
    async with request.app['db_engine'].acquire() as conn:
        await _should_authorize(conn, paste_id, request.cookies,
                                request.app['jwt_key'],
                                request.app['jwt_algorithm'])
        async with transaction_context(conn) as tc_conn:
            await tc_conn.execute(
                pastes_table.delete().where(pastes_table.c.id == paste_id))
    return web.HTTPNoContent()
コード例 #3
0
def test_select():
    with transaction_context() as session:
        p1 = session.query(Parent)\
                    .options(joinedload(Parent.children))\
                    .filter(Parent.name == "p1")\
                    .one_or_none()

        print(p1.name)
        for child in p1.children:
            print(child.name)
コード例 #4
0
def insert_test_data():
    with transaction_context() as session:
        p1 = Parent()
        p1.name = "p1"

        c1 = Child()
        c1.name = "c1"
        c2 = Child()
        c2.name = "c2"

        p1.childs = [c1, c2]

        session.add(p1)
コード例 #5
0
ファイル: handlers.py プロジェクト: franekmagiera/pastecan
async def put_paste(request):
    # Updates an existing paste.
    # Only a logged in user can update their pastes.

    body = await request.json()
    _verify_body(body)
    paste_id = request.match_info['id']

    async with request.app['db_engine'].acquire() as conn:
        await _should_authorize(conn, paste_id, request.cookies,
                                request.app['jwt_key'],
                                request.app['jwt_algorithm'])
        async with transaction_context(conn) as tc_conn:
            await tc_conn.execute(pastes_table.update().where(
                pastes_table.c.id == paste_id).values(**body))
    return web.HTTPNoContent()
コード例 #6
0
ファイル: handlers.py プロジェクト: franekmagiera/pastecan
async def twitter_login(request):
    # Implements the first step of login with Twitter.

    twitter_api_key = request.app['twitter_api_key']
    twitter_api_secret_key = request.app['twitter_api_secret_key']
    twitter_oauth_callback = request.app['twitter_oauth_callback']
    request_token_endpoint = request.app['request_token_endpoint']
    authenticate_endpoint = request.app['authenticate_endpoint']

    client = oauthlib.oauth1.Client(twitter_api_key,
                                    client_secret=twitter_api_secret_key,
                                    callback_uri=twitter_oauth_callback)
    uri, headers, _ = client.sign(request_token_endpoint, http_method='POST')

    session = request.app['client_session']

    # Fetch an unauthorized request token.
    async with session.post(uri, headers=headers) as response:
        if response.status != 200:
            raise web.HTTPInternalServerError()
        body = await response.text()

    # Parse oauth_token, oauth_token_secret, oauth_callback_confirmed.
    body = dict([pair.split('=') for pair in body.split('&')])

    if body.get('oauth_callback_confirmed') != 'true':
        raise web.HTTPInternalServerError()

    oauth_token = body['oauth_token']
    oauth_token_secret = body['oauth_token_secret']

    # Store oauth_token and oauth_token_secret so they can be used at the next stage of the sign in process.
    async with request.app['db_engine'].acquire() as conn:
        result = await conn.execute(login_sessions_table.select().where(
            login_sessions_table.c.oauth_token == oauth_token))
        login_session = await result.first()
        if login_session is None:
            async with transaction_context(conn) as tc_conn:
                await tc_conn.execute(login_sessions_table.insert().values(
                    oauth_token=oauth_token,
                    oauth_token_secret=oauth_token_secret))

    # Redirect the user to Twitter so they can authenticate themselves and authorize pastecan.
    raise web.HTTPFound(
        URL(authenticate_endpoint) % {'oauth_token': oauth_token})
コード例 #7
0
ファイル: handlers.py プロジェクト: franekmagiera/pastecan
async def token(request):
    # Implements the third step of log in with Twitter.

    params = request.query
    params_oauth_token = params.get('oauth_token')
    oauth_verifier = params.get('oauth_verifier')
    oauth_token = None
    oauth_token_secret = None

    # Check if the token provided by the user is presnet in session data.
    async with request.app['db_engine'].acquire() as conn:
        result = await conn.execute(login_sessions_table.select().where(
            login_sessions_table.c.oauth_token == params_oauth_token))
        session_data = await result.first()
        if session_data is None:
            raise web.HTTPBadRequest('Could not verify the OAuth token')
        session_data = {
            column: value
            for column, value in session_data.items()
        }
        oauth_token = session_data['oauth_token']
        oauth_token_secret = session_data['oauth_token_secret']
        # Clean up login session data. This should also be done periodically for example using a background task.
        # https://docs.aiohttp.org/en/stable/web_advanced.html#background-tasks
        await conn.execute(login_sessions_table.delete().where(
            login_sessions_table.c.oauth_token == params_oauth_token))

    if oauth_token != params_oauth_token:
        raise web.HTTPBadRequest('Could not verify the Oauth token')

    twitter_api_key = request.app['twitter_api_key']
    twitter_api_secret_key = request.app['twitter_api_secret_key']
    access_token_endpoint = request.app['access_token_endpoint']

    client = oauthlib.oauth1.Client(twitter_api_key,
                                    client_secret=twitter_api_secret_key,
                                    resource_owner_key=oauth_token,
                                    resource_owner_secret=oauth_token_secret)
    request_body = f'oauth_verifier={oauth_verifier}'
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    uri, headers, request_body = client.sign(access_token_endpoint,
                                             http_method='POST',
                                             headers=headers,
                                             body=request_body)

    session = request.app['client_session']

    # Fetch access token.
    async with session.post(uri, headers=headers,
                            data=request_body) as response:
        if response.status != 200:
            raise web.HTTPInternalServerError(
                'Could not receive an access token')
        body = await response.text()

    # Parse oauth_token, oauth_token_secret, user_id, screen_name.
    body = dict([pair.split('=') for pair in body.split('&')])
    user_id_third_step = body['user_id']

    # Determine identity of the user using GET account/verify_credentials.
    client = oauthlib.oauth1.Client(
        twitter_api_key,
        client_secret=twitter_api_secret_key,
        resource_owner_key=body['oauth_token'],
        resource_owner_secret=body['oauth_token_secret'])
    verify_credentials_endpoint = request.app['verify_credentials_endpoint']
    uri, headers, _ = client.sign(verify_credentials_endpoint,
                                  http_method='GET')

    async with session.get(uri, headers=headers) as response:
        if response.status != 200:
            raise web.HTTPInternalServerError('Could not verify user identity')
        body = await response.json()

    user_id = body['id_str']
    user_screen_name = body['screen_name']

    if user_id != user_id_third_step:
        raise web.HTTPInternalServerError('User identity mismatch')

    # Store user data in the database if it is not already present.
    async with request.app['db_engine'].acquire() as conn:
        result = await conn.execute(
            users_table.select().where(users_table.c.user_id == user_id))
        user = await result.first()
        if user is None:
            async with transaction_context(conn) as tc_conn:
                await tc_conn.execute(users_table.insert().values(
                    user_id=user_id, screen_name=user_screen_name))

    # Issue a JWT for the user.
    encoded = _create_token(user_id, user_screen_name, request.app['jwt_key'],
                            request.app['jwt_algorithm'])

    response = web.HTTPFound('/')
    response.set_cookie(TOKEN_COOKIE,
                        encoded,
                        max_age=60 * 60 * 24,
                        secure=True,
                        samesite='Strict',
                        httponly=True)  # Should expire in 24h.
    response.set_cookie('screenName',
                        user_screen_name,
                        max_age=60 * 60 * 24,
                        secure=True,
                        samesite='Strict')

    return response
コード例 #8
0
def test_delete_cascade():
    with transaction_context() as session:
        session.query(Parent).filter(Parent.name == "p1").delete()