Skip to content

Commit

Permalink
D401 Support - WWW (apache#34933)
Browse files Browse the repository at this point in the history
  • Loading branch information
ferruzzi committed Oct 14, 2023
1 parent 5155e7f commit f8b947e
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 100 deletions.
14 changes: 7 additions & 7 deletions airflow/www/api/experimental/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@


def requires_authentication(function: T):
"""Decorator for functions that require authentication."""
"""Mark a function as requiring authentication."""

@wraps(function)
def decorated(*args, **kwargs):
Expand Down Expand Up @@ -158,7 +158,7 @@ def delete_dag(dag_id):
@requires_authentication
def dag_runs(dag_id):
"""
Returns a list of Dag Runs for a specific DAG ID.
Return a list of Dag Runs for a specific DAG ID.
:query param state: a query string parameter '?state=queued|running|success...'
Expand Down Expand Up @@ -209,7 +209,7 @@ def get_dag_code(dag_id):
@api_experimental.route("/dags/<string:dag_id>/tasks/<string:task_id>", methods=["GET"])
@requires_authentication
def task_info(dag_id, task_id):
"""Returns a JSON with a task's public instance variables."""
"""Return a JSON with a task's public instance variables."""
try:
t_info = get_task(dag_id, task_id)
except AirflowException as err:
Expand All @@ -227,7 +227,7 @@ def task_info(dag_id, task_id):
@api_experimental.route("/dags/<string:dag_id>/paused/<string:paused>", methods=["GET"])
@requires_authentication
def dag_paused(dag_id, paused):
"""(Un)pauses a dag."""
"""(Un)pause a dag."""
is_paused = bool(paused == "true")

models.DagModel.get_dagmodel(dag_id).set_is_paused(
Expand All @@ -252,7 +252,7 @@ def dag_is_paused(dag_id):
@requires_authentication
def task_instance_info(dag_id, execution_date, task_id):
"""
Returns a JSON with a task instance's public instance variables.
Return a JSON with a task instance's public instance variables.
The format for the exec_date is expected to be
"YYYY-mm-DDTHH:MM:SS", for example: "2016-11-16T11:34:15". This will
Expand Down Expand Up @@ -289,7 +289,7 @@ def task_instance_info(dag_id, execution_date, task_id):
@requires_authentication
def dag_run_status(dag_id, execution_date):
"""
Returns a JSON with a dag_run's public instance variables.
Return a JSON with a dag_run's public instance variables.
The format for the exec_date is expected to be
"YYYY-mm-DDTHH:MM:SS", for example: "2016-11-16T11:34:15". This will
Expand Down Expand Up @@ -323,7 +323,7 @@ def dag_run_status(dag_id, execution_date):
@api_experimental.route("/latest_runs", methods=["GET"])
@requires_authentication
def latest_dag_runs():
"""Returns the latest DagRun for each DAG formatted for the UI."""
"""Return the latest DagRun for each DAG formatted for the UI."""
from airflow.models import DagRun

dagruns = DagRun.get_latest_runs()
Expand Down
2 changes: 1 addition & 1 deletion airflow/www/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,6 @@ def cached_app(config=None, testing=False):


def purge_cached_app():
"""Removes the cached version of the app in global state."""
"""Remove the cached version of the app in global state."""
global app
app = None
10 changes: 5 additions & 5 deletions airflow/www/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def get_access_denied_message():

def has_access(permissions: Sequence[tuple[str, str]] | None = None) -> Callable[[T], T]:
"""
Factory for decorator that checks current user's permissions against required permissions.
Check current user's permissions against required permissions.
Deprecated. Do not use this decorator, use one of the decorator `has_access_*` defined in
airflow/www/auth.py instead.
Expand All @@ -70,7 +70,7 @@ def has_access(permissions: Sequence[tuple[str, str]] | None = None) -> Callable

def _has_access_no_details(is_authorized_callback: Callable[[], bool]) -> Callable[[T], T]:
"""
Generic Decorator that checks current user's permissions against required permissions.
Check current user's permissions against required permissions.
This works only for resources with no details. This function is used in some ``has_access_`` functions
below.
Expand Down Expand Up @@ -208,15 +208,15 @@ def decorated(*args, **kwargs):


def has_access_dataset(method: ResourceMethod) -> Callable[[T], T]:
"""Decorator that checks current user's permissions against required permissions for datasets."""
"""Check current user's permissions against required permissions for datasets."""
return _has_access_no_details(lambda: get_auth_manager().is_authorized_dataset(method=method))


def has_access_variable(method: ResourceMethod) -> Callable[[T], T]:
"""Decorator that checks current user's permissions against required permissions for variables."""
"""Check current user's permissions against required permissions for variables."""
return _has_access_no_details(lambda: get_auth_manager().is_authorized_variable(method=method))


def has_access_website() -> Callable[[T], T]:
"""Decorator that checks current user's permissions to access the website."""
"""Check current user's permissions to access the website."""
return _has_access_no_details(lambda: get_auth_manager().is_authorized_website())
4 changes: 2 additions & 2 deletions airflow/www/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def _mask_connection_fields(extra_fields):


def action_logging(func: Callable | None = None, event: str | None = None) -> Callable[[T], T]:
"""Decorator to log user actions."""
"""Log user actions."""

def log_action(f: T) -> T:
@functools.wraps(f)
Expand Down Expand Up @@ -137,7 +137,7 @@ def wrapper(*args, **kwargs):


def gzipped(f: T) -> T:
"""Decorator to make a view compressed."""
"""Make a view compressed."""

@functools.wraps(f)
def view_func(*args, **kwargs):
Expand Down
8 changes: 5 additions & 3 deletions airflow/www/extensions/init_auth_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@


def get_auth_manager_cls() -> type[BaseAuthManager]:
"""Returns just the auth manager class without initializing it.
"""
Return just the auth manager class without initializing it.
Useful to save execution time if only static methods need to be called.
"""
Expand All @@ -46,7 +47,8 @@ def get_auth_manager_cls() -> type[BaseAuthManager]:


def init_auth_manager(app: Flask) -> BaseAuthManager:
"""Initialize the auth manager with the given flask app object.
"""
Initialize the auth manager with the given flask app object.
Import the user manager class and instantiate it.
"""
Expand All @@ -57,7 +59,7 @@ def init_auth_manager(app: Flask) -> BaseAuthManager:


def get_auth_manager() -> BaseAuthManager:
"""Returns the auth manager, provided it's been initialized before."""
"""Return the auth manager, provided it's been initialized before."""
if auth_manager is None:
raise Exception(
"Auth Manager has not been initialized yet. "
Expand Down
2 changes: 1 addition & 1 deletion airflow/www/extensions/init_manifest_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@


def configure_manifest_files(app):
"""Loads the manifest file and register the `url_for_asset_` template tag.
"""Load the manifest file and register the `url_for_asset_` template tag.
:param app:
"""
Expand Down
2 changes: 1 addition & 1 deletion airflow/www/extensions/init_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def apply_caching(response):


def init_api_experimental_auth(app):
"""Loads authentication backends."""
"""Load authentication backends."""
auth_backends = "airflow.api.auth.backend.default"
try:
auth_backends = conf.get("api", "auth_backends")
Expand Down
47 changes: 24 additions & 23 deletions airflow/www/fab_security/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@


def _oauth_tokengetter(token=None):
"""Default function to return the current user oauth token from session cookie."""
"""Return the current user oauth token from session cookie."""
token = session.get("oauth")
log.debug("Token Get: %s", token)
return token
Expand Down Expand Up @@ -378,7 +378,7 @@ def current_user(self):

def oauth_user_info_getter(self, f):
"""
Decorator function to be the OAuth user info getter for all the providers.
Get OAuth user info; used by all providers.
Receives provider and response return a dict with the information returned from the provider.
The returned user info dict should have its keys with the same name as the User Model.
Expand Down Expand Up @@ -407,7 +407,7 @@ def wraps(provider, response=None):

def get_oauth_token_key_name(self, provider):
"""
Returns the token_key name for the oauth provider.
Return the token_key name for the oauth provider.
If none is configured defaults to oauth_token
this is configured using OAUTH_PROVIDERS and token_key key.
Expand Down Expand Up @@ -474,7 +474,7 @@ def _rotate_session_id(self):

def auth_user_db(self, username, password):
"""
Method for authenticating user, auth db style.
Authenticate user, auth db style.
:param username:
The username or registered email address
Expand Down Expand Up @@ -506,7 +506,7 @@ def auth_user_db(self, username, password):

def _search_ldap(self, ldap, con, username):
"""
Searches LDAP for user.
Search LDAP for user.
:param ldap: The ldap module reference
:param con: The ldap connection
Expand Down Expand Up @@ -628,7 +628,7 @@ def ldap_extract_list(ldap_dict: dict[str, list[bytes]], field_name: str) -> lis

def auth_user_ldap(self, username, password):
"""
Method for authenticating user with LDAP.
Authenticate user with LDAP.
NOTE: this depends on python-ldap module.
Expand Down Expand Up @@ -885,7 +885,7 @@ def _oauth_calculate_user_roles(self, userinfo) -> list[str]:

def auth_user_oauth(self, userinfo):
"""
Method for authenticating user with OAuth.
Authenticate user with OAuth.
:userinfo: dict with user information
(keys are the same as User model columns)
Expand Down Expand Up @@ -944,7 +944,7 @@ def auth_user_oauth(self, userinfo):
return None

def _has_access_builtin_roles(self, role, action_name: str, resource_name: str) -> bool:
"""Checks permission on builtin role."""
"""Check permission on builtin role."""
perms = self.builtin_roles.get(role.name, [])
for _resource_name, _action_name in perms:
if re2.match(_resource_name, resource_name) and re2.match(_action_name, action_name):
Expand All @@ -954,7 +954,8 @@ def _has_access_builtin_roles(self, role, action_name: str, resource_name: str)
def _get_user_permission_resources(
self, user: User | None, action_name: str, resource_names: list[str] | None = None
) -> set[str]:
"""Get resource names with a certain action name that a user has access to.
"""
Get resource names with a certain action name that a user has access to.
Mainly used to fetch all menu permissions on a single db call, will also
check public permissions and builtin roles
Expand Down Expand Up @@ -1018,7 +1019,7 @@ def add_limit_view(self, baseview):

def add_permissions_view(self, base_action_names, resource_name): # Keep name for compatibility with FAB.
"""
Adds an action on a resource to the backend.
Add an action on a resource to the backend.
:param base_action_names:
list of permissions from view (all exposed methods):
Expand Down Expand Up @@ -1064,7 +1065,7 @@ def add_permissions_view(self, base_action_names, resource_name): # Keep name f

def add_permissions_menu(self, resource_name):
"""
Adds menu_access to resource on permission_resource.
Add menu_access to resource on permission_resource.
:param resource_name:
The resource name
Expand All @@ -1085,7 +1086,7 @@ def get_action(self, name: str) -> Action:

def security_cleanup(self, baseviews, menus):
"""
Will cleanup all unused permissions from the database.
Cleanup all unused permissions from the database.
:param baseviews: A list of BaseViews class
:param menus: Menu class
Expand All @@ -1109,20 +1110,20 @@ def security_cleanup(self, baseviews, menus):
self.delete_resource(resource.name)

def find_user(self, username=None, email=None):
"""Generic function find a user by its username or email."""
"""Find a user by its username or email."""
raise NotImplementedError

def get_role_permissions_from_db(self, role_id: int) -> list[Permission]:
"""Get all DB permissions from a role id."""
raise NotImplementedError

def add_user(self, username, first_name, last_name, email, role, password=""):
"""Generic function to create user."""
"""Create user."""
raise NotImplementedError

def update_user(self, user):
"""
Generic function to update user.
Update user.
:param user: User model to update to database
"""
Expand All @@ -1135,7 +1136,7 @@ def get_all_roles(self):
raise NotImplementedError

def get_public_role(self):
"""Returns all permissions from public role."""
"""Return all permissions from public role."""
raise NotImplementedError

def filter_roles_by_perm_with_action(self, permission_name: str, role_ids: list[int]):
Expand All @@ -1144,7 +1145,7 @@ def filter_roles_by_perm_with_action(self, permission_name: str, role_ids: list[
def permission_exists_in_one_or_more_roles(
self, resource_name: str, action_name: str, role_ids: list[int]
) -> bool:
"""Finds and returns permission views for a group of roles."""
"""Find and returns permission views for a group of roles."""
raise NotImplementedError

"""
Expand All @@ -1155,7 +1156,7 @@ def permission_exists_in_one_or_more_roles(

def get_all_resources(self) -> list[Resource]:
"""
Gets all existing resource records.
Get all existing resource records.
:return: List of all resources
"""
Expand All @@ -1171,7 +1172,7 @@ def create_resource(self, name):

def delete_resource(self, name):
"""
Deletes a Resource from the backend.
Delete a Resource from the backend.
:param name:
name of the Resource
Expand All @@ -1186,7 +1187,7 @@ def delete_resource(self, name):

def get_permission(self, action_name: str, resource_name: str) -> Permission | None:
"""
Gets a permission made with the given action->resource pair, if the permission already exists.
Get a permission made with the given action->resource pair, if the permission already exists.
:param action_name: Name of action
:param resource_name: Name of resource
Expand All @@ -1205,7 +1206,7 @@ def get_resource_permissions(self, resource) -> Permission:

def create_permission(self, action_name: str, resource_name: str) -> Permission | None:
"""
Creates a permission linking an action and resource.
Create a permission linking an action and resource.
:param action_name: Name of existing action
:param resource_name: Name of existing resource
Expand All @@ -1215,7 +1216,7 @@ def create_permission(self, action_name: str, resource_name: str) -> Permission

def delete_permission(self, action_name: str, resource_name: str) -> None:
"""
Deletes the permission linking an action->resource pair.
Delete the permission linking an action->resource pair.
Doesn't delete the underlying action or resource.
Expand Down Expand Up @@ -1249,5 +1250,5 @@ def remove_permission_from_role(self, role, permission) -> None:

@staticmethod
def before_request():
"""Hook runs before request."""
"""Run hook before request."""
g.user = get_auth_manager().get_user()
4 changes: 2 additions & 2 deletions airflow/www/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class DagRunEditForm(DynamicForm):
note = TextAreaField(lazy_gettext("User Note"), widget=BS3TextAreaFieldWidget())

def populate_obj(self, item):
"""Populates the attributes of the passed obj with data from the form's not-read-only fields."""
"""Populate the attributes of the passed obj with data from the form's not-read-only fields."""
for name, field in self._fields.items():
if not field.flags.readonly:
field.populate_obj(item, name)
Expand Down Expand Up @@ -188,7 +188,7 @@ class TaskInstanceEditForm(DynamicForm):
note = TextAreaField(lazy_gettext("User Note"), widget=BS3TextAreaFieldWidget())

def populate_obj(self, item):
"""Populates the attributes of the passed obj with data from the form's not-read-only fields."""
"""Populate the attributes of the passed obj with data from the form's not-read-only fields."""
for name, field in self._fields.items():
if not field.flags.readonly:
field.populate_obj(item, name)
Expand Down
Loading

0 comments on commit f8b947e

Please sign in to comment.