<commit_before>"""
Custom Authenticator to use OpenShift OAuth with JupyterHub.

Derived from the GitHub OAuth authenticator.
"""


import json
import os

from tornado.auth import OAuth2Mixin
from tornado import gen, web

from tornado.httputil import url_concat
from tornado.httpclient import HTTPRequest, AsyncHTTPClient

from jupyterhub.auth import LocalAuthenticator

from .oauth2 import OAuthLoginHandler, OAuthenticator

OPENSHIFT_URL = os.environ.get('OPENSHIFT_URL') or 'https://localhost:8443'

class OpenShiftMixin(OAuth2Mixin):
    _OAUTH_AUTHORIZE_URL = "%s/oauth/authorize" % OPENSHIFT_URL
    _OAUTH_ACCESS_TOKEN_URL = "%s/oauth/token" % OPENSHIFT_URL


class OpenShiftLoginHandler(OAuthLoginHandler, OpenShiftMixin):
    # This allows `Service Accounts as OAuth Clients` scenario
    # https://docs.openshift.org/latest/architecture/additional_concepts/authentication.html#service-accounts-as-oauth-clients
    scope=['user:info']


class OpenShiftOAuthenticator(OAuthenticator):

    login_service = "OpenShift"

    login_handler = OpenShiftLoginHandler

    @gen.coroutine
    def authenticate(self, handler, data=None):
        code = handler.get_argument("code")
        # TODO: Configure the curl_httpclient for tornado
        http_client = AsyncHTTPClient()

        # Exchange the OAuth code for a OpenShift Access Token
        #
        # See: https://docs.openshift.org/latest/architecture/additional_concepts/authentication.html#api-authentication

        params = dict(
            client_id=self.client_id,
            client_secret=self.client_secret,
            grant_type="authorization_code",
            code=code
        )

        url = url_concat("%s/oauth/token" % OPENSHIFT_URL, params)

        req = HTTPRequest(url,
                          method="POST",
                          validate_cert=False,
                          headers={"Accept": "application/json"},
                          body='' # Body is required for a POST...
                          )

        resp = yield http_client.fetch(req)

        resp_json = json.loads(resp.body.decode('utf8', 'replace'))
<commit_msg>Scope needs to be an attribute of OpenShiftOAuthenticator class.<commit_after>"""
Custom Authenticator to use OpenShift OAuth with JupyterHub.

Derived from the GitHub OAuth authenticator.
"""


import json
import os

from tornado.auth import OAuth2Mixin
from tornado import gen, web

from tornado.httputil import url_concat
from tornado.httpclient import HTTPRequest, AsyncHTTPClient

from jupyterhub.auth import LocalAuthenticator

from .oauth2 import OAuthLoginHandler, OAuthenticator

OPENSHIFT_URL = os.environ.get('OPENSHIFT_URL') or 'https://localhost:8443'

class OpenShiftMixin(OAuth2Mixin):
    _OAUTH_AUTHORIZE_URL = "%s/oauth/authorize" % OPENSHIFT_URL
    _OAUTH_ACCESS_TOKEN_URL = "%s/oauth/token" % OPENSHIFT_URL


class OpenShiftLoginHandler(OAuthLoginHandler, OpenShiftMixin):
    # This allows `Service Accounts as OAuth Clients` scenario
    # https://docs.openshift.org/latest/architecture/additional_concepts/authentication.html#service-accounts-as-oauth-clients
    @property
    def scope(self):
        return self.authenticator.scope


class OpenShiftOAuthenticator(OAuthenticator):

    login_service = "OpenShift"

    login_handler = OpenShiftLoginHandler

    scope = ['user:info']

    @gen.coroutine
    def authenticate(self, handler, data=None):
        code = handler.get_argument("code")
        # TODO: Configure the curl_httpclient for tornado
        http_client = AsyncHTTPClient()

        # Exchange the OAuth code for a OpenShift Access Token
        #
        # See: https://docs.openshift.org/latest/architecture/additional_concepts/authentication.html#api-authentication

        params = dict(
            client_id=self.client_id,
            client_secret=self.client_secret,
            grant_type="authorization_code",
            code=code
        )

        url = url_concat("%s/oauth/token" % OPENSHIFT_URL, params)

        req = HTTPRequest(url,
                          method="POST",
                          validate_cert=False,
                          headers={"Accept": "application/json"},
                          body='' # Body is required for a POST...
                          )

        resp = yield http_client.fetch(req)

        resp_json = json.loads(resp.body.decode('utf8', 'replace'))

{'fraction_non_alphanumeric': 0.08706524210047738, 'fraction_numerical': 0.0036371902705160265, 'mean_word_length': 2.9355992844364938, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4198593', 'n_tokens_mistral': 1312, 'n_tokens_neox': 1247, 'n_words': 278}