<commit_before>'''
Created on Jul 14, 2010

@author: jnaous
'''
from django import forms
from models import GENIAggregate
import logging
import traceback
from django.conf import settings
from sfa.trust.gid import GID
from sfa.trust.certificate import Keypair
from expedient_geni.utils import get_user_key_fname, get_user_cert_fname

logger = logging.getLogger("expedient_geni.forms")

def _clean_x_file_factory(name):
    """Factory to create functions that check file size"""
    def clean_x_file(self):
        logger.debug("Checking file lengths")
        if self.cleaned_data["%s_file" % name].size > \
        settings.GCF_MAX_UPLOADED_PEM_FILE_SIZE:
            raise forms.ValidationError(
                "File exceeds maximum file size of %s bytes."
                % settings.GCF_MAX_UPLOADED_PEM_FILE_SIZE)
        return self.cleaned_data["%s_file" % name]
    return clean_x_file

class UploadCertForm(forms.Form):
    """Form to upload a certificate and its corresponding key."""
    
    key_file = forms.FileField(
        help_text="Select the file that contains the key for the "\
            "certificate to upload.")
    cert_file = forms.FileField(
        help_text="Select the file that contains the "\
            "certificate to upload. The certificate must be signed "\
            "with the uploaded key.")
    
    clean_key_file = _clean_x_file_factory("key")
    clean_cert_file = _clean_x_file_factory("cert")
            
    def clean(self):
        """Check that the cert file is signed by the key file and is trusted."""
        logger.debug("cleaned_data %s" % self.cleaned_data)
        if self.files:
            self.key = Keypair(self.files["key_file"].read())
            self.cert = GID(self.files["cert_file"].read())
            
            try:
                self.cert.verify(self.key)
            except Exception as e:
                logger.error(traceback.format_exc())
                raise forms.ValidationError(
                    "Could not verify that the certificate was "
                    "signed by the uploaded key. The error was: %s" % e)
    
            try:
                self.cert.verify_chain(settings.GCF_X509_TRUSTED_CERT_DIR)
            except Exception as e:
                logger.error(traceback.format_exc())
                raise forms.ValidationError(
                    "Could not verify that the uploaded certificate is "
                    "trusted. This could be because none of the certificate's "
                    "ancestors have been installed as trusted. The error was: "
                    "%s" % e
                )

        return self.cleaned_data
    
    def save(self, user):
        """Write the key and cert into files.
        <commit_msg>fix certificate verification on upload<commit_after>'''
Created on Jul 14, 2010

@author: jnaous
'''
from django import forms
from models import GENIAggregate
import logging
import traceback
from django.conf import settings
from sfa.trust.gid import GID
from sfa.trust.certificate import Keypair
from expedient_geni.utils import get_user_key_fname, get_user_cert_fname,\
    get_trusted_cert_filenames

logger = logging.getLogger("expedient_geni.forms")

def _clean_x_file_factory(name):
    """Factory to create functions that check file size"""
    def clean_x_file(self):
        logger.debug("Checking file lengths")
        if self.cleaned_data["%s_file" % name].size > \
        settings.GCF_MAX_UPLOADED_PEM_FILE_SIZE:
            raise forms.ValidationError(
                "File exceeds maximum file size of %s bytes."
                % settings.GCF_MAX_UPLOADED_PEM_FILE_SIZE)
        return self.cleaned_data["%s_file" % name]
    return clean_x_file

class UploadCertForm(forms.Form):
    """Form to upload a certificate and its corresponding key."""
    
    key_file = forms.FileField(
        help_text="Select the file that contains the key for the "\
            "certificate to upload.")
    cert_file = forms.FileField(
        help_text="Select the file that contains the "\
            "certificate to upload. The certificate must be signed "\
            "with the uploaded key.")
    
    clean_key_file = _clean_x_file_factory("key")
    clean_cert_file = _clean_x_file_factory("cert")
            
    def clean(self):
        """Check that the cert file is signed by the key file and is trusted."""
        logger.debug("cleaned_data %s" % self.cleaned_data)
        if self.files:
            self.key = Keypair(string=self.files["key_file"].read())
            self.cert = GID(string=self.files["cert_file"].read())
            
            cert_pubkey = self.cert.get_pubkey().get_pubkey_string()
            if cert_pubkey != self.key.get_pubkey_string():
                raise forms.ValidationError(
                    "Error: The certificate was not signed "
                    "by the uploaded key. Please use a key "
                    "that matches the certificate.")
    
            try:
                certs = [GID(filename=f) for f in get_trusted_cert_filenames()]
                self.cert.verify_chain(certs)
            except Exception as e:
                logger.error(traceback.format_exc())
                raise forms.ValidationError(
                    "Could not verify that the uploaded certificate is "
                    "trusted. This could be because none of the certificate's "
                    "ancestors have been installed as trusted. The error was: "
                    "%s" % e
                )

        return self.cleaned_data
    
    def save(self, user):
        """Write the key and cert into files.
        
{'fraction_non_alphanumeric': 0.0823717379726611, 'fraction_numerical': 0.002662879460323096, 'mean_word_length': 2.1884550084889645, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2118365', 'n_tokens_mistral': 1601, 'n_tokens_neox': 1543, 'n_words': 456}