def github_auth_middleware(*, github_id, github_secret, github_org,
                           whitelist_handlers=None, api_unauthorized=False):
    """ Middleware for github authentication
    :param github_id: github client id
    :param github_secret: github secret
    :param github_org: github organization for which people are authorized
    :param whitelist_handlers: a list of handler methods
        which do not need authorization
    :param api_unauthorized: if set to True, any call without authorization
        made at a path of /api/* will return a 401 instead of
        redirecting to github login

    :return: middleware_factory
    """
    global gh_id, gh_secret, gh_org
    gh_id = github_id
    gh_secret = github_secret
    gh_org = github_org
    whitelist_handlers = whitelist_handlers or []

    async def middleware_factory(app, handler):

        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)

        return auth_handler

    return middleware_factory
Middleware for github authentication
    :param github_id: github client id
    :param github_secret: github secret
    :param github_org: github organization for which people are authorized
    :param whitelist_handlers: a list of handler methods
        which do not need authorization
    :param api_unauthorized: if set to True, any call without authorization
        made at a path of /api/* will return a 401 instead of
        redirecting to github login

    :return: middleware_factory