code: def restrictions_allow_action(
      datasette: "Datasette",
      restrictions: dict,
      action: str,
      resource: Union[str, Tuple[str, str]],
  ):
      "Do these restrictions allow the requested action against the requested resource?"
      if action == "view-instance":
          # Special case for view-instance: it's allowed if the restrictions include any
          # permissions that have the implies_can_view=True flag set
          all_rules = restrictions.get("a") or []
          for database_rules in (restrictions.get("d") or {}).values():
              all_rules += database_rules
          for database_resource_rules in (
              restrictions.get("r") or {}
          ).values():
              for resource_rules in database_resource_rules.values():
                  all_rules += resource_rules
          permissions = [
              datasette.get_permission(action) for action in all_rules
          ]
          if any(p for p in permissions if p.implies_can_view):
              return True
  
      if action == "view-database":
          # Special case for view-database: it's allowed if the restrictions include any
          # permissions that have the implies_can_view=True flag set AND takes_database
          all_rules = restrictions.get("a") or []
          database_rules = list(
              (restrictions.get("d") or {}).get(resource) or []
          )
          all_rules += database_rules
          resource_rules = (
              (restrictions.get("r") or {}).get(resource) or {}
          ).values()
          for resource_rules in (restrictions.get("r") or {}).values():
              for table_rules in resource_rules.values():
                  all_rules += table_rules
          permissions = [
              datasette.get_permission(action) for action in all_rules
          ]
          if any(
              p
              for p in permissions
              if p.implies_can_view and p.takes_database
          ):
              return True
  
      # Does this action have an abbreviation?
      to_check = {action}
      permission = datasette.permissions.get(action)
      if permission and permission.abbr:
          to_check.add(permission.abbr)
  
      # If restrictions is defined then we use those to further restrict the actor
      # Crucially, we only use this to say NO (return False) - we never
      # use it to return YES (True) because that might over-ride other
      # restrictions placed on this actor
      all_allowed = restrictions.get("a")
      if all_allowed is not None:
          assert isinstance(all_allowed, list)
          if to_check.intersection(all_allowed):
              return True
      # How about for the current database?
      if resource:
          if isinstance(resource, str):
              database_name = resource
          else:
              database_name = resource[0]
          database_allowed = restrictions.get("d", {}).get(
              database_name
          )
          if database_allowed is not None:
              assert isinstance(database_allowed, list)
              if to_check.intersection(database_allowed):
                  return True
      # Or the current table? That's any time the resource is (database, table)
      if (
          resource is not None
          and not isinstance(resource, str)
          and len(resource) == 2
      ):
          database, table = resource
          table_allowed = (
              restrictions.get("r", {}).get(database, {}).get(table)
          )
          # TODO: What should this do for canned queries?
          if table_allowed is not None:
              assert isinstance(table_allowed, list)
              if to_check.intersection(table_allowed):
                  return True
  
      # This action is not specifically allowed, so reject it
      return False
  
file_path: datasette/datasette/default_permissions.py
imports: from datasette import hookimpl, Permission
  from datasette.utils import actor_matches_allow
  import itsdangerous
  import time
  from typing import Union, Tuple
label_desc: Use image node_id 3 for calling a global function with example usage: restrictions_allow_action(datasette, restrictions, action, resource) and returns: False, True, True, True, True, True