Exemple #1
0
class AccessControl(models.Model):
    phase: AccessControlPhase = enumfields.EnumField(AccessControlPhase)

    input_kind: AccessControlInputKind = enumfields.EnumField(
        AccessControlInputKind
    )

    reverses_hostname: bool = models.BooleanField(
        blank=True
    )

    postfix_identifier: str = models.CharField(
        max_length=256,
        validators=[PostfixIdentifierValidator()]
    )

    pattern: str = models.CharField(max_length=256)

    action: AccessAction = models.ForeignKey(
        to='AccessAction',
        on_delete=models.CASCADE,
        related_name='access_controls'
    )

    notes: str = models.CharField(
        max_length=256,
        null=True,
        blank=True,
        help_text='Notes on the account.'
    )

    def __str__(self) -> str:
        return '<%s> %s: %s' % (
            self.postfix_identifier,
            self.pattern,
            self.action.action
        )

    def clean(self):
        self._validate_subject_components_consistency()
        self._validate_pattern()

    def _validate_pattern(self):
        try:
            validate = self.input_kind.pattern_validator()
            validate()(self.pattern)
        except exceptions.ValidationError:
            raise exceptions.ValidationError(
                message='Invalid pattern: %s.' % self.pattern,
                params={'field': 'pattern'}
            )

    def _validate_subject_components_consistency(self):
        # TODO: Implement server-side consistency validation.
        pass

    class Meta:
        verbose_name = 'Access Control'
        verbose_name_plural = 'Access Controls'
Exemple #2
0
class Report(models.Model):
    reporter_name = models.TextField()
    reporter_email = models.EmailField()

    target = models.ForeignKey(Target, related_name='reports', null=True)
    type = enumfields.EnumField(ReportType, max_length=200)
    title = models.TextField()
    details = models.TextField()
    status = enumfields.EnumField(ReportStatus, max_length=200, default=ReportStatus.NEW)

    date_created = models.DateTimeField(default=timezone.now)
    date_updated = models.DateTimeField(default=timezone.now)

    def save(self, *args, **kwargs):
        self.date_updated = timezone.now()
        super().save(*args, **kwargs)

    def __str__(self):
        return self.title
Exemple #3
0
 def get_field(self, **kwargs):
     return enumfields.EnumField(self.enum_class).formfield(**kwargs)
class AccessControlForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['postfix_identifier'].widget.attrs['readonly'] = 'readonly'

    phase: AccessControlPhase = enumfields.EnumField(
        AccessControlPhase).formfield(label='Phase',
                                      initial=AccessControlPhase.CLIENT)

    input_kind: AccessControlInputKind = enumfields.EnumField(
        AccessControlInputKind).formfield(
            label='Input', initial=AccessControlInputKind.HOSTNAME)

    reverses_hostname: bool = forms.BooleanField(label='Reverses Hostname',
                                                 required=False)

    postfix_identifier: str = forms.CharField(
        widget=admin_widgets.AdminTextInputWidget,
        max_length=256,
    )

    pattern: str = forms.CharField(widget=admin_widgets.AdminTextInputWidget,
                                   help_text='''
<h5>Email Address Patterns</h5>
<dl>
    <dt>user@domain</dt>
    <dd>
        <p>Matches the specified mail address.</p>
    </dd>
    <dt>domain.tld</dt>
    <dd>
        <p>Matches domain.tld as the domain part of an email address.</p>
    </dd>
    <dt>user@Matches</dt>
    <dd>
        <p>All mail addresses with the specified user part.</p>
    </dd>
</dl>
<h5>Email Address Extension</h5>
<dl>
    <dd>
        When a mail address local-part contains the optional recipient 
        delimiter (e.g., user+foo@domain), the lookup order becomes: 
        user+foo@domain, user@domain, domain, user+foo@, and user@.
    </dd>
</dl>
<h5>HOST NAME/ADDRESS PATTERNS</h5>
<dl>
    <dt>domain.tld</dt>
    <dd>
        <p>Matches domain.tld.</p>
        <p>
            The pattern domain.tld also matches subdomains, but only when
            the string smtpd_access_maps is listed in the Postfix 
            parent_domain_matches_subdomains configuration setting. 
            Otherwise, specify .domain.tld (note the initial dot) in order 
            to match subdomains.
        </p>
    </dd>
    <dt>net.work.addr.ess</dt>
    <dt>net.work.addr</dt>
    <dt>net.work</dt>
    <dt>net</dt>
    <dd>
        <p>
            Matches the specified IPv4 host address or subnetwork. An IPv4 
            host address is a sequence of four decimal octets separated by
             ".".
        </p>
        <p>
            Subnetworks are matched by repeatedly truncating the last 
            ".octet" from the remote IPv4 host address string until a 
            match is found in the access table, or until further 
            truncation is not possible.
        </p>
        <ul>
            <li>
                NOTE 1: The access map lookup key must be in canonical 
                form: do not specify unnecessary null characters, and do 
                not enclose network address information with "[]" 
                characters.
            </li>
            <li>
                NOTE 2: use the cidr lookup table type to specify 
                network/netmask patterns. See cidr_table(5) for details.
            </li>
        </ul>
    </dd>
    <dt>net:work:addr:ess</dt>
    <dt>net:work:addr</dt>
    <dt>net:work</dt>
    <dt>net</dt>
    <dd>
        <p>
            Matches the specified IPv6 host address or subnetwork. An IPv6
            host address is a sequence of three to eight hexadecimal octet 
            pairs separated by ":".
        </p>

        <p>
            Subnetworks are matched by repeatedly truncating the last 
            ":octetpair" from the remote IPv6 host address string until a
            match is found in the access table, or until further 
            truncation is not possible.
        </p>
        
        <ul>
            <li>
                NOTE 1: the truncation and comparison are done with the 
                string representation of the IPv6 host address. Thus, not 
                all the ":" subnetworks will be tried.
            </li>
            <li>
                NOTE 2: The access map lookup key must be in canonical 
                form: do not specify unnecessary null characters, and do 
                not enclose network address information with "[]" 
                characters.
            </li>
            <li>
                NOTE 3: use the cidr lookup table type to specify 
                network/netmask patterns. See cidr_table(5) for details.
            </li>
        </ul>
        <p>IPv6 support is available in Postfix 2.2 and later.</p>
    </dd>
</dl>
''')

    class Meta:
        model = AccessAction
        exclude = []

    class Media:
        js = (
            '//code.jquery.com/jquery-3.3.1.slim.min.js',
            'postcot/admin/js/access_control_change_form.js',
        )
        css = {
            'all': ('postcot/admin/css/change_form_help_text_postfix.css', ),
        }