Skip to content

Commit

Permalink
feat: Support OIDC login using solid-oidc-client
Browse files Browse the repository at this point in the history
  • Loading branch information
renyuneyun committed Oct 29, 2023
1 parent 6061bb4 commit bccdccd
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 1 deletion.
79 changes: 79 additions & 0 deletions src/solid/auth.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import httpx
from httpx import Response

from solid_oidc_client import SolidOidcClient, SolidAuthSession, MemStore
import flask

from multiprocessing import Process, Queue

from typing import Dict


class Auth:
Expand All @@ -25,3 +33,74 @@ def login(self, idp, username, password):

if not self.is_login:
raise Exception('Cannot login.')


class OidcAuth:

OAUTH_CALLBACK_PATH = '/oauth/callback'
OAUTH_CALLBACK_URI = f"http://localhost:8080{OAUTH_CALLBACK_PATH}"

def __init__(self):
self.client = httpx.Client()
self.session = None
self._server_process = None

@property
def is_login(self) -> bool:
return self.session is not None

def fetch(self, method, url, options: Dict) -> Response:
if 'headers' not in options:
options['headers'] = {}

if self.session:
auth_headers = self.session.get_auth_headers(url, method)
options['headers'].update(auth_headers)

r = self.client.request(method, url, **options)
return r

def _start_server(self, solid_oidc_client: SolidOidcClient, q: Queue):
process = Process(target=_run_flask_server, args=(solid_oidc_client, q))
self._server_process = process
process.start()

def _stop_server(self):
self._server_process.terminate()

def login(self, idp):
solid_oidc_client = SolidOidcClient(storage=MemStore())
solid_oidc_client.register_client(idp, [OidcAuth.OAUTH_CALLBACK_URI])
login_url = solid_oidc_client.create_login_uri('/', OidcAuth.OAUTH_CALLBACK_URI)
q = Queue(1)
self._start_server(solid_oidc_client, q)

print(f"Please visit this URL to log-in: {login_url}")

session = SolidAuthSession.deserialize(q.get())
self.session = session

self._stop_server()


def _run_flask_server(solid_oidc_client: SolidOidcClient, q: Queue):
app = flask.Flask(__name__)

@app.get('/oauth/callback')
def login_callback():
code = flask.request.args['code']
state = flask.request.args['state']

session = solid_oidc_client.finish_login(
code=code,
state=state,
callback_uri=OidcAuth.OAUTH_CALLBACK_URI,
)

q.put(session.serialize())

return flask.Response(
f"Logged in as {session.get_web_id()}. You can close your browser now.",
mimetype='text/html')

app.run('localhost', 8080)
5 changes: 4 additions & 1 deletion src/solid/solid_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ def fetch(self, method, url, options: Dict = None) -> Response:
options = {}
# options['verify'] = False

r = self.auth.client.request(method, url, **options)
if hasattr(self.auth, 'fetch'):
r = self.auth.fetch(method, url, options)
else:
r = self.auth.client.request(method, url, **options)
# r= httpx.request(method, url, **options)
r.raise_for_status()
return r
Expand Down

0 comments on commit bccdccd

Please sign in to comment.