Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AIRFLOW-3745] Fix viewer not able to view dag details #4569

Merged
merged 1 commit into from
Jan 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions airflow/www/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
ROLE_CONFIGS = [
{
'role': 'Viewer',
'perms': viewer_perms,
'perms': viewer_perms | dag_perms,
'vms': viewer_vms | dag_vms
},
{
Expand Down Expand Up @@ -355,11 +355,6 @@ def merge_pv(perm, view_menu):
if pv.permission and pv.view_menu:
all_pvs.add((pv.permission.name, pv.view_menu.name))

# create perm for global logical dag
for dag in dag_vms:
for perm in dag_perms:
merge_pv(perm, dag)

# Get all the active / paused dags and insert them into a set
all_dags_models = session.query(models.DagModel)\
.filter(or_(models.DagModel.is_active, models.DagModel.is_paused))\
Expand Down Expand Up @@ -424,6 +419,7 @@ def update_admin_perm_view(self):
if p not in existing_perms_vms:
existing_perms_vms.add(p)
admin.permissions = list(existing_perms_vms)

self.get_session.commit()

def sync_roles(self):
Expand All @@ -435,6 +431,8 @@ def sync_roles(self):
:return: None.
"""
logging.info('Start syncing user roles.')
# Create global all-dag VM
self.create_perm_vm_for_all_dag()

# Create default user role.
for config in ROLE_CONFIGS:
Expand All @@ -460,3 +458,13 @@ def sync_perm_for_dag(self, dag_id):
perm_on_dag = self.find_permission_view_menu(dag_perm, dag_id)
if perm_on_dag is None:
self.add_permission_view_menu(dag_perm, dag_id)

def create_perm_vm_for_all_dag(self):
"""
Create perm-vm if not exist and insert into FAB security model for all-dags.
"""
# create perm for global logical dag
for dag_vm in dag_vms:
for perm in dag_perms:
self._merge_perm(permission_name=perm,
view_menu_name=dag_vm)
1 change: 1 addition & 0 deletions docs/howto/add-new-role.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ and click ``List Roles`` in the new UI.

The image shows a role which could only write to example_python_operator is created.
And we could assign the given role to a new user using ``airflow users --add-role`` cli command.
Default roles(Admin, User, Viewer, Op) shiped with RBAC could view the details for every dag.
20 changes: 20 additions & 0 deletions tests/www/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from flask._compat import PY2
from parameterized import parameterized
from urllib.parse import quote_plus

from werkzeug.test import Client

from airflow import configuration as conf
Expand Down Expand Up @@ -1035,6 +1036,17 @@ def login(self, username=None, password=None):
role=role_user,
password='test_user')

role_viewer = self.appbuilder.sm.find_role('User')
test_viewer = self.appbuilder.sm.find_user(username='test_viewer')
if not test_viewer:
self.appbuilder.sm.add_user(
username='test_viewer',
first_name='test_viewer',
last_name='test_viewer',
email='[email protected]',
role=role_viewer,
password='test_viewer')

dag_acl_role = self.appbuilder.sm.add_role('dag_acl_tester')
dag_tester = self.appbuilder.sm.find_user(username='dag_tester')
if not dag_tester:
Expand Down Expand Up @@ -1522,6 +1534,14 @@ def test_log_success_for_user(self):
self.check_content_in_response('"message":', resp)
self.check_content_in_response('"metadata":', resp)

def test_tree_view_for_viewer(self):
self.logout()
self.login(username='test_viewer',
password='test_viewer')
url = 'tree?dag_id=example_bash_operator'
resp = self.client.get(url, follow_redirects=True)
self.check_content_in_response('runme_1', resp)


class TestTaskInstanceView(TestBase):
TI_ENDPOINT = '/taskinstance/list/?_flt_0_execution_date={}'
Expand Down