Coverage for benefits/enrollment_switchio/models.py: 100%
48 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-09 20:43 +0000
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-09 20:43 +0000
1from django.core.exceptions import ValidationError
2from django.db import models
4from benefits.core.models import PemData, SecretNameField, Environment
5from benefits.secrets import get_secret_by_name
8class SwitchioConfig(models.Model):
9 """Configuration for connecting to Switchio, an entity that applies transit agency fare rules to rider transactions."""
11 id = models.AutoField(primary_key=True)
12 environment = models.TextField(
13 choices=Environment,
14 help_text="A label to indicate which environment this configuration is for.",
15 )
16 api_key = models.TextField(help_text="The API key used to access the Switchio API.", default="", blank=True)
17 api_secret_name = SecretNameField(
18 help_text="The name of the secret containing the api_secret value used to access the Switchio API.", # noqa: E501
19 default="",
20 blank=True,
21 )
22 client_certificate = models.ForeignKey(
23 PemData,
24 related_name="+",
25 on_delete=models.PROTECT,
26 help_text="The client certificate for accessing the Switchio API.",
27 null=True,
28 blank=True,
29 default=None,
30 )
31 ca_certificate = models.ForeignKey(
32 PemData,
33 related_name="+",
34 on_delete=models.PROTECT,
35 help_text="The CA certificate chain for accessing the Switchio API.",
36 null=True,
37 blank=True,
38 default=None,
39 )
40 private_key = models.ForeignKey(
41 PemData,
42 related_name="+",
43 on_delete=models.PROTECT,
44 help_text="The private key for accessing the Switchio API.",
45 null=True,
46 blank=True,
47 default=None,
48 )
50 @property
51 def api_base_url(self):
52 if self.environment == Environment.QA.value:
53 return get_secret_by_name("switchio-qa-api-base-url")
54 elif self.environment == Environment.PROD.value:
55 return get_secret_by_name("switchio-prod-api-base-url")
56 else:
57 raise ValueError(f"Unexpected value for environment: {self.environment}")
59 @property
60 def api_secret(self):
61 secret_field = self._meta.get_field("api_secret_name")
62 return secret_field.secret_value(self)
64 @property
65 def client_certificate_data(self):
66 """This SwitchioConfig's client certificate as a string."""
67 return self.client_certificate.data
69 @property
70 def ca_certificate_data(self):
71 """This SwitchioConfig's CA certificate as a string."""
72 return self.ca_certificate.data
74 @property
75 def private_key_data(self):
76 """This SwitchioConfig's private key as a string."""
77 return self.private_key.data
79 def clean(self, agency=None):
80 field_errors = {}
82 if agency is not None:
83 used_by_active_agency = agency.active
84 elif self.pk is not None:
85 used_by_active_agency = any((agency.active for agency in self.transitagency_set.all()))
86 else:
87 used_by_active_agency = False
89 if used_by_active_agency:
90 message = "This field is required when this configuration is referenced by an active transit agency."
91 needed = dict(
92 api_key=self.api_key,
93 api_secret_name=self.api_secret_name,
94 client_certificate=self.client_certificate,
95 ca_certificate=self.ca_certificate,
96 private_key=self.private_key,
97 )
98 field_errors.update({k: ValidationError(message) for k, v in needed.items() if not v})
100 if field_errors:
101 raise ValidationError(field_errors)
103 def __str__(self):
104 environment_label = Environment(self.environment).label if self.environment else "unknown"
105 return f"{environment_label}"