11import httpx
2+ from httpx import Response
3+
4+ from solid_oidc_client import SolidOidcClient , SolidAuthSession , MemStore
5+ import flask
6+
7+ from multiprocessing import Process , Queue
8+
9+ from typing import Dict
210
311
412class Auth :
@@ -25,3 +33,74 @@ def login(self, idp, username, password):
2533
2634 if not self .is_login :
2735 raise Exception ('Cannot login.' )
36+
37+
38+ class OidcAuth :
39+
40+ OAUTH_CALLBACK_PATH = '/oauth/callback'
41+ OAUTH_CALLBACK_URI = f"http://localhost:8080{ OAUTH_CALLBACK_PATH } "
42+
43+ def __init__ (self ):
44+ self .client = httpx .Client ()
45+ self .session = None
46+ self ._server_process = None
47+
48+ @property
49+ def is_login (self ) -> bool :
50+ return self .session is not None
51+
52+ def fetch (self , method , url , options : Dict ) -> Response :
53+ if 'headers' not in options :
54+ options ['headers' ] = {}
55+
56+ if self .session :
57+ auth_headers = self .session .get_auth_headers (url , method )
58+ options ['headers' ].update (auth_headers )
59+
60+ r = self .client .request (method , url , ** options )
61+ return r
62+
63+ def _start_server (self , solid_oidc_client : SolidOidcClient , q : Queue ):
64+ process = Process (target = _run_flask_server , args = (solid_oidc_client , q ))
65+ self ._server_process = process
66+ process .start ()
67+
68+ def _stop_server (self ):
69+ self ._server_process .terminate ()
70+
71+ def login (self , idp ):
72+ solid_oidc_client = SolidOidcClient (storage = MemStore ())
73+ solid_oidc_client .register_client (idp , [OidcAuth .OAUTH_CALLBACK_URI ])
74+ login_url = solid_oidc_client .create_login_uri ('/' , OidcAuth .OAUTH_CALLBACK_URI )
75+ q = Queue (1 )
76+ self ._start_server (solid_oidc_client , q )
77+
78+ print (f"Please visit this URL to log-in: { login_url } " )
79+
80+ session = SolidAuthSession .deserialize (q .get ())
81+ self .session = session
82+
83+ self ._stop_server ()
84+
85+
86+ def _run_flask_server (solid_oidc_client : SolidOidcClient , q : Queue ):
87+ app = flask .Flask (__name__ )
88+
89+ @app .get ('/oauth/callback' )
90+ def login_callback ():
91+ code = flask .request .args ['code' ]
92+ state = flask .request .args ['state' ]
93+
94+ session = solid_oidc_client .finish_login (
95+ code = code ,
96+ state = state ,
97+ callback_uri = OidcAuth .OAUTH_CALLBACK_URI ,
98+ )
99+
100+ q .put (session .serialize ())
101+
102+ return flask .Response (
103+ f"Logged in as { session .get_web_id ()} . You can close your browser now." ,
104+ mimetype = 'text/html' )
105+
106+ app .run ('localhost' , 8080 )
0 commit comments