コード例 #1
0
class Migration(migrations.Migration):

    dependencies = [
        ('siteapp', '0055_auto_20220330_1629'),
    ]

    operations = [
        migrations.AlterField(
            model_name='appointment',
            name='party',
            field=auto_prefetch.ForeignKey(
                blank=True,
                help_text='The Party appointed to the Role.',
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                related_name='parties',
                to='siteapp.party'),
        ),
        migrations.AlterField(
            model_name='appointment',
            name='role',
            field=auto_prefetch.ForeignKey(
                blank=True,
                help_text='The Role being appointed.',
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                related_name='roles',
                to='siteapp.role'),
        ),
    ]
コード例 #2
0
ファイル: models.py プロジェクト: Khoding/khoBlog
class BaseFactAbstractModel(auto_prefetch.Model):
    """BaseFactAbstractModel A Base model for Facts"""

    title = models.CharField(max_length=200, help_text="Fact title")
    snippet = models.CharField(max_length=200,
                               blank=True,
                               default="",
                               help_text="Short Fact description")
    description = models.TextField(blank=True,
                                   default="",
                                   help_text="Fact description")
    fact = models.TextField(default="")
    slug = models.SlugField(unique=True,
                            default="",
                            max_length=200,
                            help_text="Fact slug")
    created_date = models.DateTimeField(default=timezone.now,
                                        help_text="Creation date")
    mod_date = models.DateTimeField(auto_now=True,
                                    help_text="Last modification")
    pub_date = models.DateTimeField(blank=True,
                                    null=True,
                                    help_text="Publication date")
    rnd_choice = models.IntegerField(
        default=0,
        help_text="How many times the Fact has been randomly selected")
    link = auto_prefetch.ForeignKey(Links,
                                    on_delete=models.CASCADE,
                                    null=True,
                                    blank=True)
    shown = models.BooleanField(default=True, help_text="Is it shown")
    priority = models.PositiveIntegerField(default=0)

    # Metadata about the fact
    site = auto_prefetch.ForeignKey(Site, default=1, on_delete=models.CASCADE)

    class Meta(auto_prefetch.Model.Meta):
        abstract = True

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        return super().save(*args, **kwargs)

    def save_without_historical_record(self, *args, **kwargs):
        self.skip_history_when_saving = True
        try:
            ret = self.save(*args, **kwargs)
        finally:
            del self.skip_history_when_saving
        return ret

    def rnd_chosen(self):
        self.rnd_choice += 1
        self.save_without_historical_record(update_fields=["rnd_choice"])
コード例 #3
0
class SystemAssessmentResult(auto_prefetch.Model):
    name = models.CharField(max_length=250,
                            help_text="Name of the system assessment result",
                            unique=False,
                            blank=False,
                            null=False)
    description = models.CharField(
        max_length=255,
        help_text="Brief description of the system assessment result",
        unique=False,
        blank=True,
        null=True)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    updated = models.DateTimeField(auto_now=True, db_index=True)
    uuid = models.UUIDField(
        default=uuid.uuid4,
        editable=True,
        help_text=
        "A UUID (a unique identifier) for the system assessment result.")
    system = auto_prefetch.ForeignKey(
        'System',
        related_name='system_assessment_result',
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        help_text="The system associated with the system assessment result")
    deployment = auto_prefetch.ForeignKey(
        Deployment,
        related_name="assessment_results",
        unique=False,
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        help_text="The deployment associated with the assessment result.")
    assessment_results = JSONField(
        blank=True,
        null=True,
        help_text=
        "JSON object representing the system assessment results associated with a deployment."
    )
    history = HistoricalRecords(cascade_delete_history=True)

    def __str__(self):
        return "<SystemAssesmentResult %s id=%d>" % (self.system, self.id)

    def __repr__(self):
        # For debugging.
        return "<SystemAssesmentResult %s id=%d>" % (self.system, self.id)
コード例 #4
0
ファイル: models.py プロジェクト: kerryrm/govready-q
class Deployment(auto_prefetch.Model):
    name = models.CharField(max_length=250, help_text="Name of the deployment", unique=False, blank=False, null=False)
    description = models.CharField(max_length=255, help_text="Brief description of the deployment", unique=False, blank=False, null=False)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    updated = models.DateTimeField(auto_now=True, db_index=True)
    uuid = models.UUIDField(default=uuid.uuid4, editable=True, help_text="A UUID (a unique identifier) for the deployment.")
    system = auto_prefetch.ForeignKey('System', related_name='deployments', on_delete=models.CASCADE, blank=True, null=True, help_text="The system associated with the deployment")
    inventory_items = JSONField(blank=True, null=True,
        help_text="JSON object representing the inventory items in a deployment.")
    history = HistoricalRecords(cascade_delete_history=True)

    # Notes
    #
    # Retrieve System Deployment
    #    from controls.models import *
    #    s = System.objects.get(pk=11)
    #    s.deployments.all()
    #    # returns <QuerySet ['ac-2 id=1', 'ac-3 id=2', 'au-2 id=3']>
    #

    def __str__(self):
        return "'%s id=%d'" % (self.name, self.id)

    def __repr__(self):
        # For debugging.
        return "'%s id=%d'" % (self.name, self.id)

    def get_absolute_url(self):
        return "/systems/%d/deployments" % (self.system.id)
コード例 #5
0
class Tag(MPTTModel, auto_prefetch.Model):

    text = models.CharField(max_length=100)
    parent = auto_prefetch.ForeignKey('self',
                                      on_delete=models.CASCADE,
                                      null=True,
                                      blank=True,
                                      related_name='children')

    def __str__(self):
        return self.text

    def all_siblings_leaf(self, all_tags):
        """Return true if all siblings, including self, are leaf nodes.
        """
        # siblings = self.get_siblings(include_self=True)
        if self.parent is None:
            siblings = [t for t in all_tags if t.parent is None]
        else:
            siblings = [t for t in all_tags if t.parent == self.parent]

        return all([s.is_leaf_node() for s in siblings])

    class MPTTMeta:
        order_insertion_by = ['text']

    class MyManager(TreeManager, auto_prefetch.Manager):
        pass

    objects = MyManager()
コード例 #6
0
class Migration(migrations.Migration):

    dependencies = [
        ('controls', '0061_fix_800_171_ids'),
    ]

    operations = [
        migrations.CreateModel(
            name='StatementRemote',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('remote_type', models.CharField(blank=True, choices=[('ORIGIN', 'origin')], help_text='Remote type.', max_length=80, null=True)),
                ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, help_text='A UUID (a unique identifier) for this Statement.')),
                ('created', models.DateTimeField(auto_now_add=True, db_index=True)),
                ('updated', models.DateTimeField(auto_now=True, db_index=True)),
                ('import_record', auto_prefetch.ForeignKey(blank=True, help_text='The Import Record which created this record.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='import_record_statement_remotes', to='controls.importrecord')),
                ('remote_statement', models.ForeignKey(blank=True, help_text='Remote or parent Statement.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='descendents', to='controls.statement')),
                ('statement', models.ForeignKey(blank=True, help_text='Descendent or cloned Statement.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='remotes', to='controls.statement')),
            ],
            options={
                'abstract': False,
                'base_manager_name': 'prefetch_manager',
            },
            managers=[
                ('objects', django.db.models.manager.Manager()),
                ('prefetch_manager', django.db.models.manager.Manager()),
            ],
        ),
    ]
コード例 #7
0
ファイル: models.py プロジェクト: GovReady/govready-q
class Endpoint(auto_prefetch.Model, BaseModel):
    integration = auto_prefetch.ForeignKey(Integration,
                                           related_name="endpoints",
                                           on_delete=models.CASCADE,
                                           help_text="Endpoint's Integration")
    endpoint_path = models.CharField(max_length=250,
                                     help_text="Path to the Endpoint",
                                     unique=False,
                                     blank=True,
                                     null=True)
    description = models.TextField(
        default="",
        help_text="Brief description of the endpoint",
        unique=False,
        blank=True,
        null=True)
    element_type = models.CharField(max_length=150,
                                    help_text="Component type",
                                    unique=False,
                                    blank=True,
                                    null=True)
    data = JSONField(blank=True,
                     null=True,
                     default=dict,
                     help_text="JSON object representing the API results.")
    history = HistoricalRecords(cascade_delete_history=True)

    def __str__(self):
        return f"'{self.integration.name} {self.endpoint_path} id={self.id}'"

    def __repr__(self):
        return f"'{self.integration.name}{self.endpoint_path} id={self.id}'"
コード例 #8
0
ファイル: 0001_initial.py プロジェクト: ehmatthes/tags_test
class Migration(migrations.Migration):

    initial = True

    dependencies = []

    operations = [
        migrations.CreateModel(
            name='Tag',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('text', models.CharField(max_length=100)),
                ('lft', models.PositiveIntegerField(editable=False)),
                ('rght', models.PositiveIntegerField(editable=False)),
                ('tree_id',
                 models.PositiveIntegerField(db_index=True, editable=False)),
                ('level', models.PositiveIntegerField(editable=False)),
                ('parent',
                 auto_prefetch.ForeignKey(
                     blank=True,
                     null=True,
                     on_delete=django.db.models.deletion.CASCADE,
                     related_name='children',
                     to='tags.Tag')),
            ],
            options={
                'abstract': False,
            },
        ),
    ]
コード例 #9
0
class Migration(migrations.Migration):

    dependencies = [
        ('pricetype', '0002_auto_20210313_1042'),
        ('listings', '0012_auto_20210322_0800'),
    ]

    operations = [
        migrations.AlterModelManagers(
            name='listing',
            managers=[
                ('objects', django.db.models.manager.Manager()),
                ('prefetch_manager', django.db.models.manager.Manager()),
            ],
        ),
        migrations.AlterField(
            model_name='listing',
            name='pricetext',
            field=models.CharField(blank=True, max_length=100, null=True),
        ),
        migrations.AlterField(
            model_name='listing',
            name='pricetype',
            field=auto_prefetch.ForeignKey(
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                to='pricetype.pricetype'),
        ),
    ]
コード例 #10
0
class CommonControl(auto_prefetch.Model):
    name = models.CharField(max_length=150,
                            help_text="Name of the CommonControl",
                            unique=False,
                            blank=True,
                            null=True)
    description = models.CharField(
        max_length=255,
        help_text="Brief description of the CommonControlProvider",
        unique=False)
    oscal_ctl_id = models.CharField(
        max_length=20,
        help_text="OSCAL formatted Control ID (e.g., au-2.3)",
        blank=True,
        null=True)
    legacy_imp_smt = models.TextField(
        help_text="Legacy large implementation statement",
        unique=False,
        blank=True,
        null=True,
    )
    common_control_provider = auto_prefetch.ForeignKey(
        CommonControlProvider, on_delete=models.CASCADE)

    def __str__(self):
        return self.name
コード例 #11
0
class MenuFooterLink(auto_prefetch.Model):
    VISIBILITY_CHOICES = [
        ("D", "default"),
        ("NP", "needs_permission"),
        ("NS", "needs_staff"),
        ("NA", "needs_admin"),
    ]

    title = models.CharField(max_length=200, blank=True)
    rel_url = models.CharField(max_length=200, blank=True)
    url = models.URLField(blank=True)
    visibility = models.CharField(
        max_length=25,
        verbose_name="Visibility",
        choices=VISIBILITY_CHOICES,
        default="D",
    )
    links = auto_prefetch.ForeignKey("settings_app.MenuFooter",
                                     on_delete=models.CASCADE,
                                     related_name="menu_footer_links")
    is_target_blank = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = "Menu Footer Links"

    def __str__(self):
        return self.title

    def get_rel_url(self):
        return "/" + self.rel_url
コード例 #12
0
ファイル: models.py プロジェクト: kerryrm/govready-q
class ElementCommonControl(auto_prefetch.Model):
    element = auto_prefetch.ForeignKey(Element, related_name="common_controls", on_delete=models.CASCADE, help_text="The Element (e.g., System, Component, Host) to which common controls are associated.")
    common_control = auto_prefetch.ForeignKey(CommonControl, related_name="element_common_control", on_delete=models.CASCADE, help_text="The Common Control for this association.")
    oscal_ctl_id = models.CharField(max_length=20, help_text="OSCAL formatted Control ID (e.g., au-2.3)", blank=True, null=True)
    oscal_catalog_key = models.CharField(max_length=100, help_text="Catalog key from which catalog file can be derived (e.g., 'NIST_SP-800-53_rev4')", blank=True, null=True)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    updated = models.DateTimeField(auto_now=True, db_index=True)

    class Meta:
        unique_together = [('element', 'common_control', 'oscal_ctl_id', 'oscal_catalog_key')]

    def __str__(self):
        return f"'{self.element} {self.common_control} {self.oscal_ctl_id} id={self.id}'"

    def __repr__(self):
        # For debugging.
        return f"'{self.element} {self.common_control} {self.oscal_ctl_id} id={self.id}'"
コード例 #13
0
ファイル: models.py プロジェクト: Khoding/khoBlog
class Choice(auto_prefetch.Model):
    question = auto_prefetch.ForeignKey(Question,
                                        on_delete=models.CASCADE,
                                        related_name="related_question")
    title = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.title
コード例 #14
0
class Migration(migrations.Migration):

    dependencies = [
        ('siteapp', '0066_alter_project_tags'),
        ('controls', '0074_auto_20220614_1436'),
    ]

    operations = [
        migrations.CreateModel(
            name='SystemEvent',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created',
                 models.DateTimeField(auto_now_add=True, db_index=True)),
                ('updated',
                 models.DateTimeField(auto_now=True, db_index=True,
                                      null=True)),
                ('event_type',
                 models.CharField(help_text='Event type', max_length=12)),
                ('description',
                 models.CharField(help_text='Brief description of the event',
                                  max_length=255)),
                ('info',
                 models.JSONField(
                     blank=True,
                     default=dict,
                     help_text='JSON object detailed event information')),
                ('system',
                 auto_prefetch.ForeignKey(
                     blank=True,
                     help_text='Events related to the system',
                     null=True,
                     on_delete=django.db.models.deletion.CASCADE,
                     related_name='events',
                     to='controls.system')),
                ('tags',
                 models.ManyToManyField(blank=True,
                                        related_name='systemevent',
                                        to='siteapp.Tag')),
            ],
            options={
                'abstract': False,
                'base_manager_name': 'prefetch_manager',
            },
            managers=[
                ('objects', django.db.models.manager.Manager()),
                ('prefetch_manager', django.db.models.manager.Manager()),
            ],
        ),
    ]
コード例 #15
0
class Migration(migrations.Migration):

    dependencies = [
        ('controls', '0070_auto_20220418_1140'),
        ('siteapp', '0058_request'),
    ]

    operations = [
        migrations.AlterField(
            model_name='request',
            name='requested_element',
            field=auto_prefetch.ForeignKey(
                blank=True,
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                related_name='request',
                to='controls.element'),
        ),
        migrations.AlterField(
            model_name='request',
            name='system',
            field=auto_prefetch.ForeignKey(
                blank=True,
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                related_name='request',
                to='controls.system'),
        ),
        migrations.AlterField(
            model_name='request',
            name='user',
            field=auto_prefetch.ForeignKey(
                blank=True,
                help_text='User creating the request.',
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                related_name='request',
                to=settings.AUTH_USER_MODEL),
        ),
    ]
コード例 #16
0
class BaseLinkAbstractModel(auto_prefetch.Model):
    """
    An abstract base class that any custom link models probably should
    subclass.
    """

    # Content-object field
    content_type = auto_prefetch.ForeignKey(
        ContentType,
        verbose_name=_("content type"),
        related_name="content_type_set_for_%(class)s",
        on_delete=models.CASCADE,
        blank=True,
        null=True,
    )
    object_pk = models.CharField(_("object ID"),
                                 db_index=True,
                                 max_length=64,
                                 blank=True,
                                 null=True)
    content_object = GenericForeignKey(ct_field="content_type",
                                       fk_field="object_pk")

    index = models.BooleanField(default=False)

    # Metadata about the link
    site = auto_prefetch.ForeignKey(Site, on_delete=models.CASCADE)

    class Meta(auto_prefetch.Model.Meta):
        """Meta Class for BaseLinkAbstractModel Model"""

        abstract = True

    def get_content_object_url(self):
        """Get a URL suitable for redirecting to the content object."""
        return reverse("links:link-url-redirect",
                       args=(self.content_type, self.object_pk))
コード例 #17
0
class PostCatsLink(auto_prefetch.Model):
    """PostCatsLink Through Table Model

    A through table Model linking Post and Category

    Args:
        auto_prefetch ([type]): [description]

    Returns:
        PostCatsLink: postcatslink_set
    """

    post = auto_prefetch.ForeignKey("blog.Post", on_delete=models.CASCADE)
    category = auto_prefetch.ForeignKey("blog.Category",
                                        on_delete=models.CASCADE)
    featured_cat = models.BooleanField(default=False)

    class Meta:
        """Meta class for PostCatsLink Through Table"""

        verbose_name_plural = "Post to Category Link"

    def __str__(self):
        return "%s - %s" % (self.post.title, self.category.title)
コード例 #18
0
class Migration(migrations.Migration):

    dependencies = [
        ('controls', '0053_auto_20210701_1133'),
        ('siteapp', '0049_user_default_portfolio'),
    ]

    operations = [
        migrations.AddField(
            model_name='project',
            name='import_record',
            field=auto_prefetch.ForeignKey(
                blank=True,
                help_text='The Import Record which created this Project.',
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                related_name='import_record_projects',
                to='controls.importrecord'),
        ),
    ]
コード例 #19
0
ファイル: models.py プロジェクト: NicoNieuwenhuis/omnimarket
class Listing(auto_prefetch.Model):
    # pricetype choises
    pricetype = auto_prefetch.ForeignKey(Pricetype, null=True, on_delete=models.CASCADE)
    pricetext = models.CharField(max_length=100, blank=True, null=True )
    buybuttontxt = models.TextField(blank=True, null=True)
    hasprice = models.BooleanField(blank=True, default=False,  )
    payment = models.BooleanField(blank=True, default=False,  )
    bid = models.BooleanField(blank=True, default=False,  )
    bidoptional = models.BooleanField(blank=True, default=False,  )
    # Listing description
    name = models.CharField(max_length=100, validators=[alphanumeric])
    price = models.DecimalField(max_digits=6, decimal_places=2, null=True, default=0.00, blank=True)
    firstimage = models.ImageField(blank=True,)
    thumbnail = ImageSpecField(source='firstimage', processors={ResizeToFit(262,222)}, format='JPEG', options={'quality':80})
    secondimage = models.ImageField(blank=True,)
    secondthumbnail = ImageSpecField(source='secondimage', processors={ResizeToFit(262,222)}, format='JPEG', options={'quality':80})
    description = models.TextField(blank=True, null=True)
    # Other data
    category = TreeForeignKey('categorys.Category', related_name='category', on_delete=models.CASCADE)
    # Logistic
    pickup = models.BooleanField(blank=True, default=False,  )
    delivery = models.BooleanField(blank=True, default=False,  )
    deliverycost = models.DecimalField(max_digits=6, decimal_places=2, null=True, default=0.00, blank=True)
    # Other data
    author = UserForeignKey(auto_user_add=True, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    slug = AutoSlugField(populate_from='name', validators=[alphanumeric])

    class Meta:
        ordering = ('-created_at',)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        url = reverse('listing', kwargs={'pk': self.pk, 'slug': self.get_slug()})
        return url

    def make_thumbnail(source, width, height, generator_id=None):
        if not os.path.exist(source):
            return None
コード例 #20
0
class Project(BasePortfolioAbstractModel):
    """Model for Project"""

    featured = models.BooleanField(default=False)
    history = HistoricalRecords()
    website = auto_prefetch.ForeignKey(
        "portfolio.Website",
        on_delete=models.CASCADE,
        related_name="websites",
        null=True,
        blank=True,
    )
    repository = auto_prefetch.ForeignKey(
        "portfolio.Repository",
        on_delete=models.DO_NOTHING,
        related_name="repositories",
        null=True,
        blank=True,
    )
    technology = auto_prefetch.ForeignKey(
        "portfolio.Technology",
        on_delete=models.DO_NOTHING,
        related_name="technologies",
        null=True,
        blank=True,
    )

    class Meta(BasePortfolioAbstractModel.Meta):
        """Meta class for Project Model Class"""

        ordering = ["pk"]

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        return super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("portfolio:project_detail", kwargs={"slug": self.slug})

    def get_absolute_update_url(self):
        return reverse("portfolio:project_edit", kwargs={"slug": self.slug})

    def get_absolute_delete_url(self):
        return reverse("portfolio:project_delete", kwargs={"slug": self.slug})

    def get_absolute_admin_update_url(self):
        return reverse("admin:portfolio_project_change",
                       kwargs={"object_id": self.pk})

    @property
    def get_sub_projects(self):
        sub_projects = self.sub_project.filter(is_removed=False)
        return sub_projects

    def remove(self):
        self.is_removed = True
        self.save()

    def get_index_view_url(self):
        content_type = ContentType.objects.get_for_model(self.__class__)
        return reverse("%s:%s_list" %
                       (content_type.app_label, content_type.model))
コード例 #21
0
class MixedField(models.Model):
    friend = auto_prefetch.ForeignKey(Friend, null=True, on_delete=models.CASCADE)
    associates = models.ManyToManyField(Associate)
コード例 #22
0
class Prefetch2(auto_prefetch.Model):
    other = auto_prefetch.ForeignKey(Prefetch, null=True, on_delete=models.CASCADE)
コード例 #23
0
class Category(RulesModelMixin, auto_prefetch.Model, metaclass=RulesModelBase):
    """Category model

    A model for Category

    Args:
        RulesModelMixin ([type]): [description]
        auto_prefetch ([type]): [description]
        metaclass ([type], optional): [description]. Defaults to RulesModelBase.

    Returns:
        Category: A model for Category
    """

    parent = auto_prefetch.ForeignKey(
        "self",
        on_delete=models.CASCADE,
        related_name="category_children",
        null=True,
        blank=True,
    )
    title = models.CharField(max_length=200, help_text="Category title")
    suffix = models.CharField(max_length=200,
                              help_text="Category suffix",
                              blank=True,
                              default="")
    description = models.TextField(blank=True,
                                   help_text="Category description")
    slug = models.SlugField(unique=True,
                            default="",
                            max_length=200,
                            help_text="Category slug")
    created_date = models.DateTimeField(default=timezone.now,
                                        help_text="Creation date")
    mod_date = models.DateTimeField(auto_now=True,
                                    help_text="Last modification")
    withdrawn = models.BooleanField(default=False,
                                    help_text="Is Category withdrawn")
    is_removed = models.BooleanField("is removed",
                                     default=False,
                                     db_index=True,
                                     help_text=("Soft delete"))
    needs_reviewing = models.BooleanField(default=False,
                                          help_text=("Needs reviewing"))
    history = HistoricalRecords()

    objects: CategoryManager = CategoryManager()

    class Meta:
        """Meta class for Category Model"""

        ordering = ["pk"]
        verbose_name_plural = "Categories"
        rules_permissions = {
            "add": rules.is_superuser,
            "update": rules.is_superuser,
        }

    def __str__(self):
        return self.full_title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.full_title)
        return super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("blog:post_category_list", kwargs={"slug": self.slug})

    def get_absolute_update_url(self):
        return reverse("blog:category_edit", kwargs={"slug": self.slug})

    def get_absolute_needs_review_url(self):
        return reverse("blog:category_needs_review",
                       kwargs={"slug": self.slug})

    def get_absolute_delete_url(self):
        return reverse("blog:category_remove", kwargs={"slug": self.slug})

    def get_absolute_admin_update_url(self):
        return reverse("admin:blog_category_change",
                       kwargs={"object_id": self.pk})

    def needs_review(self):
        self.needs_reviewing = True
        self.save()

    def remove(self):
        self.is_removed = True
        self.save()

    @property
    def get_post_count_in_category(self):
        return self.postcatslink_set.filter(
            post__pub_date__lte=timezone.now(),
            post__withdrawn=False,
            post__is_removed=False,
        ).count()

    @property
    def get_superuser_post_count_in_category(self):
        return self.postcatslink_set.filter(post__is_removed=False).count()

    @property
    def get_superuser_percent_of_posts(self) -> str:
        percentage = self.get_superuser_post_count_in_category / Post.objects.filter(
            is_removed=False).count() * 100
        return f"{round(percentage, 2)}%"

    @property
    def get_percent_of_posts(self) -> str:
        percentage = (self.get_post_count_in_category / Post.objects.filter(
            pub_date__lte=timezone.now(), withdrawn=False,
            is_removed=False).count() * 100)
        return f"{round(percentage, 2)}%"

    @property
    def full_title(self) -> str:
        fulltitle = ""
        if self.suffix:
            fulltitle = self.title + " " + self.suffix
        elif not self.suffix and not self.parent:
            fulltitle = self.title
        elif not self.suffix and self.parent and self.parent.suffix:
            fulltitle = self.title + " " + self.parent.suffix
        else:
            fulltitle = self.title
        return fulltitle

    def get_index_view_url(self):
        content_type = ContentType.objects.get_for_model(self.__class__)
        return reverse("%s:%s_list" %
                       (content_type.app_label, content_type.model))
コード例 #24
0
class Statement(auto_prefetch.Model):
    sid = models.CharField(
        max_length=100,
        help_text="Statement identifier such as OSCAL formatted Control ID",
        unique=False,
        blank=True,
        null=True)
    sid_class = models.CharField(
        max_length=200,
        help_text=
        "Statement identifier 'class' such as 'NIST_SP-800-53_rev4' or other OSCAL catalog name Control ID.",
        unique=False,
        blank=True,
        null=True)
    pid = models.CharField(
        max_length=20,
        help_text=
        "Statement part identifier such as 'h' or 'h.1' or other part key",
        unique=False,
        blank=True,
        null=True)
    body = models.TextField(help_text="The statement itself",
                            unique=False,
                            blank=True,
                            null=True)
    statement_type = models.CharField(max_length=150,
                                      help_text="Statement type.",
                                      unique=False,
                                      blank=True,
                                      null=True)
    remarks = models.TextField(help_text="Remarks about the statement.",
                               unique=False,
                               blank=True,
                               null=True)
    status = models.CharField(max_length=100,
                              help_text="The status of the statement.",
                              unique=False,
                              blank=True,
                              null=True)
    version = models.CharField(max_length=20,
                               help_text="Optional version number.",
                               unique=False,
                               blank=True,
                               null=True)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    updated = models.DateTimeField(auto_now=True, db_index=True)

    parent = auto_prefetch.ForeignKey('self',
                                      help_text="Parent statement",
                                      related_name="children",
                                      on_delete=models.SET_NULL,
                                      blank=True,
                                      null=True)
    prototype = auto_prefetch.ForeignKey('self',
                                         help_text="Prototype statement",
                                         related_name="instances",
                                         on_delete=models.SET_NULL,
                                         blank=True,
                                         null=True)
    producer_element = auto_prefetch.ForeignKey(
        'Element',
        related_name='statements_produced',
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        help_text="The element producing this statement.")
    consumer_element = auto_prefetch.ForeignKey(
        'Element',
        related_name='statements_consumed',
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        help_text="The element the statement is about.")
    mentioned_elements = models.ManyToManyField(
        'Element',
        related_name='statements_mentioning',
        blank=True,
        help_text=
        "All elements mentioned in a statement; elements with a first degree relationship to the statement."
    )
    uuid = models.UUIDField(
        default=uuid.uuid4,
        editable=False,
        help_text="A UUID (a unique identifier) for this Statement.")
    import_record = auto_prefetch.ForeignKey(
        ImportRecord,
        related_name="import_record_statements",
        on_delete=models.CASCADE,
        unique=False,
        blank=True,
        null=True,
        help_text="The Import Record which created this Statement.")
    history = HistoricalRecords(cascade_delete_history=True)

    class Meta:
        indexes = [
            models.Index(fields=['producer_element'],
                         name='producer_element_idx'),
        ]
        permissions = [
            ('can_grant_smt_owner_permission',
             'Grant a user statement owner permission'),
        ]
        ordering = ['producer_element__name', 'sid']

    def __str__(self):
        return "'%s %s %s %s %s'" % (self.statement_type, self.sid, self.pid,
                                     self.sid_class, self.id)

    def __repr__(self):
        # For debugging.
        return "'%s %s %s %s %s'" % (self.statement_type, self.sid, self.pid,
                                     self.sid_class, self.id)

    @cached_property
    def producer_element_name(self):
        return self.producer_element.name

    @property
    def catalog_control(self):
        """Return the control content from the catalog"""
        # Get instance of the control catalog
        catalog = Catalog.GetInstance(catalog_key=self.sid_class)
        # Look up control by ID
        return catalog.get_control_by_id(self.sid)

    @property
    def catalog_control_as_dict(self):
        """Return the control content from the catalog"""
        # Get instance of the control catalog
        catalog = Catalog.GetInstance(catalog_key=self.sid_class)
        catalog_control_dict = catalog.get_flattened_controls_all_as_dict()
        # Look up control by ID
        return catalog_control_dict[self.sid]

    def create_prototype(self):
        """Creates a prototype statement from an existing statement and prototype object"""

        if self.prototype is not None:
            # Prototype already exists for statement
            return self.prototype
            # check if prototype content is the same, report error if not, or overwrite if permission approved
        prototype = deepcopy(self)
        prototype.statement_type = "control_implementation_prototype"
        prototype.consumer_element_id = None
        prototype.id = None
        prototype.save()
        # Set prototype attribute on the instances to newly created prototype
        self.prototype = prototype
        self.save()
        return self.prototype

    def create_instance_from_prototype(self, consumer_element_id):
        """Creates a control_implementation statement instance for a system's root_element from an existing control implementation prototype statement"""

        # TODO: Check statement is a prototype

        # System already has instance of the control_implementation statement
        # TODO: write check for this logic
        # Get all statements for consumer element so we can identify
        smts_existing = Statement.objects.filter(
            consumer_element__id=consumer_element_id,
            statement_type="control_implementation").select_related(
                'prototype')

        # Get prototype ids for all consumer element statements
        smts_existing_prototype_ids = [
            smt.prototype.id for smt in smts_existing
        ]
        if self.id is smts_existing_prototype_ids:
            return self.prototype

        #     # TODO:
        #     # check if prototype content is the same, report error if not, or overwrite if permission approved

        instance = deepcopy(self)
        instance.statement_type = "control_implementation"
        instance.consumer_element_id = consumer_element_id
        instance.id = None
        # Set prototype attribute to newly created instance
        instance.prototype = self
        instance.save()
        return instance

    @property
    def prototype_synched(self):
        """Returns one of STATEMENT_SYNCHED, STATEMENT_NOT_SYNCHED, STATEMENT_ORPHANED for control_implementations"""

        if self.statement_type == "control_implementation":
            if self.prototype:
                if self.body == self.prototype.body:
                    return STATEMENT_SYNCHED
                else:
                    return STATEMENT_NOT_SYNCHED
            else:
                return STATEMENT_ORPHANED
        else:
            return STATEMENT_NOT_SYNCHED

    @property
    def diff_prototype_main(self):
        """Generate a diff of statement of type `control_implementation` and its prototype"""

        if self.statement_type != 'control_implementation':
            # TODO: Should we return None or raise error because statement is not of type control_implementation?
            return None
        if self.prototype is None:
            # TODO: Should we return None or raise error because statement does not have a prototype?
            return None
        dmp = dmp_module.diff_match_patch()
        diff = dmp.diff_main(self.prototype.body, self.body)
        return diff

    @property
    def diff_prototype_prettyHtml(self):
        """Generate a diff of statement of type `control_implementation` and its prototype"""

        if self.statement_type != 'control_implementation':
            # TODO: Should we return None or raise error because statement is not of type control_implementation?
            return None
        if self.prototype is None:
            # TODO: Should we return None or raise error because statement does not have a prototype?
            return None
        dmp = dmp_module.diff_match_patch()
        diff = dmp.diff_main(self.prototype.body, self.body)
        return dmp.diff_prettyHtml(diff)

    # TODO:c
    #   - On Save be sure to replace any '\r\n' with '\n' added by round-tripping with excel

    @staticmethod
    def _statement_id_from_control(control_id, part_id):
        if part_id:
            return f"{control_id}_smt.{part_id}"
        else:
            return f"{control_id}_smt"

    @property
    def oscal_statement_id(self):
        return Statement._statement_id_from_control(self.sid, self.pid)

    @staticmethod
    def _statement_id_from_control(control_id, part_id):
        if part_id:
            return f"{control_id}_smt.{part_id}"
        else:
            return f"{control_id}_smt"

    @property
    def oscal_statement_id(self):
        return Statement._statement_id_from_control(self.sid, self.pid)
コード例 #25
0
class System(auto_prefetch.Model):
    root_element = auto_prefetch.ForeignKey(
        Element,
        related_name="system",
        on_delete=models.CASCADE,
        help_text=
        "The Element that is this System. Element must be type [Application, General Support System]"
    )
    fisma_id = models.CharField(max_length=40,
                                help_text="The FISMA Id of the system",
                                unique=False,
                                blank=True,
                                null=True)

    # Notes
    # Retrieve system implementation statements
    #   system = System.objects.get(pk=2)
    #   system.root_element.statements_consumed.filter(statement_type="control_implementation")
    #
    # Retrieve system common controls statements
    #   system = System.objects.get(pk=2)
    #   system.root_element.common_controls.all()[0].common_control.legacy_imp_smt
    #   system.root_element.common_controls.all()[0].common_control.body
    #

    def __str__(self):
        return "'System %s id=%d'" % (self.root_element.name, self.id)

    def __repr__(self):
        # For debugging.
        return "'System %s id=%d'" % (self.root_element.name, self.id)

    # @property
    # def statements_consumed(self):
    #     smts = self.root_element.statements_consumed.all()
    #     return smts

    def assign_owner_permissions(self, user):
        try:
            permissions = get_perms_for_model(System)
            for perm in permissions:
                assign_perm(perm.codename, user, self)
            return True
        except:
            return False

    def assign_edit_permissions(self, user):
        try:
            permissions = ['view_system', 'change_system', 'add_system']
            for perm in permissions:
                assign_perm(perm, user, self)
            return True
        except:
            return False

    @property
    def smts_common_controls_as_dict(self):
        common_controls = self.root_element.common_controls.all()
        smts_as_dict = {}
        for cc in common_controls:
            if cc.common_control.oscal_ctl_id in smts_as_dict:
                smts_as_dict[cc.common_control.oscal_ctl_id].append(cc)
            else:
                smts_as_dict[cc.common_control.oscal_ctl_id] = [cc]
        return smts_as_dict

    @property
    def smts_control_implementation_as_dict(self):
        smts = self.root_element.statements_consumed.filter(
            statement_type="control_implementation").order_by('pid')
        smts_as_dict = {}
        for smt in smts:
            if smt.sid in smts_as_dict:
                smts_as_dict[smt.sid]['control_impl_smts'].append(smt)
            else:
                smts_as_dict[smt.sid] = {
                    "control_impl_smts": [smt],
                    "common_controls": [],
                    "combined_smt": ""
                }
        return smts_as_dict

    @cached_property
    def control_implementation_as_dict(self):
        pid_current = None

        # Fetch all selected controls
        elm = self.root_element
        selected_controls = elm.controls.all().values("oscal_ctl_id", "uuid")
        # Get the smts_control_implementations ordered by part, e.g. pid
        smts = elm.statements_consumed.filter(
            statement_type="control_implementation").order_by('pid')

        smts_as_dict = {}

        # Retrieve all of the existing statements
        for smt in smts:
            if smt.sid in smts_as_dict:
                smts_as_dict[smt.sid]['control_impl_smts'].append(smt)
            else:

                try:
                    elementcontrol = self.root_element.controls.get(
                        oscal_ctl_id=smt.sid, oscal_catalog_key=smt.sid_class)
                    smts_as_dict[smt.sid] = {
                        "control_impl_smts": [smt],
                        "common_controls": [],
                        "combined_smt": "",
                        "elementcontrol_uuid": elementcontrol.uuid,
                        "combined_smt_uuid": uuid.uuid4()
                    }
                except ElementControl.DoesNotExist:
                    # Handle case where Element control does not exist
                    elementcontrol = None
                    smts_as_dict[smt.sid] = {
                        "control_impl_smts": [smt],
                        "common_controls": [],
                        "combined_smt": "",
                        "elementcontrol_uuid": None,
                        "combined_smt_uuid": uuid.uuid4()
                    }

            # Build combined statement

            # Define status options
            impl_statuses = [
                "Not implemented", "Planned", "Partially implemented",
                "Implemented", "Unknown"
            ]
            status_str = ""
            for status in impl_statuses:
                if (smt.status is not None) and (smt.status.lower()
                                                 == status.lower()):
                    status_str += f'[x] {status} '
                else:
                    status_str += f'<span style="color: #888;">[ ] {status}</span> '
            # Conditionally add statement part in the beginning of a block of statements related to a part
            if smt.pid != "" and smt.pid != pid_current:
                smts_as_dict[smt.sid]['combined_smt'] += f"{smt.pid}.\n"
                pid_current = smt.pid
            # DEBUG
            # TODO
            # Poor performance, at least in some instances, appears to being caused by `smt.producer_element.name`
            # parameter in the below statement.
            if smt.producer_element:
                smts_as_dict[smt.sid][
                    'combined_smt'] += f"<i>{smt.producer_element.name}</i>\n{status_str}\n\n{smt.body}\n\n"
            # When "smt.producer_element.name" the provided as a fixed string (e.g, "smt.producer_element.name")
            # for testing purposes, the loop runs 3x faster
            # The reference `smt.producer_element.name` appears to be calling the database and creating poor performance
            # even where there are no statements.

        # Deprecated implementation of inherited/common controls
        # Leave commented out until we can fully delete...Greg - 2020-10-12
        # # Add in the common controls
        # for cc in self.root_element.common_controls.all():
        #     if cc.common_control.oscal_ctl_id in smts_as_dict:
        #         smts_as_dict[smt.sid]['common_controls'].append(cc)
        #     else:
        #         smts_as_dict[cc.common_control.oscal_ctl_id] = {"control_impl_smts": [], "common_controls": [cc], "combined_smt": ""}
        #     # Build combined statement
        #     smts_as_dict[cc.common_control.oscal_ctl_id]['combined_smt'] += "{}\n{}\n\n".format(cc.common_control.name, cc.common_control.body)

        # Populate any controls from assigned baseline that do not have statements
        for ec in selected_controls:
            if ec.get('oscal_ctl_id') not in smts_as_dict:
                smts_as_dict[ec.get('oscal_ctl_id')] = {
                    "control_impl_smts": [],
                    "common_controls": [],
                    "combined_smt": "",
                    "elementcontrol_uuid": ec.get('ec.uuid'),
                    "combined_smt_uuid": uuid.uuid4()
                }

        # Return the dictionary
        return smts_as_dict

    @cached_property
    def controls_status_count(self):
        """Retrieve counts of control status"""

        status_list = [
            'Not Implemented', 'Planned', 'Partially Implemented',
            'Implemented', 'Unknown'
        ]
        status_stats = {}
        # Fetch all selected controls
        elm = self.root_element
        for status in status_list:
            # Get the smts_control_implementations ordered by part, e.g. pid
            status_stats[status] = elm.statements_consumed.filter(
                statement_type="control_implementation",
                status=status).count()
        # TODO add index on statement status

        # Get overall controls addressed (e.g., covered)
        status_stats['Addressed'] = elm.statements_consumed.filter(
            statement_type="control_implementation").values('sid').count()
        return status_stats

    @cached_property
    def poam_status_count(self):
        """Retrieve counts of poam status"""

        # Temporarily hard code status list
        status_list = ['Open', 'Closed', "In Progress"]
        # TODO
        # Get a unique filter of status list and gather on that...
        status_stats = {}
        # Fetch all selected controls
        elm = self.root_element
        for status in status_list:
            # Get the smts_control_implementations ordered by part, e.g. pid
            status_stats[status] = elm.statements_consumed.filter(
                statement_type="POAM", status__iexact=status).count()
        # TODO add index on statement status
        return status_stats

    # @property (See below for creation of property from method)
    def get_producer_elements(self):
        smts = self.root_element.statements_consumed.all()
        components = set()
        for smt in smts:
            if smt.producer_element:
                components.add(smt.producer_element)
        components = list(components)
        components.sort(key=lambda component: component.name)
        return components

    producer_elements = cached_property(get_producer_elements)
コード例 #26
0
class ElementControl(auto_prefetch.Model):
    element = auto_prefetch.ForeignKey(
        Element,
        related_name="controls",
        on_delete=models.CASCADE,
        help_text=
        "The Element (e.g., System, Component, Host) to which controls are associated."
    )
    oscal_ctl_id = models.CharField(
        max_length=20,
        help_text="OSCAL formatted Control ID (e.g., au-2.3)",
        blank=True,
        null=True)
    oscal_catalog_key = models.CharField(
        max_length=100,
        help_text=
        "Catalog key from which catalog file can be derived (e.g., 'NIST_SP-800-53_rev4')",
        blank=True,
        null=True)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    updated = models.DateTimeField(auto_now=True, db_index=True)
    smts_updated = models.DateTimeField(
        auto_now=False,
        db_index=True,
        help_text="Store date of most recent statement update",
        blank=True,
        null=True)
    uuid = models.UUIDField(
        default=uuid.uuid4,
        editable=True,
        help_text="A UUID (a unique identifier) for this ElementControl.")

    # Notes
    # from controls.oscal import *;from controls.models import *;
    #     e = Element.objects.get(id=8);
    #     e.name;
    #     ecq = ElementControl.objects.filter(element=e);
    #     ec = ecq[0]
    #     ec.oscal_catalog_key
    #     cg = Catalog(ec.oscal_catalog_key)
    #     print(cg.get_flattened_control_as_dict(cg.get_control_by_id(ec.oscal_ctl_id)))
    #
    #     # Get the flattened oscal control information
    #     ec.get_flattened_oscal_control_as_dict()
    #     # Get Implementation statement if it exists
    #     ec.get_flattened_impl_smt_as_dict()
    #
    #     # Get an element/system by it's element id
    #     e = Element.objects.get(id=8);
    #     e.name;
    #     # Get all ElementControls for the Element
    #     ec_list = ElementControl.objects.filter(element=e);
    #     for ec in ec_list:
    #       print("OSCAL CONTROL")
    #       print(ec.get_flattened_oscal_control_as_dict())
    #       print("Implementation Statement")
    #       print(ec.get_flattened_impl_smt_as_dict())

    class Meta:
        unique_together = [('element', 'oscal_ctl_id', 'oscal_catalog_key')]

    def __str__(self):
        return "'%s id=%d'" % (self.oscal_ctl_id, self.id)

    def __repr__(self):
        # For debugging.
        return "'%s id=%d'" % (self.oscal_ctl_id, self.id)

    # Commenting out get_controls_by_element in 0.9.1.53+ because it does
    # not appear to be used in the code base.
    # def get_controls_by_element(self, element):

    #     # TODO: Is this method being used? Can it be deleted?
    #     query_set = self.objects.filter(element=element)
    #     selected_controls = {}
    #     for cl in query_set:
    #         selected_controls[cl['oscal_ctl_id']] = {'oscal_ctl_id': cl['oscal_ctl_id'],
    #                                                  'oscal_catalog_key': cl['oscal_catalog_key'],
    #                                                  'uuid': cl['uuid']
    #                                                  }
    #     # Sort
    #     selected_controls = natsorted(selected_controls, key=lambda x: x.oscal_ctl_id.casefold)

    #     return selected_controls

    def get_flattened_oscal_control_as_dict(self):
        cg = Catalog.GetInstance(catalog_key=self.oscal_catalog_key)
        return cg.get_flattened_control_as_dict(
            cg.get_control_by_id(self.oscal_ctl_id))
コード例 #27
0
class Element(auto_prefetch.Model):
    name = models.CharField(max_length=250,
                            help_text="Common name or acronym of the element",
                            unique=True,
                            blank=False,
                            null=False)
    full_name = models.CharField(max_length=250,
                                 help_text="Full name of the element",
                                 unique=False,
                                 blank=True,
                                 null=True)
    description = models.CharField(
        max_length=255,
        help_text="Brief description of the Element",
        unique=False,
        blank=True,
        null=True)
    element_type = models.CharField(max_length=150,
                                    help_text="Component type",
                                    unique=False,
                                    blank=True,
                                    null=True)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    updated = models.DateTimeField(auto_now=True, db_index=True)
    uuid = models.UUIDField(
        default=uuid.uuid4,
        editable=True,
        help_text="A UUID (a unique identifier) for this Element.")
    import_record = auto_prefetch.ForeignKey(
        ImportRecord,
        related_name="import_record_elements",
        on_delete=models.CASCADE,
        unique=False,
        blank=True,
        null=True,
        help_text="The Import Record which created this Element.")

    # Notes
    # Retrieve Element controls where element is e to answer "What controls selected for a system?" (System is an element.)
    #    element_id = 8
    #    e = Element.objects.get(id=element_id);
    #    e.controls.all()
    #    # returns <QuerySet ['ac-2 id=1', 'ac-3 id=2', 'au-2 id=3']>
    #
    # Retrieve statements
    #    e.statements_consumed.all()
    #
    # Retrieve statements that are control implementations
    #    e.statements_consumed.filter(statement_type="control_implementation")

    def __str__(self):
        return "'%s id=%d'" % (self.name, self.id)

    def __repr__(self):
        # For debugging.
        return "'%s id=%d'" % (self.name, self.id)

    def assign_owner_permissions(self, user):
        try:
            permissions = get_perms_for_model(Element)
            for perm in permissions:
                assign_perm(perm.codename, user, self)
            return True
        except:
            return False

    def assign_edit_permissions(self, user):
        try:
            permissions = ['view_element', 'change_element', 'add_element']
            for perm in permissions:
                assign_perm(perm, user, self)
            return True
        except:
            return False

    def assign_baseline_controls(self, user, baselines_key, baseline_name):
        """Assign set of controls from baseline to an element"""

        # Usage
        # s = System.objects.get(pk=20)
        # s.root_element.assign_baseline_controls('NIST_SP-800-53_rev4', 'low')

        can_assign_controls = user.has_perm('change_element', self)
        # Does user have edit permissions on system?
        if can_assign_controls:
            from controls.models import Baselines
            bs = Baselines()
            controls = bs.get_baseline_controls(baselines_key, baseline_name)
            for oscal_ctl_id in controls:
                ec = ElementControl(element=self,
                                    oscal_ctl_id=oscal_ctl_id,
                                    oscal_catalog_key=baselines_key)
                ec.save()
            return True
        else:
            # print("User does not have permission to assign selected controls to element's system.")
            return False

    def statements(self, statement_type):
        """Return on the statements of statement_type produced by this element"""
        smts = Statement.objects.filter(producer_element=self,
                                        statement_type=statement_type)
        return smts

    @property
    def get_control_impl_smts_prototype_count(self):
        """Return count of statements with this element as producer_element"""

        smt_count = Statement.objects.filter(
            producer_element=self,
            statement_type="control_implementation_prototype").count()

        return smt_count

    @transaction.atomic
    def copy(self, name=None):
        """Return a copy of an existing system element as a new element with duplicate control_implementation_prototype statements"""

        # Copy only elements that are components. Do not copy an element of type "system"
        # Components that are systems should always be associated with a project (at least currently).
        # Also, statement structure for a system would be very different.
        if self.element_type == "system":
            raise SystemException("Copying an entire system is not permitted.")

        e_copy = deepcopy(self)
        e_copy.id = None
        if name is not None:
            e_copy.name = name
        else:
            e_copy.name = self.name + " copy"
        e_copy.save()
        # Copy prototype statements from existing element
        for smt in self.statements("control_implementation_prototype"):
            smt_copy = deepcopy(smt)
            smt_copy.producer_element = e_copy
            smt_copy.consumer_element_id = None
            smt_copy.id = None
            smt_copy.save()
        return e_copy

    @property
    def selected_controls_oscal_ctl_ids(self):
        """Return array of selectecd controls oscal ids"""
        # oscal_ids = self.controls.all()
        oscal_ctl_ids = [
            control.oscal_ctl_id for control in self.controls.all()
        ]
        # Sort
        oscal_ctl_ids = natsorted(oscal_ctl_ids, key=str.casefold)

        return oscal_ctl_ids
コード例 #28
0
class Post(RulesModelMixin, auto_prefetch.Model, metaclass=RulesModelBase):
    """Post Model

    A model for Blog Posts

    Args:
        RulesModelMixin ([type]): [description]
        auto_prefetch ([type]): [description]
        metaclass ([type], optional): [description]. Defaults to RulesModelBase.

    Returns:
        Post: A model for Post
    """

    PUBLICATION_CHOICES = [
        ("P", "Published"),
        ("W", "Withdrawn"),
        ("D", "Draft"),
    ]

    FEATURING_CHOICES = [
        ("F", "Featured"),
        ("FB", "Featured Big"),
        ("N", "Not Featured"),
    ]

    LANGUAGE_CHOICES = [
        ("EN", "English"),
        ("FR", "French"),
        ("ML", "Multi Linguistic"),
        ("OL", "Other Language"),
        ("NS", "Not Specified"),
    ]

    author = auto_prefetch.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="post_author",
        help_text="Post author",
    )
    title = models.CharField(max_length=200, help_text="Post title")
    featured_title = models.CharField(max_length=27,
                                      default="",
                                      blank=True,
                                      help_text="Featured post title")
    body = MarkdownxField(help_text="Post main content", blank=True)

    image = models.ImageField(null=True,
                              blank=True,
                              upload_to="images/post/",
                              help_text="Post image")
    description = models.TextField(help_text="Post description")
    slug = models.SlugField(unique=True, max_length=200, help_text="Post slug")
    categories = models.ManyToManyField("blog.Category",
                                        through="PostCatsLink",
                                        help_text="Post categories")
    tags = TaggableManager(blank=True, through=CustomTaggedItem)
    series = auto_prefetch.ForeignKey(
        "blog.Series",
        on_delete=models.CASCADE,
        related_name="post_series",
        help_text="Post series",
        blank=True,
        null=True,
    )
    order_in_series = models.PositiveIntegerField(
        default=0, help_text="Post order in its series")
    created_date = models.DateTimeField(default=timezone.now,
                                        help_text="Creation date")
    mod_date = models.DateTimeField(auto_now=True,
                                    help_text="Last modification")
    pub_date = models.DateTimeField(blank=True,
                                    null=True,
                                    help_text="Publication date")
    publication_state = models.CharField(
        max_length=25,
        verbose_name="Publication",
        choices=PUBLICATION_CHOICES,
        default="D",
        help_text="Post publication state",
    )
    withdrawn = models.BooleanField(default=False,
                                    help_text="Is Post withdrawn")
    featuring_state = models.CharField(
        max_length=25,
        verbose_name="Featuring",
        choices=FEATURING_CHOICES,
        default="N",
        help_text="Featuring state",
    )
    language = models.CharField(
        max_length=25,
        verbose_name="Language",
        choices=LANGUAGE_CHOICES,
        default="EN",
        help_text="What's the main language",
    )
    is_outdated = models.BooleanField(default=False,
                                      help_text="Is Post content's outdated")
    url_to_article = models.URLField(
        default="", blank=True, help_text="Url to page that inspired the Post")
    url_to_article_title = models.CharField(
        max_length=200,
        default="",
        blank=True,
        help_text="What will be shown as url name",
    )
    clicks = models.IntegerField(
        default=0, help_text="How many times the Post has been seen")
    rnd_choice = models.IntegerField(
        default=0,
        help_text="How many times the Post has been randomly chosen")
    history = HistoricalRecords()
    is_removed = models.BooleanField("is removed",
                                     default=False,
                                     db_index=True,
                                     help_text=("Soft delete"))
    needs_reviewing = models.BooleanField(default=False,
                                          help_text=("Needs reviewing"))
    enable_comments = models.BooleanField(default=True)

    objects: PostManager = PostManager()

    class Meta:
        """Meta class for Post Model"""

        ordering = ["-pub_date"]
        get_latest_by = ["id"]
        rules_permissions = {
            "add": rules.is_superuser,
            "update": rules.is_superuser,
        }

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            max_length = Post._meta.get_field("slug").max_length
            self.slug = orig = slugify(self.title)[:max_length]
            for x in itertools.count(2):
                if (self.pk and Post.objects.filter(
                        Q(slug=self.slug),
                        Q(author=self.author),
                        Q(id=self.pk),
                ).exists()):
                    break
                if not Post.objects.filter(slug=self.slug).exists():
                    break

                # Truncate & Minus 1 for the hyphen.
                self.slug = "%s-%d" % (orig[:max_length - len(str(x)) - 1], x)
        return super().save(*args, **kwargs)

    def save_without_historical_record(self, *args, **kwargs):
        self.skip_history_when_saving = True
        try:
            ret = self.save(*args, **kwargs)
        finally:
            del self.skip_history_when_saving
        return ret

    def get_absolute_url(self):
        return reverse("blog:post_detail", kwargs={"slug": self.slug})

    def get_absolute_update_url(self):
        return reverse("blog:post_edit", kwargs={"slug": self.slug})

    def get_absolute_needs_review_url(self):
        return reverse("blog:post_needs_review", kwargs={"slug": self.slug})

    def get_absolute_delete_url(self):
        return reverse("blog:post_remove", kwargs={"slug": self.slug})

    def get_absolute_publish_url(self):
        return reverse("blog:post_publish", kwargs={"slug": self.slug})

    def get_absolute_publish_withdrawn_url(self):
        return reverse("blog:post_publish_withdrawn",
                       kwargs={"slug": self.slug})

    def get_absolute_clone_url(self):
        return reverse("blog:clone_post", kwargs={"slug": self.slug})

    def get_absolute_admin_update_url(self):
        return reverse("admin:blog_post_change", kwargs={"object_id": self.pk})

    def publish(self):
        self.pub_date = timezone.now()
        self.publication_state = "P"
        self.withdrawn = False
        self.save()

    def publish_withdrawn(self):
        self.pub_date = timezone.now()
        self.publication_state = "W"
        self.withdrawn = True
        self.save()

    def needs_review(self):
        self.needs_reviewing = True
        self.save()

    def clicked(self):
        self.clicks += 1
        self.save_without_historical_record(update_fields=["clicks"])

    def rnd_chosen(self):
        self.rnd_choice += 1
        self.save_without_historical_record(update_fields=["rnd_choice"])

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now

    def remove(self):
        self.is_removed = True
        self.save()

    # Create a property that returns the markdown instead
    @property
    def formatted_markdown(self):
        return markdownify(self.body)

    @property
    def is_scheduled(self) -> bool:
        now = timezone.now()
        if not self.pub_date:
            return False

        return self.pub_date >= now

    @property
    def author_name(self):
        return self.author.username

    @property
    def get_tags(self):
        return self.tags.filter(withdrawn=False)

    @property
    def get_admin_tags(self):
        return self.tags.all()

    @property
    def get_featured_cat(self):
        for post_cat in PostCatsLink.objects.filter(
                post_id=self.pk, category__is_removed=False,
                featured_cat=True).select_related("post", "category"):
            return post_cat

    @property
    def featured_cat_title(self):
        for post_cat in PostCatsLink.objects.filter(
                post_id=self.pk, category__is_removed=False,
                featured_cat=True).select_related("post", "category"):
            return post_cat.category.full_title

    def get_index_view_url(self):
        content_type = ContentType.objects.get_for_model(self.__class__)
        return reverse("%s:%s_list" %
                       (content_type.app_label, content_type.model))
コード例 #29
0
class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Integration',
            fields=[
                ('id',
                 models.BigAutoField(auto_created=True,
                                     primary_key=True,
                                     serialize=False,
                                     verbose_name='ID')),
                ('created',
                 models.DateTimeField(auto_now_add=True, db_index=True)),
                ('updated',
                 models.DateTimeField(auto_now=True, db_index=True,
                                      null=True)),
                ('name',
                 models.CharField(help_text='Endpoint name in lowercase',
                                  max_length=250)),
                ('description',
                 models.TextField(
                     blank=True,
                     default='',
                     help_text='Brief description of the Integration',
                     null=True)),
                ('config',
                 jsonfield.fields.JSONField(
                     blank=True,
                     default=dict,
                     help_text='Integration configuration',
                     null=True)),
                ('config_schema',
                 jsonfield.fields.JSONField(blank=True,
                                            default=dict,
                                            help_text='Integration schema',
                                            null=True)),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.CreateModel(
            name='HistoricalEndpoint',
            fields=[
                ('id',
                 models.BigIntegerField(auto_created=True,
                                        blank=True,
                                        db_index=True,
                                        verbose_name='ID')),
                ('created',
                 models.DateTimeField(blank=True,
                                      db_index=True,
                                      editable=False)),
                ('updated',
                 models.DateTimeField(blank=True,
                                      db_index=True,
                                      editable=False,
                                      null=True)),
                ('endpoint_path',
                 models.CharField(blank=True,
                                  help_text='Path to the Endpoint',
                                  max_length=250,
                                  null=True)),
                ('description',
                 models.TextField(
                     blank=True,
                     default='',
                     help_text='Brief description of the endpoint',
                     null=True)),
                ('element_type',
                 models.CharField(blank=True,
                                  help_text='Component type',
                                  max_length=150,
                                  null=True)),
                ('data',
                 jsonfield.fields.JSONField(
                     blank=True,
                     default=dict,
                     help_text='JSON object representing the API results.',
                     null=True)),
                ('history_id',
                 models.AutoField(primary_key=True, serialize=False)),
                ('history_date', models.DateTimeField()),
                ('history_change_reason',
                 models.CharField(max_length=100, null=True)),
                ('history_type',
                 models.CharField(choices=[('+', 'Created'), ('~', 'Changed'),
                                           ('-', 'Deleted')],
                                  max_length=1)),
                ('history_user',
                 models.ForeignKey(
                     null=True,
                     on_delete=django.db.models.deletion.SET_NULL,
                     related_name='+',
                     to=settings.AUTH_USER_MODEL)),
                ('integration',
                 auto_prefetch.ForeignKey(
                     blank=True,
                     db_constraint=False,
                     help_text="Endpoint's Integration",
                     null=True,
                     on_delete=django.db.models.deletion.DO_NOTHING,
                     related_name='+',
                     to='integrations.integration')),
            ],
            options={
                'verbose_name': 'historical endpoint',
                'ordering': ('-history_date', '-history_id'),
                'get_latest_by': 'history_date',
            },
            bases=(simple_history.models.HistoricalChanges, models.Model),
        ),
        migrations.CreateModel(
            name='Endpoint',
            fields=[
                ('id',
                 models.BigAutoField(auto_created=True,
                                     primary_key=True,
                                     serialize=False,
                                     verbose_name='ID')),
                ('created',
                 models.DateTimeField(auto_now_add=True, db_index=True)),
                ('updated',
                 models.DateTimeField(auto_now=True, db_index=True,
                                      null=True)),
                ('endpoint_path',
                 models.CharField(blank=True,
                                  help_text='Path to the Endpoint',
                                  max_length=250,
                                  null=True)),
                ('description',
                 models.TextField(
                     blank=True,
                     default='',
                     help_text='Brief description of the endpoint',
                     null=True)),
                ('element_type',
                 models.CharField(blank=True,
                                  help_text='Component type',
                                  max_length=150,
                                  null=True)),
                ('data',
                 jsonfield.fields.JSONField(
                     blank=True,
                     default=dict,
                     help_text='JSON object representing the API results.',
                     null=True)),
                ('integration',
                 auto_prefetch.ForeignKey(
                     help_text="Endpoint's Integration",
                     on_delete=django.db.models.deletion.CASCADE,
                     related_name='endpoints',
                     to='integrations.integration')),
            ],
            options={
                'abstract': False,
                'base_manager_name': 'prefetch_manager',
            },
            managers=[
                ('objects', django.db.models.manager.Manager()),
                ('prefetch_manager', django.db.models.manager.Manager()),
            ],
        ),
    ]
コード例 #30
0
class SubProject(BasePortfolioAbstractModel):
    """Model for SubProject"""

    parent_project = auto_prefetch.ForeignKey(
        "portfolio.Project",
        on_delete=models.CASCADE,
        related_name="sub_project",
        blank=True,
        null=True,
    )
    link_in_repo = models.CharField(max_length=255, default="", blank=True)
    featured = models.BooleanField(default=False)

    class Meta(BasePortfolioAbstractModel.Meta):
        """Meta class for SubProject Model Class"""

        ordering = ["pk"]

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.full_title)
        return super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("portfolio:sub_project_detail",
                       kwargs={
                           "slug": self.parent_project.slug,
                           "subproject_slug": self.slug
                       })

    def get_absolute_update_url(self):
        return reverse("portfolio:sub_project_edit",
                       kwargs={
                           "slug": self.parent_project.slug,
                           "subproject_slug": self.slug
                       })

    def get_absolute_delete_url(self):
        return reverse("portfolio:sub_project_delete",
                       kwargs={
                           "slug": self.parent_project.slug,
                           "subproject_slug": self.slug
                       })

    def get_absolute_admin_update_url(self):
        return reverse("admin:portfolio_subproject_change",
                       kwargs={"object_id": self.pk})

    @property
    def full_title(self) -> str:
        fulltitle = ""
        fulltitle = self.parent_project.title + " " + self.title
        return fulltitle

    def remove(self):
        self.is_removed = True
        self.save()

    def get_index_view_url(self):
        content_type = ContentType.objects.get_for_model(self.__class__)
        return reverse("%s:%s_list" %
                       (content_type.app_label, content_type.model))