Ejemplo n.º 1
0
        async def auth_handler(request):
            session = await get_session(request)
            params = urllib.parse.parse_qs(request.query_string)
            user = session.get('User')
            if user:  # Already authenticated
                request['user'] = user
            elif handler in whitelist_handlers:  # We don't need authentication
                pass
            elif handler == handle_github_callback and \
                    session.get('github_state'):
                # Attempting to authenticate - let them pass through
                pass

            elif api_unauthorized and request.path.startswith('/api/'):
                return web.HTTPUnauthorized()
            else:
                gh = GithubClient(client_id=gh_id, client_secret=gh_secret)
                state = os.urandom(30).hex()
                authorize_url = gh.get_authorize_url(
                    scope='user:email read:org', state=state)
                session['github_state'] = state
                session['desired_location'] = request.path
                return web.HTTPFound(authorize_url)

            return await handler(request)
Ejemplo n.º 2
0
async def test_oauth2(http, response):
    from aioauth_client import GithubClient, ClientRegistry

    github = GithubClient(client_id='cid', client_secret='csecret')
    assert github
    assert 'github' in ClientRegistry.clients
    assert github.get_authorize_url(
    ) == 'https://github.com/login/oauth/authorize?client_id=cid&response_type=code'  # noqa

    http.return_value = response(json={'access_token': 'TEST-TOKEN'})
    token, meta = await github.get_access_token('000')
    assert token == 'TEST-TOKEN'
    assert meta
    assert http.called

    http.reset_mock()
    http.return_value = response(json={'access_token': 'TEST-TOKEN'})

    res = await github.request('GET', 'user', access_token='NEW-TEST-TOKEN')
    assert res
    http.assert_called_with(
        'GET',
        'https://api.github.com/user',
        params=None,
        headers={
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
            'Authorization': 'Bearer NEW-TEST-TOKEN'
        })
Ejemplo n.º 3
0
        async def auth_handler(request):
            session = await get_session(request)
            params = urllib.parse.parse_qs(request.query_string)
            user = session.get('User')
            if user:  # Already authenticated
                request['user'] = user
            elif handler in whitelist_handlers:  # We don't need authentication
                pass
            elif handler == handle_github_callback and \
                    session.get('github_state'):
                # Attempting to authenticate - let them pass through
                        pass

            elif api_unauthorized and request.path.startswith('/api/'):
                return web.HTTPUnauthorized()
            else:
                gh = GithubClient(
                    client_id=gh_id,
                    client_secret=gh_secret
                )
                state = os.urandom(30).hex()
                authorize_url = gh.get_authorize_url(
                    scope='user:email read:org',
                    state=state)
                session['github_state'] = state
                session['desired_location'] = request.path
                return web.HTTPFound(authorize_url)

            return await handler(request)
Ejemplo n.º 4
0
class GithubAuth:
    def __init__(self, client_id, client_secret):
        self.client_id = client_id
        self.__client_secret = client_secret
        self.client = GithubClient(client_id, client_secret)

    def auth_url(self):
        # user:email might be enough here
        return self.client.get_authorize_url(scope="user")

    async def get_token(self, code):
        return await self.client.get_access_token(code)

    def api(self, token):
        return GithubAPI(token)
Ejemplo n.º 5
0
class GithubAuth:
    def __init__(self, client_id, client_secret):
        self.client_id = client_id
        self.__client_secret = client_secret
        self.client = GithubClient(client_id, client_secret)

    def auth_url(self):
        # user:email might be enough here
        return self.client.get_authorize_url(scope="user")

    async def get_token(self, code):
        return await self.client.get_access_token(code)

    def api(self, token):
        return GithubAPI(token)
Ejemplo n.º 6
0
async def github(request):
    github = GithubClient(
        client_id='b6281b6fe88fa4c313e6',
        client_secret='21ff23d9f1cad775daee6a38d230e1ee05b04f7c',
    )
    if 'code' not in request.url.query:
        return ResponseRedirect(github.get_authorize_url(scope='user:email'))

    # Get access token
    code = request.url.query['code']
    token, _ = await github.get_access_token(code)
    assert token

    # Get a resource `https://api.github.com/user`
    response = await github.request('GET', 'user')
    return await response.read()
Ejemplo n.º 7
0
def github(request):
    github = GithubClient(
        client_id='b6281b6fe88fa4c313e6',
        client_secret='21ff23d9f1cad775daee6a38d230e1ee05b04f7c',
    )
    if 'code' not in request.GET:
        return web.HTTPFound(github.get_authorize_url(scope='user:email'))

    # Get access token
    code = request.GET['code']
    token = yield from github.get_access_token(code)

    # Get a resource
    response = yield from github.request('GET', 'user')
    body = yield from response.read()
    return web.Response(body=body, content_type='application/json')
Ejemplo n.º 8
0
def github(request):
    github = GithubClient(
        client_id='b6281b6fe88fa4c313e6',
        client_secret='21ff23d9f1cad775daee6a38d230e1ee05b04f7c',
    )
    if 'code' not in request.query:
        return web.HTTPFound(github.get_authorize_url(scope='user:email'))

    # Get access token
    code = request.query['code']
    token, _ = yield from github.get_access_token(code)
    assert token

    # Get a resource `https://api.github.com/user`
    response = yield from github.request('GET', 'user')
    body = yield from response.read()
    return web.Response(body=body, content_type='application/json')
Ejemplo n.º 9
0
async def github_auth(request):
    github = GithubClient(
        client_id=config.GITHUB_CLIENT_ID,
        client_secret=config.GITHUB_CLIENT_SECRET,
    )
    session = await aiohttp_session.get_session(request)

    if 'code' not in request.query:
        redirect_uri = request.query.get('redirect_uri', '/')
        session['redirect_uri'] = redirect_uri
        return web.HTTPFound(github.get_authorize_url(scope='user:email'))

    code = request.query['code']
    token, _ = await github.get_access_token(code)

    session['token'] = token
    next_uri = session.pop('redirect_uri', '/')
    logger.debug('Redirecting back to %s', next_uri)
    return web.HTTPFound(next_uri)
Ejemplo n.º 10
0
class User(BaseUser):
    method = "github"
    routes = web.RouteTableDef()

    def __init__(self, redirect_uri, code_challenge):
        super().__init__(redirect_uri, code_challenge)

        if not GITHUB_CLIENT_ID or not GITHUB_CLIENT_SECRET:
            raise Exception("GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET should be set via environment")

        self._github = GithubClient(client_id=GITHUB_CLIENT_ID, client_secret=GITHUB_CLIENT_SECRET)

    def get_authorize_page(self):
        # Chance on collision is really low, but would be really annoying. So
        # simply protect against it by looking for an unused UUID.
        state = secrets.token_hex(16)
        while state in _github_states:
            state = secrets.token_hex(16)
        self._state = state

        _github_states[self._state] = self

        # We don't set any scope, as we only want the username + id
        authorize_url = self._github.get_authorize_url(state=self._state)
        return web.HTTPFound(location=authorize_url)

    @staticmethod
    def get_by_state(state):
        if state not in _github_states:
            return None

        user = _github_states[state]
        user._forget_github_state()

        return user

    def logout(self):
        self._forget_github_state()

        super().logout()

    def _forget_github_state(self):
        if self._state:
            del _github_states[self._state]

        self._state = None

    async def get_user_information(self, code):
        # Validate the code and fetch the user info
        await self._github.get_access_token(code)
        user, _ = await self._github.user_info()

        self.display_name = user.username
        self.id = str(user.id)

    @staticmethod
    @routes.get("/user/github-callback")
    async def login_github_callback(request):
        code = in_query_github_code(request.query.get("code"))
        state = in_query_github_state(request.query.get("state"))

        user = User.get_by_state(state)
        if user is None:
            return web.HTTPNotFound()

        await user.get_user_information(code)

        return web.HTTPFound(location=f"{user.redirect_uri}?code={user.code}")

    @staticmethod
    def get_description():
        return "Login via GitHub"

    @staticmethod
    def get_settings_url():
        return f"https://github.com/settings/connections/applications/{GITHUB_CLIENT_ID}"
Ejemplo n.º 11
0
 async def get_oauth_url(self, request, session, state):
     gh = GithubClient(client_id=self._id, client_secret=self._secret)
     authorize_url = gh.get_authorize_url(scope='user:email read:org',
                                          state=state)
     return authorize_url