Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Troubles with Nextcloud OAuth integration (HTTP error 500) #321

Closed
dmigis opened this issue Dec 6, 2019 · 2 comments
Closed

Troubles with Nextcloud OAuth integration (HTTP error 500) #321

dmigis opened this issue Dec 6, 2019 · 2 comments

Comments

@dmigis
Copy link

dmigis commented Dec 6, 2019

Hello again! I'm trying to integrate Jupyterhub with Nextcloud OAuth, but the problem is, that Nextcloud OAuth JSON response has nested variables and thus I don't understand, how to pass ocs.data.id JSON variable to username_key. After using Callable as username_key I get HTTP error 500. Same happens, if I do not use this variable at all. What I'm doing wrong and how to solve this problem? Thanks in beforehand.

jupyterhub_config.py
`import os
from oauthenticator.oauth2 import OAuthLoginHandler
from oauthenticator.generic import GenericOAuthenticator
from tornado.auth import OAuth2Mixin

c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
c.DockerSpawner.image = os.environ['DOCKER_JUPYTER_IMAGE']
c.DockerSpawner.network_name = os.environ['DOCKER_NETWORK_NAME']
c.JupyterHub.hub_ip = os.environ['HUB_IP']

OAuth2 endpoints

class MyOAuthMixin(OAuth2Mixin):
_OAUTH_AUTHORIZE_URL = 'https://cloud.dmigis.me/apps/oauth2/authorize'
_OAUTH_ACCESS_TOKEN_URL = 'https://cloud.dmigis.me/apps/oauth2/api/v1/token'

class MyOAuthLoginHandler(OAuthLoginHandler, MyOAuthMixin):
pass

Authenticator configuration

class MyOAuthAuthenticator(GenericOAuthenticator):
class username_key:
def init(self, obj):
self.obj = obj
def call(self):
return self.obj['ocs']['data']['id']

login_service = 'Nextcloud'
login_handler = MyOAuthLoginHandler
token_url = 'https://<Nextcloud domain>/apps/oauth2/api/v1/token'
userdata_url = 'https://<Nextcloud domain>/ocs/v2.php/cloud/user?format=json'
oauth_callback_url = 'https://<Jupyterhub domain>/hub/oauth_callback'
client_id = os.environ['OAUTH_ID'] #passed through docker-compose
client_secret = os.environ['OAUTH_SECRET'] #passed through docker-compose

c.JupyterHub.authenticator_class = MyOAuthAuthenticator

notebook_dir = os.environ.get('DOCKER_NOTEBOOK_DIR')
c.DockerSpawner.notebook_dir = notebook_dir
c.DockerSpawner.volumes = { 'jupyterhub-user-{username}': notebook_dir }`

Error message:
jupyterhub | Traceback (most recent call last): jupyterhub | File "/opt/conda/lib/python3.6/site-packages/tornado/web.py", line 1592, in _execute jupyterhub | result = yield result jupyterhub | File "/opt/conda/lib/python3.6/site-packages/oauthenticator/oauth2.py", line 182, in get jupyterhub | user = yield self.login_user() jupyterhub | File "/opt/conda/lib/python3.6/site-packages/jupyterhub/handlers/base.py", line 483, in login_user jupyterhub | authenticated = await self.authenticate(data) jupyterhub | File "/opt/conda/lib/python3.6/site-packages/jupyterhub/auth.py", line 257, in get_authenticated_user jupyterhub | authenticated = await maybe_future(self.authenticate(handler, data)) jupyterhub | File "/opt/conda/lib/python3.6/site-packages/oauthenticator/generic.py", line 116, in authenticate jupyterhub | resp = yield http_client.fetch(req) jupyterhub | tornado.curl_httpclient.CurlError: HTTP 599: Operation timed out after 20001 milliseconds with 0 bytes received jupyterhub | jupyterhub | [E 2019-12-06 22:32:56.721 JupyterHub log:150] { jupyterhub | "X-Real-Ip": "[censored]", jupyterhub | "X-Forwarded-Proto": "https", jupyterhub | "X-Forwarded-Port": "443", jupyterhub | "X-Forwarded-For": "[censored]", jupyterhub | "Upgrade-Insecure-Requests": "1", jupyterhub | "Cookie": "oauthenticator-state=\"2|1:0|10:1575667952|20:oauthenticator-state|120:ZXlKemRHRjBaVjlwWkNJNklDSmpORGt3TWpJM01tRTJOMlEwTWpjeU9XRXlNVE0wWXpSbFlXWXpNekJsWWlJc0lDSnVaWGgwWDNWeWJDSTZJQ0lpZlE9PQ==|20a66078ee5a54bb0b85c81ae8b7443a3175b8930230001c9ee3f0b4402e1f03\"", jupyterhub | "Accept-Language": "en-US,en;q=0.5", jupyterhub | "Accept-Encoding": "gzip, deflate, br", jupyterhub | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", jupyterhub | "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0", jupyterhub | "Host": "[censored]", jupyterhub | "Connection": "close" jupyterhub | } jupyterhub | [E 2019-12-06 22:32:56.721 JupyterHub log:158] 500 GET /hub/oauth_callback?state=[secret]&code=[secret] (@109.252.89.232) 20029.10ms

Addition: OAuth JSON response:
{'ocs': {'meta': {'status': 'ok', 'statuscode': 200, 'message': 'OK'}, 'data': {'enabled': True, 'storageLocation': '[censored]', 'id': '[censored]', 'lastLogin':'[censored]', 'backend': 'Database', 'subadmin': [], 'quota': {'free': 585679208448, 'used': 13012258, 'total': 585692220706, 'relative': 0, 'quota': -3}, 'email': None, 'phone': '', 'address': '', 'website': '', 'twitter': '', 'groups': ['admin'], 'language': 'en', 'locale': '', 'backendCapabilities': {'setDisplayName': True, 'setPassword': True}, 'display-name': '[censored]'}}}

@dmigis
Copy link
Author

dmigis commented Dec 7, 2019

Solved the problem.
Working configuration (jupyterhub_config.py) for Nextcloud OAuth as identity provider (before using it install dictor library from pip or conda for nested JSON parsing):

import os
from oauthenticator.oauth2 import OAuthLoginHandler
from oauthenticator.generic import GenericOAuthenticator
from tornado.auth import OAuth2Mixin
from dictor import dictor

class MyOAuthMixin(OAuth2Mixin):
_OAUTH_AUTHORIZE_URL = 'https:///apps/oauth2/authorize'
_OAUTH_ACCESS_TOKEN_URL = 'https:///apps/oauth2/api/v1/token'

class MyOAuthLoginHandler(OAuthLoginHandler, MyOAuthMixin):
pass

class MyOAuthAuthenticator(GenericOAuthenticator):
def username_key(self, obj):
res = dictor(obj, 'ocs.data.id')
return res
login_service = 'Nextcloud'
login_handler = MyOAuthLoginHandler
token_url = 'https:///apps/oauth2/api/v1/token'
userdata_url = 'https:///ocs/v2.php/cloud/user?format=json'
oauth_callback_url = 'https:///hub/oauth_callback'
client_id =
client_secret =

c.JupyterHub.authenticator_class = MyOAuthAuthenticator

@dmigis dmigis closed this as completed Dec 7, 2019
@dmigis
Copy link
Author

dmigis commented Dec 7, 2019

Also note for developers: are you planning native support of Nextcloud OAuth or at least support of nested JSON keys?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant