We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Model eligibility verification form field validation
Our current practice has been to offload input validation to the Eligibility Server, since we're simply a pass-through for rules and data defined there.

However this creates at least a couple potential issues:

* The user must submit their information before they know if it's formatted incorrectly, vs. immediate in-browser feedback
* The fields allow for any size and type of value, a potential DDoS vector

Given we will have more than one `EligibilityVerifier` in the next phase, each with unique form validation needs and UX considerations, now is the time to implement Eligibility verification form field validation.

## Tasks

* [x] Add a `TextField` or similar to the `EligibilityVerifier` model that captures a regex pattern that can be used to validate the `sub` field in the [eligibility verification form](https://github.com/cal-itp/benefits/blob/dev/benefits/eligibility/forms.py#L15).
* [x] Add a `PositiveIntegerField` or similar to the `EligibilityVerifier` model that captures the maximum allowed length for the `name` field in the form.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `benefits/core/models.py`
Content:
```
1 """
2 The core application: Common model definitions.
3 """
4 import logging
5 
6 from django.db import models
7 from django.urls import reverse
8 
9 from jwcrypto import jwk
10 
11 
12 logger = logging.getLogger(__name__)
13 
14 
15 class PemData(models.Model):
16     """API Certificate or Key in PEM format."""
17 
18     id = models.AutoField(primary_key=True)
19     text = models.TextField(help_text="The data in utf-8 encoded PEM text format.")
20     label = models.TextField(help_text="Human description of the PEM data.")
21 
22     def __str__(self):
23         return self.label
24 
25     @property
26     def jwk(self):
27         """jwcrypto.jwk.JWK instance from this PemData."""
28         pem_bytes = bytes(self.text, "utf-8")
29         return jwk.JWK.from_pem(pem_bytes)
30 
31 
32 class EligibilityType(models.Model):
33     """A single conditional eligibility type."""
34 
35     id = models.AutoField(primary_key=True)
36     name = models.TextField()
37     label = models.TextField()
38     group_id = models.TextField()
39 
40     def __str__(self):
41         return self.label
42 
43     @staticmethod
44     def get(id):
45         """Get an EligibilityType instance by its id."""
46         logger.debug(f"Get {EligibilityType.__name__} by id: {id}")
47         return EligibilityType.objects.get(pk=id)
48 
49     @staticmethod
50     def get_many(ids):
51         """Get a list of EligibilityType instances from a list of ids."""
52         logger.debug(f"Get {EligibilityType.__name__} list by ids: {ids}")
53         return EligibilityType.objects.filter(id__in=ids)
54 
55 
56 class EligibilityVerifier(models.Model):
57     """An entity that verifies eligibility."""
58 
59     # fmt: off
60     id = models.AutoField(primary_key=True)
61     name = models.TextField()
62     api_url = models.TextField()
63     api_auth_header = models.TextField()
64     api_auth_key = models.TextField()
65     eligibility_types = models.ManyToManyField(EligibilityType)
66     public_key = models.ForeignKey(PemData, help_text="The Verifier's public key, used to encrypt requests targeted at this Verifier and to verify signed responses from this verifier.", related_name="+", on_delete=models.PROTECT)  # noqa: 503
67     jwe_cek_enc = models.TextField(help_text="The JWE-compatible Content Encryption Key (CEK) key-length and mode")
68     jwe_encryption_alg = models.TextField(help_text="The JWE-compatible encryption algorithm")
69     jws_signing_alg = models.TextField(help_text="The JWS-compatible signing algorithm")
70     # fmt: on
71 
72     def __str__(self):
73         return self.name
74 
75     @property
76     def public_jwk(self):
77         """jwcrypto.jwk.JWK instance of this Verifier's public key"""
78         return self.public_key.jwk
79 
80 
81 class PaymentProcessor(models.Model):
82     """An entity that processes payments for transit agencies."""
83 
84     # fmt: off
85     id = models.AutoField(primary_key=True)
86     name = models.TextField()
87     api_base_url = models.TextField()
88     api_access_token_endpoint = models.TextField()
89     api_access_token_request_key = models.TextField()
90     api_access_token_request_val = models.TextField()
91     card_tokenize_url = models.TextField()
92     card_tokenize_func = models.TextField()
93     card_tokenize_env = models.TextField()
94     client_cert = models.ForeignKey(PemData, help_text="The certificate used for client certificate authentication to the API.", related_name="+", on_delete=models.PROTECT)  # noqa: 503
95     client_cert_private_key = models.ForeignKey(PemData, help_text="The private key, used to sign the certificate.", related_name="+", on_delete=models.PROTECT)  # noqa: 503
96     client_cert_root_ca = models.ForeignKey(PemData, help_text="The root CA bundle, used to verify the server.", related_name="+", on_delete=models.PROTECT)  # noqa: 503
97     customer_endpoint = models.TextField()
98     customers_endpoint = models.TextField()
99     group_endpoint = models.TextField()
100     # fmt: on
101 
102     def __str__(self):
103         return self.name
104 
105 
106 class TransitAgency(models.Model):
107     """An agency offering transit service."""
108 
109     # fmt: off
110     id = models.AutoField(primary_key=True)
111     slug = models.TextField()
112     short_name = models.TextField()
113     long_name = models.TextField()
114     agency_id = models.TextField()
115     merchant_id = models.TextField()
116     info_url = models.URLField()
117     phone = models.TextField()
118     active = models.BooleanField(default=False)
119     eligibility_types = models.ManyToManyField(EligibilityType)
120     eligibility_verifiers = models.ManyToManyField(EligibilityVerifier)
121     payment_processor = models.ForeignKey(PaymentProcessor, on_delete=models.PROTECT)
122     private_key = models.ForeignKey(PemData, help_text="The Agency's private key, used to sign tokens created on behalf of this Agency.", related_name="+", on_delete=models.PROTECT)  # noqa: 503
123     jws_signing_alg = models.TextField(help_text="The JWS-compatible signing algorithm.")
124     # fmt: on
125 
126     def __str__(self):
127         return self.long_name
128 
129     def get_type_id(self, name):
130         """Get the id of the EligibilityType identified by the given name for this agency."""
131         eligibility = self.eligibility_types.all().filter(name=name)
132         if eligibility.count() == 1:
133             return eligibility[0].id
134         else:
135             raise Exception("name does not correspond to a single eligibility type for agency")
136 
137     def supports_type(self, eligibility_type):
138         """True if the eligibility_type is one of this agency's types. False otherwise."""
139         return isinstance(eligibility_type, EligibilityType) and eligibility_type in self.eligibility_types.all()
140 
141     def types_to_verify(self, eligibility_verifier):
142         """List of eligibility types to verify for this agency."""
143         # compute set intersection of agency and verifier type ids
144         agency_types = set(self.eligibility_types.values_list("id", flat=True))
145         verifier_types = set(eligibility_verifier.eligibility_types.values_list("id", flat=True))
146         supported_types = list(agency_types & verifier_types)
147         return EligibilityType.get_many(supported_types)
148 
149     @property
150     def index_url(self):
151         """Url to the TransitAgency's landing page."""
152         return reverse("core:agency_index", args=[self.slug])
153 
154     @property
155     def private_jwk(self):
156         """jwcrypto.jwk.JWK instance of this Agency's private key"""
157         return self.private_key.jwk
158 
159     @staticmethod
160     def by_id(id):
161         """Get a TransitAgency instance by its ID."""
162         logger.debug(f"Get {TransitAgency.__name__} by id: {id}")
163         return TransitAgency.objects.get(id=id)
164 
165     @staticmethod
166     def by_slug(slug):
167         """Get a TransitAgency instance by its slug."""
168         logger.debug(f"Get {TransitAgency.__name__} by slug: {slug}")
169         return TransitAgency.objects.filter(slug=slug).first()
170 
171     @staticmethod
172     def all_active():
173         """Get all TransitAgency instances marked active."""
174         logger.debug(f"Get all active {TransitAgency.__name__}")
175         return TransitAgency.objects.filter(active=True)
176
```

Path: `benefits/core/migrations/0001_initial.py`
Content:
```
1 from django.db import migrations, models
2 
3 
4 class Migration(migrations.Migration):
5 
6     initial = True
7 
8     dependencies = []
9 
10     operations = [
11         migrations.CreateModel(
12             name="EligibilityType",
13             fields=[
14                 ("id", models.AutoField(primary_key=True, serialize=False, verbose_name="ID")),
15                 ("name", models.TextField()),
16                 ("label", models.TextField()),
17                 ("group_id", models.TextField()),
18             ],
19         ),
20         migrations.CreateModel(
21             name="PemData",
22             fields=[
23                 ("id", models.AutoField(primary_key=True, serialize=False)),
24                 ("text", models.TextField(help_text="The data in utf-8 encoded PEM text format.")),
25                 ("label", models.TextField(help_text="Human description of the PEM data.")),
26             ],
27         ),
28         migrations.CreateModel(
29             name="EligibilityVerifier",
30             fields=[
31                 ("id", models.AutoField(primary_key=True, serialize=False, verbose_name="ID")),
32                 ("name", models.TextField()),
33                 ("api_url", models.TextField()),
34                 ("api_auth_header", models.TextField()),
35                 ("api_auth_key", models.TextField()),
36                 # fmt: off
37                 ("public_key", models.ForeignKey(help_text="The Verifier's public key, used to encrypt requests targeted at this Verifier and to verify signed responses from this verifier.", on_delete=models.deletion.PROTECT, related_name="+", to="core.PemData")),  # noqa: E501
38                 ("jwe_cek_enc", models.TextField(help_text="The JWE-compatible Content Encryption Key (CEK) key-length and mode")),  # noqa: E501
39                 ("jwe_encryption_alg", models.TextField(help_text="The JWE-compatible encryption algorithm")),
40                 # fmt: on
41                 ("jws_signing_alg", models.TextField(help_text="The JWS-compatible signing algorithm")),
42                 ("eligibility_types", models.ManyToManyField(to="core.EligibilityType")),
43             ],
44         ),
45         migrations.CreateModel(
46             name="PaymentProcessor",
47             fields=[
48                 ("id", models.AutoField(primary_key=True, serialize=False, verbose_name="ID")),
49                 ("name", models.TextField()),
50                 ("api_base_url", models.TextField()),
51                 ("api_access_token_endpoint", models.TextField()),
52                 ("api_access_token_request_key", models.TextField()),
53                 ("api_access_token_request_val", models.TextField()),
54                 ("card_tokenize_url", models.TextField()),
55                 ("card_tokenize_func", models.TextField()),
56                 ("card_tokenize_env", models.TextField()),
57                 # fmt: off
58                 ("client_cert", models.ForeignKey(help_text="The certificate used for client certificate authentication to the API.", on_delete=models.deletion.PROTECT, related_name="+", to="core.PemData")),  # noqa: E501
59                 ("client_cert_private_key", models.ForeignKey(help_text="The private key used to sign the certificate.", on_delete=models.deletion.PROTECT, related_name="+", to="core.PemData")),  # noqa: E501
60                 ("client_cert_root_ca", models.ForeignKey(help_text="The root CA bundle used to verify the server.", on_delete=models.deletion.PROTECT, related_name="+", to="core.PemData")),  # noqa: E501
61                 ("customer_endpoint", models.TextField()),
62                 # fmt: on
63                 ("customers_endpoint", models.TextField()),
64                 ("group_endpoint", models.TextField()),
65             ],
66         ),
67         migrations.CreateModel(
68             name="TransitAgency",
69             fields=[
70                 ("id", models.AutoField(primary_key=True, serialize=False, verbose_name="ID")),
71                 ("slug", models.TextField()),
72                 ("short_name", models.TextField()),
73                 ("long_name", models.TextField()),
74                 ("agency_id", models.TextField()),
75                 ("merchant_id", models.TextField()),
76                 ("info_url", models.URLField()),
77                 ("phone", models.TextField()),
78                 ("active", models.BooleanField(default=False)),
79                 # fmt: off
80                 ("private_key", models.ForeignKey(help_text="The Agency's private key, used to sign tokens created on behalf of this Agency.", on_delete=models.deletion.PROTECT, related_name="+", to="core.PemData")),  # noqa: E501
81                 ("jws_signing_alg", models.TextField(help_text="The JWS-compatible signing algorithm.")),
82                 ("payment_processor", models.ForeignKey(on_delete=models.deletion.PROTECT, to="core.paymentprocessor")),
83                 ("eligibility_types", models.ManyToManyField(to="core.EligibilityType")),
84                 ("eligibility_verifiers", models.ManyToManyField(to="core.eligibilityverifier")),
85                 # fmt: on
86             ],
87         ),
88     ]
89
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/benefits/core/migrations/0001_initial.py b/benefits/core/migrations/0001_initial.py
--- a/benefits/core/migrations/0001_initial.py
+++ b/benefits/core/migrations/0001_initial.py
@@ -34,6 +34,8 @@
                 ("api_auth_header", models.TextField()),
                 ("api_auth_key", models.TextField()),
                 # fmt: off
+                ("sub_regex", models.TextField(help_text="A regular expression used to validate the 'sub' API field before sending to this verifier", null=True)),  # noqa: E501
+                ("name_max_length", models.PositiveSmallIntegerField(help_text="The maximum length accepted for the 'name' API field before sending to this verifier", null=True)),  # noqa: E501
                 ("public_key", models.ForeignKey(help_text="The Verifier's public key, used to encrypt requests targeted at this Verifier and to verify signed responses from this verifier.", on_delete=models.deletion.PROTECT, related_name="+", to="core.PemData")),  # noqa: E501
                 ("jwe_cek_enc", models.TextField(help_text="The JWE-compatible Content Encryption Key (CEK) key-length and mode")),  # noqa: E501
                 ("jwe_encryption_alg", models.TextField(help_text="The JWE-compatible encryption algorithm")),
diff --git a/benefits/core/models.py b/benefits/core/models.py
--- a/benefits/core/models.py
+++ b/benefits/core/models.py
@@ -67,6 +67,8 @@
     jwe_cek_enc = models.TextField(help_text="The JWE-compatible Content Encryption Key (CEK) key-length and mode")
     jwe_encryption_alg = models.TextField(help_text="The JWE-compatible encryption algorithm")
     jws_signing_alg = models.TextField(help_text="The JWS-compatible signing algorithm")
+    sub_regex = models.TextField(null=True, help_text="A regular expression used to validate the 'sub' API field before sending to this verifier")  # noqa: 503
+    name_max_length = models.PositiveSmallIntegerField(null=True, help_text="The maximum length accepted for the 'name' API field before sending to this verifier")  # noqa: 503
     # fmt: on
 
     def __str__(self):

{"golden_diff": "diff --git a/benefits/core/migrations/0001_initial.py b/benefits/core/migrations/0001_initial.py\n--- a/benefits/core/migrations/0001_initial.py\n+++ b/benefits/core/migrations/0001_initial.py\n@@ -34,6 +34,8 @@\n                 (\"api_auth_header\", models.TextField()),\n                 (\"api_auth_key\", models.TextField()),\n                 # fmt: off\n+                (\"sub_regex\", models.TextField(help_text=\"A regular expression used to validate the 'sub' API field before sending to this verifier\", null=True)),  # noqa: E501\n+                (\"name_max_length\", models.PositiveSmallIntegerField(help_text=\"The maximum length accepted for the 'name' API field before sending to this verifier\", null=True)),  # noqa: E501\n                 (\"public_key\", models.ForeignKey(help_text=\"The Verifier's public key, used to encrypt requests targeted at this Verifier and to verify signed responses from this verifier.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                 (\"jwe_cek_enc\", models.TextField(help_text=\"The JWE-compatible Content Encryption Key (CEK) key-length and mode\")),  # noqa: E501\n                 (\"jwe_encryption_alg\", models.TextField(help_text=\"The JWE-compatible encryption algorithm\")),\ndiff --git a/benefits/core/models.py b/benefits/core/models.py\n--- a/benefits/core/models.py\n+++ b/benefits/core/models.py\n@@ -67,6 +67,8 @@\n     jwe_cek_enc = models.TextField(help_text=\"The JWE-compatible Content Encryption Key (CEK) key-length and mode\")\n     jwe_encryption_alg = models.TextField(help_text=\"The JWE-compatible encryption algorithm\")\n     jws_signing_alg = models.TextField(help_text=\"The JWS-compatible signing algorithm\")\n+    sub_regex = models.TextField(null=True, help_text=\"A regular expression used to validate the 'sub' API field before sending to this verifier\")  # noqa: 503\n+    name_max_length = models.PositiveSmallIntegerField(null=True, help_text=\"The maximum length accepted for the 'name' API field before sending to this verifier\")  # noqa: 503\n     # fmt: on\n \n     def __str__(self):\n", "issue": "Model eligibility verification form field validation\nOur current practice has been to offload input validation to the Eligibility Server, since we're simply a pass-through for rules and data defined there.\r\n\r\nHowever this creates at least a couple potential issues:\r\n\r\n* The user must submit their information before they know if it's formatted incorrectly, vs. immediate in-browser feedback\r\n* The fields allow for any size and type of value, a potential DDoS vector\r\n\r\nGiven we will have more than one `EligibilityVerifier` in the next phase, each with unique form validation needs and UX considerations, now is the time to implement Eligibility verification form field validation.\r\n\r\n## Tasks\r\n\r\n* [x] Add a `TextField` or similar to the `EligibilityVerifier` model that captures a regex pattern that can be used to validate the `sub` field in the [eligibility verification form](https://github.com/cal-itp/benefits/blob/dev/benefits/eligibility/forms.py#L15).\r\n* [x] Add a `PositiveIntegerField` or similar to the `EligibilityVerifier` model that captures the maximum allowed length for the `name` field in the form.\n", "before_files": [{"content": "\"\"\"\nThe core application: Common model definitions.\n\"\"\"\nimport logging\n\nfrom django.db import models\nfrom django.urls import reverse\n\nfrom jwcrypto import jwk\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass PemData(models.Model):\n    \"\"\"API Certificate or Key in PEM format.\"\"\"\n\n    id = models.AutoField(primary_key=True)\n    text = models.TextField(help_text=\"The data in utf-8 encoded PEM text format.\")\n    label = models.TextField(help_text=\"Human description of the PEM data.\")\n\n    def __str__(self):\n        return self.label\n\n    @property\n    def jwk(self):\n        \"\"\"jwcrypto.jwk.JWK instance from this PemData.\"\"\"\n        pem_bytes = bytes(self.text, \"utf-8\")\n        return jwk.JWK.from_pem(pem_bytes)\n\n\nclass EligibilityType(models.Model):\n    \"\"\"A single conditional eligibility type.\"\"\"\n\n    id = models.AutoField(primary_key=True)\n    name = models.TextField()\n    label = models.TextField()\n    group_id = models.TextField()\n\n    def __str__(self):\n        return self.label\n\n    @staticmethod\n    def get(id):\n        \"\"\"Get an EligibilityType instance by its id.\"\"\"\n        logger.debug(f\"Get {EligibilityType.__name__} by id: {id}\")\n        return EligibilityType.objects.get(pk=id)\n\n    @staticmethod\n    def get_many(ids):\n        \"\"\"Get a list of EligibilityType instances from a list of ids.\"\"\"\n        logger.debug(f\"Get {EligibilityType.__name__} list by ids: {ids}\")\n        return EligibilityType.objects.filter(id__in=ids)\n\n\nclass EligibilityVerifier(models.Model):\n    \"\"\"An entity that verifies eligibility.\"\"\"\n\n    # fmt: off\n    id = models.AutoField(primary_key=True)\n    name = models.TextField()\n    api_url = models.TextField()\n    api_auth_header = models.TextField()\n    api_auth_key = models.TextField()\n    eligibility_types = models.ManyToManyField(EligibilityType)\n    public_key = models.ForeignKey(PemData, help_text=\"The Verifier's public key, used to encrypt requests targeted at this Verifier and to verify signed responses from this verifier.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    jwe_cek_enc = models.TextField(help_text=\"The JWE-compatible Content Encryption Key (CEK) key-length and mode\")\n    jwe_encryption_alg = models.TextField(help_text=\"The JWE-compatible encryption algorithm\")\n    jws_signing_alg = models.TextField(help_text=\"The JWS-compatible signing algorithm\")\n    # fmt: on\n\n    def __str__(self):\n        return self.name\n\n    @property\n    def public_jwk(self):\n        \"\"\"jwcrypto.jwk.JWK instance of this Verifier's public key\"\"\"\n        return self.public_key.jwk\n\n\nclass PaymentProcessor(models.Model):\n    \"\"\"An entity that processes payments for transit agencies.\"\"\"\n\n    # fmt: off\n    id = models.AutoField(primary_key=True)\n    name = models.TextField()\n    api_base_url = models.TextField()\n    api_access_token_endpoint = models.TextField()\n    api_access_token_request_key = models.TextField()\n    api_access_token_request_val = models.TextField()\n    card_tokenize_url = models.TextField()\n    card_tokenize_func = models.TextField()\n    card_tokenize_env = models.TextField()\n    client_cert = models.ForeignKey(PemData, help_text=\"The certificate used for client certificate authentication to the API.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    client_cert_private_key = models.ForeignKey(PemData, help_text=\"The private key, used to sign the certificate.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    client_cert_root_ca = models.ForeignKey(PemData, help_text=\"The root CA bundle, used to verify the server.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    customer_endpoint = models.TextField()\n    customers_endpoint = models.TextField()\n    group_endpoint = models.TextField()\n    # fmt: on\n\n    def __str__(self):\n        return self.name\n\n\nclass TransitAgency(models.Model):\n    \"\"\"An agency offering transit service.\"\"\"\n\n    # fmt: off\n    id = models.AutoField(primary_key=True)\n    slug = models.TextField()\n    short_name = models.TextField()\n    long_name = models.TextField()\n    agency_id = models.TextField()\n    merchant_id = models.TextField()\n    info_url = models.URLField()\n    phone = models.TextField()\n    active = models.BooleanField(default=False)\n    eligibility_types = models.ManyToManyField(EligibilityType)\n    eligibility_verifiers = models.ManyToManyField(EligibilityVerifier)\n    payment_processor = models.ForeignKey(PaymentProcessor, on_delete=models.PROTECT)\n    private_key = models.ForeignKey(PemData, help_text=\"The Agency's private key, used to sign tokens created on behalf of this Agency.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    jws_signing_alg = models.TextField(help_text=\"The JWS-compatible signing algorithm.\")\n    # fmt: on\n\n    def __str__(self):\n        return self.long_name\n\n    def get_type_id(self, name):\n        \"\"\"Get the id of the EligibilityType identified by the given name for this agency.\"\"\"\n        eligibility = self.eligibility_types.all().filter(name=name)\n        if eligibility.count() == 1:\n            return eligibility[0].id\n        else:\n            raise Exception(\"name does not correspond to a single eligibility type for agency\")\n\n    def supports_type(self, eligibility_type):\n        \"\"\"True if the eligibility_type is one of this agency's types. False otherwise.\"\"\"\n        return isinstance(eligibility_type, EligibilityType) and eligibility_type in self.eligibility_types.all()\n\n    def types_to_verify(self, eligibility_verifier):\n        \"\"\"List of eligibility types to verify for this agency.\"\"\"\n        # compute set intersection of agency and verifier type ids\n        agency_types = set(self.eligibility_types.values_list(\"id\", flat=True))\n        verifier_types = set(eligibility_verifier.eligibility_types.values_list(\"id\", flat=True))\n        supported_types = list(agency_types & verifier_types)\n        return EligibilityType.get_many(supported_types)\n\n    @property\n    def index_url(self):\n        \"\"\"Url to the TransitAgency's landing page.\"\"\"\n        return reverse(\"core:agency_index\", args=[self.slug])\n\n    @property\n    def private_jwk(self):\n        \"\"\"jwcrypto.jwk.JWK instance of this Agency's private key\"\"\"\n        return self.private_key.jwk\n\n    @staticmethod\n    def by_id(id):\n        \"\"\"Get a TransitAgency instance by its ID.\"\"\"\n        logger.debug(f\"Get {TransitAgency.__name__} by id: {id}\")\n        return TransitAgency.objects.get(id=id)\n\n    @staticmethod\n    def by_slug(slug):\n        \"\"\"Get a TransitAgency instance by its slug.\"\"\"\n        logger.debug(f\"Get {TransitAgency.__name__} by slug: {slug}\")\n        return TransitAgency.objects.filter(slug=slug).first()\n\n    @staticmethod\n    def all_active():\n        \"\"\"Get all TransitAgency instances marked active.\"\"\"\n        logger.debug(f\"Get all active {TransitAgency.__name__}\")\n        return TransitAgency.objects.filter(active=True)\n", "path": "benefits/core/models.py"}, {"content": "from django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = []\n\n    operations = [\n        migrations.CreateModel(\n            name=\"EligibilityType\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False, verbose_name=\"ID\")),\n                (\"name\", models.TextField()),\n                (\"label\", models.TextField()),\n                (\"group_id\", models.TextField()),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"PemData\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False)),\n                (\"text\", models.TextField(help_text=\"The data in utf-8 encoded PEM text format.\")),\n                (\"label\", models.TextField(help_text=\"Human description of the PEM data.\")),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"EligibilityVerifier\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False, verbose_name=\"ID\")),\n                (\"name\", models.TextField()),\n                (\"api_url\", models.TextField()),\n                (\"api_auth_header\", models.TextField()),\n                (\"api_auth_key\", models.TextField()),\n                # fmt: off\n                (\"public_key\", models.ForeignKey(help_text=\"The Verifier's public key, used to encrypt requests targeted at this Verifier and to verify signed responses from this verifier.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"jwe_cek_enc\", models.TextField(help_text=\"The JWE-compatible Content Encryption Key (CEK) key-length and mode\")),  # noqa: E501\n                (\"jwe_encryption_alg\", models.TextField(help_text=\"The JWE-compatible encryption algorithm\")),\n                # fmt: on\n                (\"jws_signing_alg\", models.TextField(help_text=\"The JWS-compatible signing algorithm\")),\n                (\"eligibility_types\", models.ManyToManyField(to=\"core.EligibilityType\")),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"PaymentProcessor\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False, verbose_name=\"ID\")),\n                (\"name\", models.TextField()),\n                (\"api_base_url\", models.TextField()),\n                (\"api_access_token_endpoint\", models.TextField()),\n                (\"api_access_token_request_key\", models.TextField()),\n                (\"api_access_token_request_val\", models.TextField()),\n                (\"card_tokenize_url\", models.TextField()),\n                (\"card_tokenize_func\", models.TextField()),\n                (\"card_tokenize_env\", models.TextField()),\n                # fmt: off\n                (\"client_cert\", models.ForeignKey(help_text=\"The certificate used for client certificate authentication to the API.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"client_cert_private_key\", models.ForeignKey(help_text=\"The private key used to sign the certificate.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"client_cert_root_ca\", models.ForeignKey(help_text=\"The root CA bundle used to verify the server.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"customer_endpoint\", models.TextField()),\n                # fmt: on\n                (\"customers_endpoint\", models.TextField()),\n                (\"group_endpoint\", models.TextField()),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"TransitAgency\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False, verbose_name=\"ID\")),\n                (\"slug\", models.TextField()),\n                (\"short_name\", models.TextField()),\n                (\"long_name\", models.TextField()),\n                (\"agency_id\", models.TextField()),\n                (\"merchant_id\", models.TextField()),\n                (\"info_url\", models.URLField()),\n                (\"phone\", models.TextField()),\n                (\"active\", models.BooleanField(default=False)),\n                # fmt: off\n                (\"private_key\", models.ForeignKey(help_text=\"The Agency's private key, used to sign tokens created on behalf of this Agency.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"jws_signing_alg\", models.TextField(help_text=\"The JWS-compatible signing algorithm.\")),\n                (\"payment_processor\", models.ForeignKey(on_delete=models.deletion.PROTECT, to=\"core.paymentprocessor\")),\n                (\"eligibility_types\", models.ManyToManyField(to=\"core.EligibilityType\")),\n                (\"eligibility_verifiers\", models.ManyToManyField(to=\"core.eligibilityverifier\")),\n                # fmt: on\n            ],\n        ),\n    ]\n", "path": "benefits/core/migrations/0001_initial.py"}], "after_files": [{"content": "\"\"\"\nThe core application: Common model definitions.\n\"\"\"\nimport logging\n\nfrom django.db import models\nfrom django.urls import reverse\n\nfrom jwcrypto import jwk\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass PemData(models.Model):\n    \"\"\"API Certificate or Key in PEM format.\"\"\"\n\n    id = models.AutoField(primary_key=True)\n    text = models.TextField(help_text=\"The data in utf-8 encoded PEM text format.\")\n    label = models.TextField(help_text=\"Human description of the PEM data.\")\n\n    def __str__(self):\n        return self.label\n\n    @property\n    def jwk(self):\n        \"\"\"jwcrypto.jwk.JWK instance from this PemData.\"\"\"\n        pem_bytes = bytes(self.text, \"utf-8\")\n        return jwk.JWK.from_pem(pem_bytes)\n\n\nclass EligibilityType(models.Model):\n    \"\"\"A single conditional eligibility type.\"\"\"\n\n    id = models.AutoField(primary_key=True)\n    name = models.TextField()\n    label = models.TextField()\n    group_id = models.TextField()\n\n    def __str__(self):\n        return self.label\n\n    @staticmethod\n    def get(id):\n        \"\"\"Get an EligibilityType instance by its id.\"\"\"\n        logger.debug(f\"Get {EligibilityType.__name__} by id: {id}\")\n        return EligibilityType.objects.get(pk=id)\n\n    @staticmethod\n    def get_many(ids):\n        \"\"\"Get a list of EligibilityType instances from a list of ids.\"\"\"\n        logger.debug(f\"Get {EligibilityType.__name__} list by ids: {ids}\")\n        return EligibilityType.objects.filter(id__in=ids)\n\n\nclass EligibilityVerifier(models.Model):\n    \"\"\"An entity that verifies eligibility.\"\"\"\n\n    # fmt: off\n    id = models.AutoField(primary_key=True)\n    name = models.TextField()\n    api_url = models.TextField()\n    api_auth_header = models.TextField()\n    api_auth_key = models.TextField()\n    eligibility_types = models.ManyToManyField(EligibilityType)\n    public_key = models.ForeignKey(PemData, help_text=\"The Verifier's public key, used to encrypt requests targeted at this Verifier and to verify signed responses from this verifier.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    jwe_cek_enc = models.TextField(help_text=\"The JWE-compatible Content Encryption Key (CEK) key-length and mode\")\n    jwe_encryption_alg = models.TextField(help_text=\"The JWE-compatible encryption algorithm\")\n    jws_signing_alg = models.TextField(help_text=\"The JWS-compatible signing algorithm\")\n    sub_regex = models.TextField(null=True, help_text=\"A regular expression used to validate the 'sub' API field before sending to this verifier\")  # noqa: 503\n    name_max_length = models.PositiveSmallIntegerField(null=True, help_text=\"The maximum length accepted for the 'name' API field before sending to this verifier\")  # noqa: 503\n    # fmt: on\n\n    def __str__(self):\n        return self.name\n\n    @property\n    def public_jwk(self):\n        \"\"\"jwcrypto.jwk.JWK instance of this Verifier's public key\"\"\"\n        return self.public_key.jwk\n\n\nclass PaymentProcessor(models.Model):\n    \"\"\"An entity that processes payments for transit agencies.\"\"\"\n\n    # fmt: off\n    id = models.AutoField(primary_key=True)\n    name = models.TextField()\n    api_base_url = models.TextField()\n    api_access_token_endpoint = models.TextField()\n    api_access_token_request_key = models.TextField()\n    api_access_token_request_val = models.TextField()\n    card_tokenize_url = models.TextField()\n    card_tokenize_func = models.TextField()\n    card_tokenize_env = models.TextField()\n    client_cert = models.ForeignKey(PemData, help_text=\"The certificate used for client certificate authentication to the API.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    client_cert_private_key = models.ForeignKey(PemData, help_text=\"The private key, used to sign the certificate.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    client_cert_root_ca = models.ForeignKey(PemData, help_text=\"The root CA bundle, used to verify the server.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    customer_endpoint = models.TextField()\n    customers_endpoint = models.TextField()\n    group_endpoint = models.TextField()\n    # fmt: on\n\n    def __str__(self):\n        return self.name\n\n\nclass TransitAgency(models.Model):\n    \"\"\"An agency offering transit service.\"\"\"\n\n    # fmt: off\n    id = models.AutoField(primary_key=True)\n    slug = models.TextField()\n    short_name = models.TextField()\n    long_name = models.TextField()\n    agency_id = models.TextField()\n    merchant_id = models.TextField()\n    info_url = models.URLField()\n    phone = models.TextField()\n    active = models.BooleanField(default=False)\n    eligibility_types = models.ManyToManyField(EligibilityType)\n    eligibility_verifiers = models.ManyToManyField(EligibilityVerifier)\n    payment_processor = models.ForeignKey(PaymentProcessor, on_delete=models.PROTECT)\n    private_key = models.ForeignKey(PemData, help_text=\"The Agency's private key, used to sign tokens created on behalf of this Agency.\", related_name=\"+\", on_delete=models.PROTECT)  # noqa: 503\n    jws_signing_alg = models.TextField(help_text=\"The JWS-compatible signing algorithm.\")\n    # fmt: on\n\n    def __str__(self):\n        return self.long_name\n\n    def get_type_id(self, name):\n        \"\"\"Get the id of the EligibilityType identified by the given name for this agency.\"\"\"\n        eligibility = self.eligibility_types.all().filter(name=name)\n        if eligibility.count() == 1:\n            return eligibility[0].id\n        else:\n            raise Exception(\"name does not correspond to a single eligibility type for agency\")\n\n    def supports_type(self, eligibility_type):\n        \"\"\"True if the eligibility_type is one of this agency's types. False otherwise.\"\"\"\n        return isinstance(eligibility_type, EligibilityType) and eligibility_type in self.eligibility_types.all()\n\n    def types_to_verify(self, eligibility_verifier):\n        \"\"\"List of eligibility types to verify for this agency.\"\"\"\n        # compute set intersection of agency and verifier type ids\n        agency_types = set(self.eligibility_types.values_list(\"id\", flat=True))\n        verifier_types = set(eligibility_verifier.eligibility_types.values_list(\"id\", flat=True))\n        supported_types = list(agency_types & verifier_types)\n        return EligibilityType.get_many(supported_types)\n\n    @property\n    def index_url(self):\n        \"\"\"Url to the TransitAgency's landing page.\"\"\"\n        return reverse(\"core:agency_index\", args=[self.slug])\n\n    @property\n    def private_jwk(self):\n        \"\"\"jwcrypto.jwk.JWK instance of this Agency's private key\"\"\"\n        return self.private_key.jwk\n\n    @staticmethod\n    def by_id(id):\n        \"\"\"Get a TransitAgency instance by its ID.\"\"\"\n        logger.debug(f\"Get {TransitAgency.__name__} by id: {id}\")\n        return TransitAgency.objects.get(id=id)\n\n    @staticmethod\n    def by_slug(slug):\n        \"\"\"Get a TransitAgency instance by its slug.\"\"\"\n        logger.debug(f\"Get {TransitAgency.__name__} by slug: {slug}\")\n        return TransitAgency.objects.filter(slug=slug).first()\n\n    @staticmethod\n    def all_active():\n        \"\"\"Get all TransitAgency instances marked active.\"\"\"\n        logger.debug(f\"Get all active {TransitAgency.__name__}\")\n        return TransitAgency.objects.filter(active=True)\n", "path": "benefits/core/models.py"}, {"content": "from django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = []\n\n    operations = [\n        migrations.CreateModel(\n            name=\"EligibilityType\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False, verbose_name=\"ID\")),\n                (\"name\", models.TextField()),\n                (\"label\", models.TextField()),\n                (\"group_id\", models.TextField()),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"PemData\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False)),\n                (\"text\", models.TextField(help_text=\"The data in utf-8 encoded PEM text format.\")),\n                (\"label\", models.TextField(help_text=\"Human description of the PEM data.\")),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"EligibilityVerifier\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False, verbose_name=\"ID\")),\n                (\"name\", models.TextField()),\n                (\"api_url\", models.TextField()),\n                (\"api_auth_header\", models.TextField()),\n                (\"api_auth_key\", models.TextField()),\n                # fmt: off\n                (\"sub_regex\", models.TextField(help_text=\"A regular expression used to validate the 'sub' API field before sending to this verifier\", null=True)),  # noqa: E501\n                (\"name_max_length\", models.PositiveSmallIntegerField(help_text=\"The maximum length accepted for the 'name' API field before sending to this verifier\", null=True)),  # noqa: E501\n                (\"public_key\", models.ForeignKey(help_text=\"The Verifier's public key, used to encrypt requests targeted at this Verifier and to verify signed responses from this verifier.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"jwe_cek_enc\", models.TextField(help_text=\"The JWE-compatible Content Encryption Key (CEK) key-length and mode\")),  # noqa: E501\n                (\"jwe_encryption_alg\", models.TextField(help_text=\"The JWE-compatible encryption algorithm\")),\n                # fmt: on\n                (\"jws_signing_alg\", models.TextField(help_text=\"The JWS-compatible signing algorithm\")),\n                (\"eligibility_types\", models.ManyToManyField(to=\"core.EligibilityType\")),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"PaymentProcessor\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False, verbose_name=\"ID\")),\n                (\"name\", models.TextField()),\n                (\"api_base_url\", models.TextField()),\n                (\"api_access_token_endpoint\", models.TextField()),\n                (\"api_access_token_request_key\", models.TextField()),\n                (\"api_access_token_request_val\", models.TextField()),\n                (\"card_tokenize_url\", models.TextField()),\n                (\"card_tokenize_func\", models.TextField()),\n                (\"card_tokenize_env\", models.TextField()),\n                # fmt: off\n                (\"client_cert\", models.ForeignKey(help_text=\"The certificate used for client certificate authentication to the API.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"client_cert_private_key\", models.ForeignKey(help_text=\"The private key used to sign the certificate.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"client_cert_root_ca\", models.ForeignKey(help_text=\"The root CA bundle used to verify the server.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"customer_endpoint\", models.TextField()),\n                # fmt: on\n                (\"customers_endpoint\", models.TextField()),\n                (\"group_endpoint\", models.TextField()),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"TransitAgency\",\n            fields=[\n                (\"id\", models.AutoField(primary_key=True, serialize=False, verbose_name=\"ID\")),\n                (\"slug\", models.TextField()),\n                (\"short_name\", models.TextField()),\n                (\"long_name\", models.TextField()),\n                (\"agency_id\", models.TextField()),\n                (\"merchant_id\", models.TextField()),\n                (\"info_url\", models.URLField()),\n                (\"phone\", models.TextField()),\n                (\"active\", models.BooleanField(default=False)),\n                # fmt: off\n                (\"private_key\", models.ForeignKey(help_text=\"The Agency's private key, used to sign tokens created on behalf of this Agency.\", on_delete=models.deletion.PROTECT, related_name=\"+\", to=\"core.PemData\")),  # noqa: E501\n                (\"jws_signing_alg\", models.TextField(help_text=\"The JWS-compatible signing algorithm.\")),\n                (\"payment_processor\", models.ForeignKey(on_delete=models.deletion.PROTECT, to=\"core.paymentprocessor\")),\n                (\"eligibility_types\", models.ManyToManyField(to=\"core.EligibilityType\")),\n                (\"eligibility_verifiers\", models.ManyToManyField(to=\"core.eligibilityverifier\")),\n                # fmt: on\n            ],\n        ),\n    ]\n", "path": "benefits/core/migrations/0001_initial.py"}]}