Skip to content

Commit 0d35f54

Browse files
committed
chore: define an initial InitConfig model
1 parent 02743a7 commit 0d35f54

3 files changed

Lines changed: 132 additions & 4 deletions

File tree

benefits/enrollment_init/admin.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1-
# from django.contrib import admin
1+
from django.contrib import admin
2+
from django.db import models
3+
from django.forms import TextInput
24

3-
# Register your models here.
5+
from benefits.core.admin.mixins import StaffPermissionMixin
6+
from benefits.enrollment_init import models as benefitsModels
7+
8+
9+
@admin.register(benefitsModels.InitConfig)
10+
class InitConfigAdmin(StaffPermissionMixin, admin.ModelAdmin):
11+
# use a TextInput for inherited fields instead of a Textarea
12+
formfield_overrides = {
13+
models.TextField: {"widget": TextInput(attrs={"size": "80"})},
14+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Generated by Django 5.2.17 on 2026-09-04 18:29
2+
3+
import django.db.models.deletion
4+
from django.db import migrations, models
5+
6+
import benefits.core.models.common
7+
import benefits.secrets
8+
9+
10+
class Migration(migrations.Migration):
11+
12+
initial = True
13+
14+
dependencies = [
15+
("core", "0008_alter_enrollmentflow_system_name"),
16+
]
17+
18+
operations = [
19+
migrations.CreateModel(
20+
name="InitConfig",
21+
fields=[
22+
(
23+
"transitprocessorconfig_ptr",
24+
models.OneToOneField(
25+
auto_created=True,
26+
on_delete=django.db.models.deletion.CASCADE,
27+
parent_link=True,
28+
primary_key=True,
29+
serialize=False,
30+
to="core.transitprocessorconfig",
31+
),
32+
),
33+
(
34+
"tokenization_api_key",
35+
models.CharField(blank=True, default="", help_text="The Collect.js API key used for tokenization."),
36+
),
37+
(
38+
"registration_base_url",
39+
models.URLField(
40+
blank=True, default="", help_text="The absolute base url of the MOBILEvario API instance."
41+
),
42+
),
43+
(
44+
"registration_username",
45+
models.CharField(
46+
blank=True, default="", help_text="The username used to authenticate with MOBILEvario.", max_length=50
47+
),
48+
),
49+
(
50+
"registration_password_secret_name",
51+
benefits.core.models.common.SecretNameField(
52+
blank=True,
53+
default="",
54+
help_text="The name of the secret containing the password used to authenticate with MOBILEvario, "
55+
"typically: [agency]-init-registration-password",
56+
max_length=127,
57+
validators=[benefits.secrets.SecretNameValidator()],
58+
),
59+
),
60+
],
61+
options={
62+
"verbose_name": "INIT Config",
63+
},
64+
bases=("core.transitprocessorconfig",),
65+
),
66+
]

benefits/enrollment_init/models.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,54 @@
1-
# from django.db import models
1+
import logging
22

3-
# Create your models here.
3+
from django.core.exceptions import ValidationError
4+
from django.db import models
5+
6+
from benefits.core.models import SecretNameField, TransitProcessorConfig
7+
8+
logger = logging.getLogger(__name__)
9+
10+
11+
class InitConfig(TransitProcessorConfig):
12+
"""Configuration for connecting to INIT, an entity that applies transit agency fare rules to rider transactions."""
13+
14+
tokenization_api_key = models.CharField(help_text="The Collect.js API key used for tokenization.", default="", blank=True)
15+
16+
registration_base_url = models.URLField(
17+
help_text="The absolute base url of the MOBILEvario API instance.", default="", blank=True
18+
)
19+
20+
registration_username = models.CharField(
21+
help_text="The username used to authenticate with MOBILEvario.",
22+
default="",
23+
blank=True,
24+
max_length=50,
25+
)
26+
27+
registration_password_secret_name = SecretNameField(
28+
help_text="The name of the secret containing the password used to authenticate with MOBILEvario, "
29+
"typically: [agency]-init-registration-password",
30+
default="",
31+
blank=True,
32+
max_length=50,
33+
)
34+
35+
@property
36+
def registration_password(self):
37+
secret_field = self._meta.get_field("registration_password_secret_name")
38+
return secret_field.secret_value(self)
39+
40+
def clean(self):
41+
field_errors = {}
42+
43+
if self.pk and self.transitagency_set and any([agency.active for agency in self.transitagency_set.all()]):
44+
message = "This field is required when this configuration is referenced by an active transit agency."
45+
needed = dict(
46+
tokenization_api_key=self.tokenization_api_key,
47+
)
48+
field_errors.update({k: ValidationError(message) for k, v in needed.items() if not v})
49+
50+
if field_errors:
51+
raise ValidationError(field_errors)
52+
53+
class Meta:
54+
verbose_name = "INIT Config"

0 commit comments

Comments
 (0)