diff --git a/passbook/sources/saml/api.py b/passbook/sources/saml/api.py index d89014d4a..53d741fef 100644 --- a/passbook/sources/saml/api.py +++ b/passbook/sources/saml/api.py @@ -17,7 +17,7 @@ class SAMLSourceSerializer(ModelSerializer): "idp_url", "idp_logout_url", "auto_logout", - "signing_cert", + "signing_kp", ] diff --git a/passbook/sources/saml/forms.py b/passbook/sources/saml/forms.py index ff6ed84ee..cfc3bf2c5 100644 --- a/passbook/sources/saml/forms.py +++ b/passbook/sources/saml/forms.py @@ -5,19 +5,12 @@ from django.contrib.admin.widgets import FilteredSelectMultiple from django.utils.translation import gettext as _ from passbook.admin.forms.source import SOURCE_FORM_FIELDS -from passbook.providers.saml.utils.cert import CertificateBuilder from passbook.sources.saml.models import SAMLSource class SAMLSourceForm(forms.ModelForm): """SAML Provider form""" - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - builder = CertificateBuilder() - builder.build() - self.fields["signing_cert"].initial = builder.certificate - class Meta: model = SAMLSource @@ -26,7 +19,7 @@ class SAMLSourceForm(forms.ModelForm): "idp_url", "idp_logout_url", "auto_logout", - "signing_cert", + "signing_kp", ] widgets = { "name": forms.TextInput(), diff --git a/passbook/sources/saml/migrations/0006_auto_20200303_2201.py b/passbook/sources/saml/migrations/0006_auto_20200303_2201.py new file mode 100644 index 000000000..7a152b2c3 --- /dev/null +++ b/passbook/sources/saml/migrations/0006_auto_20200303_2201.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.3 on 2020-03-03 22:01 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("passbook_crypto", "0001_initial"), + ("passbook_sources_saml", "0005_auto_20200220_1621"), + ] + + operations = [ + migrations.RemoveField(model_name="samlsource", name="signing_cert",), + migrations.AddField( + model_name="samlsource", + name="signing_kp", + field=models.ForeignKey( + default=None, + help_text="Certificate Key Pair of the IdP which Assertions are validated against.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="passbook_crypto.CertificateKeyPair", + ), + ), + ] diff --git a/passbook/sources/saml/models.py b/passbook/sources/saml/models.py index 4f8127bec..f98133ffc 100644 --- a/passbook/sources/saml/models.py +++ b/passbook/sources/saml/models.py @@ -5,6 +5,7 @@ from django.utils.translation import gettext_lazy as _ from passbook.core.models import Source from passbook.core.types import UILoginButton +from passbook.crypto.models import CertificateKeyPair class SAMLSource(Source): @@ -22,7 +23,16 @@ class SAMLSource(Source): default=None, blank=True, null=True, verbose_name=_("IDP Logout URL") ) auto_logout = models.BooleanField(default=False) - signing_cert = models.TextField() + + signing_kp = models.ForeignKey( + CertificateKeyPair, + default=None, + null=True, + help_text=_( + "Certificate Key Pair of the IdP which Assertions are validated against." + ), + on_delete=models.SET_NULL, + ) form = "passbook.sources.saml.forms.SAMLSourceForm" diff --git a/passbook/sources/saml/processors/base.py b/passbook/sources/saml/processors/base.py index 775791adf..5568d9286 100644 --- a/passbook/sources/saml/processors/base.py +++ b/passbook/sources/saml/processors/base.py @@ -46,7 +46,7 @@ class Processor: def _verify_signed(self): """Verify SAML Response's Signature""" verifier = XMLVerifier() - verifier.verify(self._root_xml, x509_cert=self._source.signing_cert) + verifier.verify(self._root_xml, x509_cert=self._source.signing_kp.certificate) def _get_email(self) -> Optional[str]: """ diff --git a/passbook/sources/saml/views.py b/passbook/sources/saml/views.py index 9f6516afa..6dd38db93 100644 --- a/passbook/sources/saml/views.py +++ b/passbook/sources/saml/views.py @@ -101,9 +101,9 @@ class MetadataView(View): """Replies with the XML Metadata SPSSODescriptor.""" source: SAMLSource = get_object_or_404(SAMLSource, slug=source_slug) issuer = get_issuer(request, source) - cert_stripped = strip_pem_header(source.signing_cert.replace("\r", "")).replace( - "\n", "" - ) + cert_stripped = strip_pem_header( + source.signing_kp.certificate_data.replace("\r", "") + ).replace("\n", "") return render_xml( request, "saml/sp/xml/sp_sso_descriptor.xml",