Skip to content

Commit

Permalink
feat(AuthCallback): add AuthCallback class and convert authorize func…
Browse files Browse the repository at this point in the history
…tion to a method

now the authorization callback is a method of an object instantiated by hydra, selected from auth/default.yaml config file
change auth/default.yaml config file to instantiate an object instead of a function
  • Loading branch information
Michele-Alberti committed Jan 4, 2025
1 parent 5273194 commit 2042e91
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 48 deletions.
6 changes: 2 additions & 4 deletions dlunch/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,10 @@ def run_app(config: DictConfig) -> None:
# Configurations
pn.config.nthreads = config.panel.nthreads
pn.config.notifications = True
authorize_callback_factory = hydra.utils.call(
authorize_callback_object: auth.AuthCallback = hydra.utils.instantiate(
config.auth.authorization_callback, config
)
pn.config.authorize_callback = lambda ui, tp: authorize_callback_factory(
user_info=ui, target_path=tp
)
pn.config.authorize_callback = authorize_callback_object.authorize
pn.config.auth_template = config.auth.auth_error_template

# If basic auth is used the database and users credentials shall be created here
Expand Down
94 changes: 52 additions & 42 deletions dlunch/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ def set_guest_user_password(self) -> str:
if self.is_basic_auth_active():
# If active basic_auth.guest_user is true if guest user is active
is_guest_user_active = self.config.basic_auth.guest_user
log.debug("guest user flag is {is_guest_user_active}")
log.debug(f"guest user flag is {is_guest_user_active}")
else:
# Otherwise the guest user feature is not applicable
is_guest_user_active = False
Expand Down Expand Up @@ -970,51 +970,61 @@ def remove_user(self) -> dict:
}


# FUNCTIONS -------------------------------------------------------------------


def authorize(
config: DictConfig,
user_info: dict,
target_path: str,
authorize_guest_users=False,
) -> bool:
"""Authorization callback: read config, user info and the target path of the
requested resource.
Return `True` (authorized) or `False` (not authorized) by checking current user
and target path.
class AuthCallback:
"""Class to handle authorization callback.
Args:
config (DictConfig): Hydra configuration dictionary.
user_info (dict): dictionary with user info passed by Panel to the authorization handle.
target_path (str): path of the requested resource.
authorize_guest_users (bool, optional): Set to `True` to enable the main page to guest users.
Defaults to `False`.
Returns:
bool: authorization flag. `True` if authorized.
"""
# Set authenticated user from panel state (authentication context is
# instantiated automatically)
auth_user = AuthUser(config=config)
# If authorization is not active authorize every user
if not auth_user.auth_context.is_auth_active():
return True
# Get privileged users
privileged_users = auth_user.auth_context.list_privileged_users()
log.debug(f"target path: {target_path}")
# If user is not authenticated block it
if not auth_user.name:

def __init__(
self, config: DictConfig, authorize_guest_users: bool = False
) -> None:
self.config = config
self.authorize_guest_users = authorize_guest_users

def authorize(self, user_info: dict, target_path: str) -> bool:
"""Authorization callback: read config, user info and the target path of the
requested resource.
Return `True` (authorized) or `False` (not authorized) by checking current user
and target path.
Args:
user_info (dict): dictionary with user info passed by Panel to the authorization handle.
target_path (str): path of the requested resource.
Returns:
bool: authorization flag. `True` if authorized.
"""
# Set authenticated user from panel state (authentication context is
# instantiated automatically)
auth_user = AuthUser(config=self.config)
# If authorization is not active authorize every user
if not auth_user.auth_context.is_auth_active():
return True
# Get privileged users
privileged_users = auth_user.auth_context.list_privileged_users()
log.debug(f"target path: {target_path}")
# If user is not authenticated block it
if not auth_user.name:
log.debug("user not authenticated")
return False
# All privileged users can reach backend (but the backend will have
# controls only for admins)
if auth_user.name in privileged_users:
return True
# If the target is the mainpage always authorized (if authenticated)
if self.authorize_guest_users and (target_path == "/"):
return True

# In all other cases, don't authorize and logout
log.debug("not authorized")
pn.state.location.pathname.split("/")[0] + "/logout"
return False
# All privileged users can reach backend (but the backend will have
# controls only for admins)
if auth_user.name in privileged_users:
return True
# If the target is the mainpage always authorized (if authenticated)
if authorize_guest_users and (target_path == "/"):
return True

# In all other cases, don't authorize and logout
pn.state.location.pathname.split("/")[0] + "/logout"
return False


# FUNCTIONS -------------------------------------------------------------------
# Intentionally left void
3 changes: 1 addition & 2 deletions dlunch/conf/auth/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ oauth_expiry: 15
auth_error_template: ${package_path}/templates/error.html
# Autorization callback (_partial_ is required for usage with lambda functions)
authorization_callback:
_target_: dlunch.auth.authorize
_partial_: true
_target_: dlunch.auth.AuthCallback
# Flag to authorize access of guest users to the home page
# They can only place orders for guests
authorize_guest_users: true
Expand Down

0 comments on commit 2042e91

Please sign in to comment.