jhtimmins commented on a change in pull request #11189:
URL: https://github.com/apache/airflow/pull/11189#discussion_r503365859
##########
File path: airflow/www/security.py
##########
@@ -320,33 +307,75 @@ def get_accessible_dags(self, user_actions, user,
session=None):
for permission in role.permissions:
resource = permission.view_menu.name
action = permission.permission.name
- if action in user_actions:
+ if action not in user_actions:
+ continue
+
+ if resource.startswith(permissions.RESOURCE_DAG_PREFIX):
+
resources.add(resource[len(permissions.RESOURCE_DAG_PREFIX) :])
+ else:
resources.add(resource)
- if bool({'Dag', 'all_dags'}.intersection(resources)):
+ if permissions.RESOURCE_ALL_DAGS in resources:
return session.query(DagModel)
return session.query(DagModel).filter(DagModel.dag_id.in_(resources))
- def has_access(self, permission, view_name, user=None) -> bool:
+ def can_read_dag(self, dag_id, user=None) -> bool:
+ """Determines whether a user has DAG read access."""
+ if not user:
+ user = g.user
+ prefixed_dag_id = self.prefixed_dag_id(dag_id)
+ return self._has_view_access(
+ user, permissions.ACTION_CAN_READ, permissions.RESOURCE_ALL_DAGS
+ ) or self._has_view_access(user, permissions.ACTION_CAN_READ,
prefixed_dag_id)
+
+ def can_edit_dag(self, dag_id, user=None) -> bool:
+ """Determines whether a user has DAG edit access."""
+ if not user:
+ user = g.user
+ prefixed_dag_id = self.prefixed_dag_id(dag_id)
+
+ return self._has_view_access(
+ user, permissions.ACTION_CAN_EDIT, permissions.RESOURCE_ALL_DAGS
+ ) or self._has_view_access(user, permissions.ACTION_CAN_EDIT,
prefixed_dag_id)
+
+ def prefixed_dag_id(self, dag_id):
+ """Returns the permission name for a DAG id."""
+ if dag_id == permissions.RESOURCE_ALL_DAGS:
+ return dag_id
+
+ if dag_id.startswith(permissions.RESOURCE_DAG_PREFIX):
+ return dag_id
+ return f"{permissions.RESOURCE_DAG_PREFIX}{dag_id}"
+
+ def has_access(self, permission, resource, user=None) -> bool:
"""
Verify whether a given user could perform certain permission
(e.g can_read, can_write) on the given dag_id.
:param permission: permission on dag_id(e.g can_read, can_edit).
:type permission: str
- :param view_name: name of view-menu(e.g dag id is a view-menu as well).
- :type view_name: str
+ :param resource: name of view-menu or resource.
+ :type resource: str
:param user: user name
:type user: str
:return: a bool whether user could perform certain permission on the
dag_id.
:rtype bool
"""
if not user:
user = g.user
+
if user.is_anonymous:
- return self.is_item_public(permission, view_name)
- return self._has_view_access(user, permission, view_name)
+ return self.is_item_public(permission, resource)
+
+ has_access = self._has_view_access(user, permission, resource)
+
+ if permission == permissions.ACTION_CAN_READ:
+ has_access |= self.can_read_dag(resource, user)
+ elif permission == permissions.ACTION_CAN_EDIT:
+ has_access |= self.can_edit_dag(resource, user)
Review comment:
Shoot, you're right. Good catch. I'll add a test to `test_security.py`.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]