Skip to content

Commit

Permalink
Add OAuth Guest for selected endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
tupui committed Oct 25, 2023
1 parent 49e1cd6 commit c4f9dd5
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 4 deletions.
15 changes: 14 additions & 1 deletion panel/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,8 @@ class BasicAuthProvider(AuthProvider):

def __init__(
self, login_endpoint=None, logout_endpoint=None,
login_template=None, logout_template=None, error_template=None
login_template=None, logout_template=None, error_template=None,
guest_endpoints=None
):
if error_template is None:
self._error_template = ERROR_TEMPLATE
Expand All @@ -868,6 +869,7 @@ def __init__(
self._login_template = _env.from_string(f.read())
self._login_endpoint = login_endpoint or '/login'
self._logout_endpoint = logout_endpoint or '/logout'
self._guest_endpoints = guest_endpoints or []

state.on_session_destroyed(self._remove_user)
super().__init__()
Expand All @@ -879,10 +881,17 @@ def _remove_user(self, session_context):
if not state._active_users[user]:
del state._active_users[user]

def _is_guest(self, uri):
return True if uri in self._guest_endpoints else False

@property
def get_user(self):
def get_user(request_handler):
user = request_handler.get_secure_cookie("user", max_age_days=config.oauth_expiry)

if user is None and self._is_guest(request_handler.request.uri):
user = "guest".encode('utf-8')

if user:
user = user.decode('utf-8')
if user and isinstance(request_handler, WebSocketHandler):
Expand Down Expand Up @@ -927,6 +936,10 @@ def get_user_async(self):
async def get_user(handler):
user = handler.get_secure_cookie('user', max_age_days=config.oauth_expiry)
user = user.decode('utf-8') if user else None

if user is None and self._is_guest(handler.request.uri):
user = "guest"

if user and isinstance(handler, WebSocketHandler):
state._active_users[user] += 1
if not config.oauth_refresh_tokens or user is None:
Expand Down
12 changes: 11 additions & 1 deletion panel/command/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ class Serve(_BkServe):
action = 'store_true',
help = "Whether to automatically OAuth access tokens when they expire.",
)),
('--oauth-guest-endpoints', dict(
action = 'store',
type = str,
help = "Guest endpoints.",
)),
('--login-endpoint', dict(
action = 'store',
type = str,
Expand Down Expand Up @@ -478,14 +483,18 @@ def customize_kwargs(self, args, server_kwargs):
else:
error_template = None

if args.oauth_guest_endpoints:
config.oauth_guest_endpoints = ast.literal_eval(args.oauth_guest_endpoints)

if args.basic_auth:
config.basic_auth = args.basic_auth
if config.basic_auth:
kwargs['auth_provider'] = BasicAuthProvider(
login_endpoint=login_endpoint,
logout_endpoint=logout_endpoint,
login_template=login_template,
logout_template=logout_template
logout_template=logout_template,
guest_endpoints=config.oauth_guest_endpoints,
)

if args.cookie_secret and config.cookie_secret:
Expand Down Expand Up @@ -596,6 +605,7 @@ def customize_kwargs(self, args, server_kwargs):
login_template=login_template,
logout_template=logout_template,
error_template=error_template,
guest_endpoints=config.oauth_guest_endpoints,
)

if args.oauth_redirect_uri and config.oauth_redirect_uri:
Expand Down
10 changes: 10 additions & 0 deletions panel/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ class _config(_base_config):
_oauth_extra_params = param.Dict(default={}, doc="""
Additional parameters required for OAuth provider.""")

_oauth_guest_endpoints = param.List(default=None, doc="""
Guest endpoints.""")

_oauth_refresh_tokens = param.Boolean(default=False, doc="""
Whether to automatically refresh access tokens in the background.""")

Expand Down Expand Up @@ -580,6 +583,13 @@ def oauth_extra_params(self):
else:
return self._oauth_extra_params

@property
def oauth_gest_endpoints(self):
if 'PANEL_OAUTH_GUEST_ENDPOINTS' in os.environ:
return ast.literal_eval(os.environ['PANEL_OAUTH_GUEST_ENDPOINTS'])
else:
return self._oauth_guest_endpoints

@property
def theme(self):
curdoc = state.curdoc
Expand Down
7 changes: 5 additions & 2 deletions panel/io/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,10 @@ def user_info(self) -> Dict[str, Any] | None:
"""
Returns the OAuth user information if enabled.
"""
id_token = self._decode_cookie('id_token')
return decode_token(id_token)
try:
id_token = self._decode_cookie('id_token')
return decode_token(id_token)
except TypeError:
return {"user": "guest", "username": "guest"}

state = _state()

0 comments on commit c4f9dd5

Please sign in to comment.