text: import base64
  
  from flask import url_for
  
  from app import instance_keys, app as original_app
  from data.model.user import regenerate_robot_token, get_robot_and_metadata, get_user
  from endpoints.test.shared import conduct_call, gen_basic_auth
  from util.security.registry_jwt import decode_bearer_token, CLAIM_TUF_ROOTS
  
  from test.fixtures import *
  
  
  def get_robot_password(username):
      parent_name, robot_shortname = username.split("+", 1)
      parent = get_user(parent_name)
      _, token, _ = get_robot_and_metadata(robot_shortname, parent)
      return token
  
  
  @pytest.mark.parametrize(
      "scope, username, password, expected_code, expected_scopes",
      [
          # Invalid repository.
          ("repository:devtable/simple/foo/bar/baz:pull", "devtable", "password", 400, []),
          # Invalid scopes.
          ("some_invalid_scope", "devtable", "password", 400, []),
          # Invalid credentials.
          ("repository:devtable/simple:pull", "devtable", "invalid", 401, []),
          # Valid credentials.
          ("repository:devtable/simple:pull", "devtable", "password", 200, ["devtable/simple:pull"]),
          ("repository:devtable/simple:push", "devtable", "password", 200, ["devtable/simple:push"]),
          (
              "repository:devtable/simple:pull,push",
              "devtable",
              "password",
              200,
              ["devtable/simple:push,pull"],
          ),
          (
              "repository:devtable/simple:pull,push,*",
              "devtable",
              "password",
              200,
              ["devtable/simple:push,pull,*"],
          ),
          (
              "repository:buynlarge/orgrepo:pull,push,*",
              "devtable",
              "password",
              200,
              ["buynlarge/orgrepo:push,pull,*"],
          ),
          ("", "devtable", "password", 200, []),
          # No credentials, non-public repo.
          ("repository:devtable/simple:pull", None, None, 200, ["devtable/simple:"]),
          # No credentials, public repo.
          ("repository:public/publicrepo:pull", None, None, 200, ["public/publicrepo:pull"]),
          # Reader only.
          (
              "repository:buynlarge/orgrepo:pull,push,*",
              "reader",
              "password",
              200,
              ["buynlarge/orgrepo:pull"],
          ),
          # Unknown repository.
          (
              "repository:devtable/unknownrepo:pull,push",
              "devtable",
              "password",
              200,
              ["devtable/unknownrepo:push,pull"],
          ),
          # Unknown repository in another namespace.
          (
              "repository:somenamespace/unknownrepo:pull,push",
              "devtable",
              "password",
              200,
              ["somenamespace/unknownrepo:"],
          ),
          # Disabled namespace.
          (
              ["repository:devtable/simple:pull,push", "repository:disabled/complex:pull"],
              "devtable",
              "password",
              405,
              [],
          ),
          # Multiple scopes.
          (
              ["repository:devtable/simple:pull,push", "repository:devtable/complex:pull"],
              "devtable",
              "password",
              200,
              ["devtable/simple:push,pull", "devtable/complex:pull"],
          ),
          # Multiple scopes with restricted behavior.
          (
              ["repository:devtable/simple:pull,push", "repository:public/publicrepo:pull,push"],
              "devtable",
              "password",
              200,
              ["devtable/simple:push,pull", "public/publicrepo:pull"],
          ),
          (
              ["repository:devtable/simple:pull,push,*", "repository:public/publicrepo:pull,push,*"],
              "devtable",
              "password",
              200,
              ["devtable/simple:push,pull,*", "public/publicrepo:pull"],
          ),
          # Read Only State
          (
              "repository:devtable/readonly:pull,push,*",
              "devtable",
              "password",
              200,
              ["devtable/readonly:pull"],
          ),
          # Mirror State as a typical User
          (
              "repository:devtable/mirrored:pull,push,*",
              "devtable",
              "password",
              200,
              ["devtable/mirrored:pull"],
          ),
          # Mirror State as the robot User should have write access
          (
              "repository:devtable/mirrored:pull,push,*",
              "devtable+dtrobot",
              get_robot_password,
              200,
              ["devtable/mirrored:push,pull"],
          ),
          # Organization repository, org admin
          (
              "repository:buynlarge/orgrepo:pull,push,*",
              "devtable",
              "password",
              200,
              ["buynlarge/orgrepo:push,pull,*"],
          ),
          # Organization repository, org creator
          (
              "repository:buynlarge/orgrepo:pull,push,*",
              "creator",
              "password",
              200,
              ["buynlarge/orgrepo:"],
          ),
          # Organization repository, org reader
          (
              "repository:buynlarge/orgrepo:pull,push,*",
              "reader",
              "password",
              200,
              ["buynlarge/orgrepo:pull"],
          ),
          # Organization repository, freshuser
          (
              "repository:buynlarge/orgrepo:pull,push,*",
              "freshuser",
              "password",
              200,
              ["buynlarge/orgrepo:"],
          ),
      ],
  )
  def test_generate_registry_jwt(
      scope, username, password, expected_code, expected_scopes, app, client
  ):
      params = {
          "service": original_app.config["SERVER_HOSTNAME"],
          "scope": scope,
      }
  
      if callable(password):
          password = password(username)
  
      headers = {}
      if username and password:
          headers["Authorization"] = gen_basic_auth(username, password)
  
      resp = conduct_call(
          client,
          "v2.generate_registry_jwt",
          url_for,
          "GET",
          params,
          {},
          expected_code,
          headers=headers,
      )
      if expected_code != 200:
          return
  
      token = resp.json["token"]
      decoded = decode_bearer_token(token, instance_keys, original_app.config)
      assert decoded["iss"] == "quay"
      assert decoded["aud"] == original_app.config["SERVER_HOSTNAME"]
      assert decoded["sub"] == username if username else "(anonymous)"
  
      expected_access = []
      for scope in expected_scopes:
          name, actions_str = scope.split(":")
          actions = actions_str.split(",") if actions_str else []
  
          expected_access.append(
              {"type": "repository", "name": name, "actions": actions,}
          )
  
      assert decoded["access"] == expected_access
      assert len(decoded["context"][CLAIM_TUF_ROOTS]) == len(expected_scopes)
  