diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/ACMECertificateDomain.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/ACMECertificateDomain.inc index 4604efb7..95d7638f 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/ACMECertificateDomain.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/ACMECertificateDomain.inc @@ -305,6 +305,8 @@ class ACMECertificateDomain extends Model { public StringField $zone_username; public StringField $zone_key; public StringField $zilore_key; + public StringField $technitium_server; + public StringField $technitium_token; public StringField $anydnschallengealias; public BooleanField $anydnschallengedomain; @@ -2524,6 +2526,21 @@ class ACMECertificateDomain extends Model { conditions: ['method' => 'dns_zilore'], help_text: 'Zilore API Key', ); + $this->technitium_server = new StringField( + default: '', + allow_empty: true, + internal_name: 'dns_technitiumtechnitium_server', + conditions: ['method' => 'dns_technitium'], + help_text: 'Technitium DNS Server address', + ); + $this->technitium_token = new StringField( + default: '', + allow_empty: true, + sensitive: true, + internal_name: 'dns_technitiumtechnitium_token', + conditions: ['method' => 'dns_technitium'], + help_text: 'Technitium DNS Server API Token', + ); $this->anydnschallengealias = new StringField( default: '', allow_empty: true, diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/CertificateAuthority.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/CertificateAuthority.inc index bfe4645a..0f121969 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/CertificateAuthority.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/CertificateAuthority.inc @@ -8,6 +8,7 @@ use RESTAPI\Fields\BooleanField; use RESTAPI\Fields\IntegerField; use RESTAPI\Fields\StringField; use RESTAPI\Fields\UIDField; +use RESTAPI\Responses\ConflictError; use RESTAPI\Responses\ForbiddenError; use RESTAPI\Responses\ValidationError; use RESTAPI\Validators\RegexValidator; @@ -115,8 +116,8 @@ class CertificateAuthority extends Model { */ public function _delete(): void { # Do not allow this CertificateAuthority to be deleted if it is in use - if (cert_in_use($this->refid->value)) { - throw new ForbiddenError( + if (ca_in_use($this->refid->value)) { + throw new ConflictError( message: 'Certificate authority cannot be deleted because it is in use.', response_id: 'CERTIFICATE_AUTHORITY_CANNOT_BE_DELETED_WHILE_IN_USE', ); diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/CertificateRevocationList.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/CertificateRevocationList.inc index 031bf96a..7f8ca96a 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/CertificateRevocationList.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/CertificateRevocationList.inc @@ -40,7 +40,6 @@ class CertificateRevocationList extends Model { $this->descr = new StringField( required: true, unique: true, - editable: false, validators: [new RegexValidator(pattern: "/[\?\>\<\&\/\\\"\']/", invert: true)], help_text: 'The unique name/description for this CRL.', ); @@ -59,7 +58,6 @@ class CertificateRevocationList extends Model { ); $this->lifetime = new IntegerField( default: 730, - editable: false, minimum: 1, maximum: 8381, conditions: ['method' => 'internal'], @@ -67,7 +65,6 @@ class CertificateRevocationList extends Model { ); $this->serial = new IntegerField( default: 0, - editable: false, conditions: ['method' => 'internal'], help_text: 'The serial number of the CRL.', ); diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsCertificateAuthorityTestCase.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsCertificateAuthorityTestCase.inc index d07f8a77..c0436596 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsCertificateAuthorityTestCase.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsCertificateAuthorityTestCase.inc @@ -3,6 +3,7 @@ namespace RESTAPI\Tests; use RESTAPI\Core\Command; +use RESTAPI\Core\Model; use RESTAPI\Core\TestCase; use RESTAPI\Models\CertificateAuthority; @@ -127,6 +128,25 @@ R02Pul8ulWQ8Kl3Q3pou8As7W1mMzA2DxQ== $ca->delete(); } - # TODO: Need test to ensure CA cannot be deleted while in use + /** + * Checks that we cannot delete a CA that is in use. + */ + public function test_cannot_delete_ca_in_use(): void { + # Create a CA to test with + $ca = new CertificateAuthority(descr: 'test', crt: self::EXAMPLE_CRT, prv: self::EXAMPLE_PRV); + $ca->create(); + + # Mock an OpenVPN server using this CA to be in use + Model::set_config(path: 'openvpn/openvpn-server/0/caref', value: $ca->refid->value); + + # Ensure an error is thrown if we try to delete the CA while it's in use + $this->assert_throws_response( + response_id: 'CERTIFICATE_AUTHORITY_CANNOT_BE_DELETED_WHILE_IN_USE', + code: 409, + callable: function () use ($ca) { + $ca->delete(); + }, + ); + } # TODO: Need test to ensure crt must be CA capable }