code: def actor_from_request(datasette, request):
      prefix = "dstok_"
      if not datasette.setting("allow_signed_tokens"):
          return None
      max_signed_tokens_ttl = datasette.setting("max_signed_tokens_ttl")
      authorization = request.headers.get("authorization")
      if not authorization:
          return None
      if not authorization.startswith("Bearer "):
          return None
      token = authorization[len("Bearer ") :]
      if not token.startswith(prefix):
          return None
      token = token[len(prefix) :]
      try:
          decoded = datasette.unsign(token, namespace="token")
      except itsdangerous.BadSignature:
          return None
      if "t" not in decoded:
          # Missing timestamp
          return None
      created = decoded["t"]
      if not isinstance(created, int):
          # Invalid timestamp
          return None
      duration = decoded.get("d")
      if duration is not None and not isinstance(duration, int):
          # Invalid duration
          return None
      if (duration is None and max_signed_tokens_ttl) or (
          duration is not None
          and max_signed_tokens_ttl
          and duration > max_signed_tokens_ttl
      ):
          duration = max_signed_tokens_ttl
      if duration:
          if time.time() - created > duration:
              # Expired
              return None
      actor = {"id": decoded["a"], "token": "dstok"}
      if "_r" in decoded:
          actor["_r"] = decoded["_r"]
      if duration:
          actor["token_expires"] = created + duration
      return actor
  
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 5 for calling a global function with example usage: actor_from_request(datasette, request) and returns: actor, None, None, None, None, None, None, None, None, None