Running Airflow 2.1.2. Setup using oauth authentication (azure). With the public permissions role if a user did not have a valid role in Azure AD or did not login I got all sorts of redirect loops and errors. So I updated the public permissions to: [can read on Website, menu access on My Profile, can read on My Profile, menu access on Documentation, menu access on Docs]. So basically a user not logged in can view a nearly empty airflow UI and click the "Login" button to login. I also added a group to my Azure AD with the role public that includes all users in the subscription. So users can login and it will create an account in airflow for them and they see the same thing as if they are not logged in. Then if someone added them in to a role in the azure enterprise application with a different role when the login they will have what they need. Keeps everything clean and no redirect errors, etc... always just nice airflow screens.

Now one issue I noticed is with the "can read on Website" permission added to a public role the dag errors appears and are not hidden. Since the errors are related to dags I and the user does not have any dag related permissions I would think the errors would not be displayed. 

I'm wondering if this is an issue or more of something that should be a new feature? Cause if I can't view the dag should I be able to view the errors for it? Like adding a role "can read on Website Errors" if a new feature or update the code to tie the display of there errors into a role permission that they are related to like can view one of the dags permissions.  

Not logged in or logged in as a user who is defaulted to "Public" role and you can see the red errors that can be expanded and see line reference details of the errors:
![image](https://user-images.githubusercontent.com/83670736/129922067-e0da80fb-f6ab-44fc-80ea-9b9c7f685bb2.png)

airflow/www/views.py
"""
    Create the list of edges needed to construct the Graph view.
    A special case is made if a TaskGroup is immediately upstream/downstream of another
    TaskGroup or task. Two dummy nodes named upstream_join_id and downstream_join_id are
    created for the TaskGroup. Instead of drawing an edge onto every task in the TaskGroup,
    all edges are directed onto the dummy nodes. This is to cut down the number of edges on
    the graph.
    For example: A DAG with TaskGroups group1 and group2:
        group1: task1, task2, task3
        group2: task4, task5, task6
    group2 is downstream of group1:
        group1 >> group2
    Edges to add (This avoids having to create edges between every task in group1 and group2):
        task1 >> downstream_join_id
        task2 >> downstream_join_id
        task3 >> downstream_join_id
        downstream_join_id >> upstream_join_id
        upstream_join_id >> task4
        upstream_join_id >> task5
        upstream_join_id >> task6
    """
    
    edges_to_add = set()
    
    edges_to_skip = set()
    task_group_map = dag.task_group.get_task_group_dict()
    def collect_edges(task_group):