Exemplo n.º 1
0
    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)
Exemplo n.º 2
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)
Exemplo 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)
Exemplo n.º 4
0
    async def handle_oauth_callback(self, request, session) -> dict:
        params = request.query

        gh = GithubClient(client_id=self._id, client_secret=self._secret)
        code = params.get('code')
        if not code:
            raise BadAttemptError("No github code found. It's possible the "
                                  "session timed out while authenticating.")
        otoken, _ = await gh.get_access_token(code)
        gh = GithubClient(
            # Need a new client, so it includes the new access token
            client_id=self._id,
            client_secret=self._secret,
            access_token=otoken)
        req = await gh.request('GET', 'user')
        user = await req.json()
        req.close()
        req = await gh.request('GET', 'user/orgs')
        orgs = await req.json()
        req.close()

        for org in orgs:
            if org.get('login') == self.org:
                user['username'] = user.get('login')
                return user

        raise BadAttemptError('User not in correct Org')
Exemplo n.º 5
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'
        })
Exemplo n.º 6
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')
Exemplo n.º 7
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()
Exemplo 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')
Exemplo 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)
Exemplo n.º 10
0
    async def wrapped(request, **kwargs):
        session = await get_session(request)

        if 'token' not in session:
            return web.HTTPFound('/auth?redirect_uri={}'.format(request.url))

        github = GithubClient(client_id=config.GITHUB_CLIENT_ID,
                              client_secret=config.GITHUB_CLIENT_SECRET,
                              access_token=session['token'])
        user, info = await github.user_info()

        return await fn(request, user, **kwargs)
Exemplo n.º 11
0
async def handle_github_callback(request):
    params = urllib.parse.parse_qs(request.query_string)
    session = await get_session(request)

    # Check conditions
    if (session.get('github_state') !=  # Github_state is incorrect
            params.get('state', [None])[0]):
        print('bad state returned')
        """
        Codes are the same, we are in the middle of
        authenticating and things look ok, carry on
        """
        return web.HTTPForbidden()

    gh = GithubClient(client_id=gh_id, client_secret=gh_secret)
    code = params.get('code', [None])[0]
    if not code:
        return web.HTTPNotFound(body=b'Page not found. Its possible the '
                                b'session timed out while authenticating.')
    otoken, _ = await gh.get_access_token(code)
    gh = GithubClient(client_id=gh_id,
                      client_secret=gh_secret,
                      access_token=otoken)
    req = await gh.request('GET', 'user')
    user = await req.json()
    req.close()
    req = await gh.request('GET', 'user/orgs')
    orgs = await req.json()
    req.close()

    for org in orgs:
        if org.get('login') == gh_org:

            # Swap github_state for user
            session.pop('github_state', None)
            session['User'] = user.get('login')
            location = session.pop('desired_location')
            return web.HTTPFound(location)

    return web.HTTPForbidden()
Exemplo n.º 12
0
async def test_custom_client(http, response):
    from aioauth_client import GithubClient

    transport = AsyncClient()
    github = GithubClient(client_id='cid',
                          client_secret='csecret',
                          transport=transport)
    assert github.transport

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

    token, meta = await github.get_access_token('000')
    assert http.called
    assert meta
    assert token
Exemplo n.º 13
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)
Exemplo n.º 14
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)
Exemplo n.º 15
0
async def test_oauth2_request(http):
    from aioauth_client import GithubClient

    github = GithubClient(client_id='cid',
                          client_secret='csecret',
                          access_token='token')
    res = await github.request('GET', '/user', params={'test': 'ok'})
    assert res
    http.assert_called_with(
        'GET',
        'https://api.github.com/user',
        params={'test': 'ok'},
        headers={
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
            'Authorization': 'Bearer token'
        })
Exemplo n.º 16
0
 def __init__(self, client_id, client_secret):
     self.client_id = client_id
     self.__client_secret = client_secret
     self.client = GithubClient(client_id, client_secret)
Exemplo n.º 17
0
 def __init__(self, client_id, client_secret):
     self.client_id = client_id
     self.__client_secret = client_secret
     self.client = GithubClient(client_id, client_secret)
Exemplo n.º 18
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
Exemplo n.º 19
0
 def gh_client(**kw):
     return GithubClient(conf['github_id'], conf['github_secret'], **kw)
Exemplo n.º 20
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}"
Exemplo n.º 21
0
class UserOAuthView(UserViewMixin, PeeweeView):
    model = UserOAuth

    github = GithubClient(client_id='config.CLIENT_ID',
                          client_secret='config.CLIENT_SECRET')

    @app.route.interface('GET')
    async def get_oauth_url(self):
        authorize_url = self.github.get_authorize_url(scope="user:email")
        self.finish(RETCODE.SUCCESS, {'state': 0, 'url': authorize_url})

    @app.route.interface('GET')
    async def get_user_data(self):
        code = self.params
        print(code)
        code = code['code']
        if code == 'undefined':
            self.finish(RETCODE.FAILED)
            return
        otoken, _ = await self.github.get_access_token(code)
        github = GithubClient(
            client_id=config.CLIENT_ID,
            client_secret=config.CLIENT_SECRET,
            access_token=otoken,
        )
        response = await github.request('GET', 'user')
        # response = json.loads(response)
        if response['id']:
            try:
                account = UserOAuth.get(UserOAuth.login_id == response['id'],
                                        UserOAuth.platform == 'github')
            except UserOAuth.DoesNotExist:
                account = None

            if account:
                if account.user_id:  # 返回用户已有信息
                    u = UserModel.get_by_pk(account.user_id)
                    if u:
                        expires = 30
                        u.refresh_key()
                        self.setup_user_key(u.key, expires)
                        self.finish(
                            RETCODE.SUCCESS, {
                                'oauthcode': 0,
                                'user_id': account.user_id,
                                'state': account.state,
                                'access_token': u.key
                            })
                else:
                    self.finish(
                        RETCODE.SUCCESS, {
                            'oauthcode': 1,
                            'state': account.state,
                            'oauth_id': account.id,
                            'login_id': account.login_id,
                            'platform': account.platform
                        })
            else:
                ins = [{
                    'login_id': response['id'],
                    'time': time.time(),
                    'platform': 'github',
                    'state': POST_STATE.APPLY
                }]
                if not isinstance(config.LONG_ID_GENERATOR,
                                  config.SQLSerialGenerator):
                    ins[0]['id'] = config.LONG_ID_GENERATOR().to_bin()

                UserOAuth.insert_many(ins).execute()
                self.finish(
                    RETCODE.SUCCESS, {
                        'oauthcode': 1,
                        'oauth_id': ins[0]['id'],
                        'state': ins[0]['state'],
                        'login_id': ins[0]['login_id'],
                        'platform': ins[0]['platform']
                    })
        else:
            self.finish(RETCODE.NOT_FOUND)

    @app.route.interface('POST')
    async def update(self):
        post = await self.post_data()
        print('提交的更新内容', post)

        try:
            account = UserOAuth.get(UserOAuth.login_id == post['loginId'],
                                    UserOAuth.platform == post['platform'])
        except UserOAuth.DoesNotExist:
            account = None
        except KeyError:
            account = None
            print('keyerror')

        if account:
            if post['state'] == str(POST_STATE.APPLY):
                # 该post['id']是user表中的id
                post_user_id = to_bin(post['id'])
                UserOAuth.update(
                    user_id=post_user_id, state=POST_STATE.NORMAL).where(
                        UserOAuth.login_id == post['loginId']).execute()
                self.finish(RETCODE.SUCCESS)
            else:
                print('非法参数')
                self.finish(RETCODE.FAILED)
        else:
            self.finish(RETCODE.FAILED)
            print('failed')
Exemplo n.º 22
0
    async def get_user_data(self):
        code = self.params
        print(code)
        code = code['code']
        if code == 'undefined':
            self.finish(RETCODE.FAILED)
            return
        otoken, _ = await self.github.get_access_token(code)
        github = GithubClient(
            client_id=config.CLIENT_ID,
            client_secret=config.CLIENT_SECRET,
            access_token=otoken,
        )
        response = await github.request('GET', 'user')
        # response = json.loads(response)
        if response['id']:
            try:
                account = UserOAuth.get(UserOAuth.login_id == response['id'],
                                        UserOAuth.platform == 'github')
            except UserOAuth.DoesNotExist:
                account = None

            if account:
                if account.user_id:  # 返回用户已有信息
                    u = UserModel.get_by_pk(account.user_id)
                    if u:
                        expires = 30
                        u.refresh_key()
                        self.setup_user_key(u.key, expires)
                        self.finish(
                            RETCODE.SUCCESS, {
                                'oauthcode': 0,
                                'user_id': account.user_id,
                                'state': account.state,
                                'access_token': u.key
                            })
                else:
                    self.finish(
                        RETCODE.SUCCESS, {
                            'oauthcode': 1,
                            'state': account.state,
                            'oauth_id': account.id,
                            'login_id': account.login_id,
                            'platform': account.platform
                        })
            else:
                ins = [{
                    'login_id': response['id'],
                    'time': time.time(),
                    'platform': 'github',
                    'state': POST_STATE.APPLY
                }]
                if not isinstance(config.LONG_ID_GENERATOR,
                                  config.SQLSerialGenerator):
                    ins[0]['id'] = config.LONG_ID_GENERATOR().to_bin()

                UserOAuth.insert_many(ins).execute()
                self.finish(
                    RETCODE.SUCCESS, {
                        'oauthcode': 1,
                        'oauth_id': ins[0]['id'],
                        'state': ins[0]['state'],
                        'login_id': ins[0]['login_id'],
                        'platform': ins[0]['platform']
                    })
        else:
            self.finish(RETCODE.NOT_FOUND)