Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0813db0
refactor(product_type): extract Product_Type model into dojo/product_…
valentijnscholten Jun 7, 2026
9d5e1f7
refactor(product_type): move forms + UI filter into dojo/product_type…
valentijnscholten Jun 7, 2026
a53c81e
refactor(product_type): move views into dojo/product_type/ui/views.py…
valentijnscholten Jun 7, 2026
ced171c
refactor(product_type): extract API layer into dojo/product_type/api/…
valentijnscholten Jun 7, 2026
68c101c
docs(agents): fold Phase 1 reorg lessons into the playbook
valentijnscholten Jun 7, 2026
0d48ce8
docs(agents): add Phase 2-9 lessons from the product_type full reorg
valentijnscholten Jun 7, 2026
dc7e7bc
docs(agents): add API serializer/viewset cycle-break + class-copy les…
valentijnscholten Jun 7, 2026
06b9be7
docs(agents): note prefetcher full-reexport + extend_schema_field cyc…
valentijnscholten Jun 7, 2026
4cc2e7d
docs(agents): add Phase 10 peripheral-module 10-PR stack plan
valentijnscholten Jun 8, 2026
024b466
refactor(test): extract Test/Test_Type/Test_Import models into dojo/t…
valentijnscholten Jun 7, 2026
60d6dcb
refactor(test): extract copy_test workflow into services.py [test Pha…
valentijnscholten Jun 7, 2026
3bdfbb9
refactor(test): move forms + UI filters into dojo/test/ui/ [test Phas…
valentijnscholten Jun 7, 2026
4c8a661
refactor(test): move views + urls into dojo/test/ui/ [test Phase 5]
valentijnscholten Jun 7, 2026
4037931
refactor(test): extract API layer into dojo/test/api/ [test Phase 6,7…
valentijnscholten Jun 7, 2026
504b670
refactor(engagement): extract Engagement/Engagement_Presets models in…
valentijnscholten Jun 7, 2026
92bbdfa
refactor(engagement): extract copy_engagement workflow into services.…
valentijnscholten Jun 7, 2026
4740f8f
refactor(engagement): move forms + UI filters into dojo/engagement/ui…
valentijnscholten Jun 7, 2026
3124b19
refactor(engagement): move views + urls into dojo/engagement/ui/ [eng…
valentijnscholten Jun 7, 2026
f91f072
refactor(engagement): extract API layer into dojo/engagement/api/ [en…
valentijnscholten Jun 7, 2026
ac196a5
refactor(product): extract Product/Product_Line/Product_API_Scan_Conf…
valentijnscholten Jun 7, 2026
fe523c6
refactor(product): move forms + UI filters into dojo/product/ui/ [pro…
valentijnscholten Jun 7, 2026
f9d671a
refactor(product): move views into dojo/product/ui/ [product Phase 5]
valentijnscholten Jun 7, 2026
5f3fe41
refactor(product): extract API layer into dojo/product/api/ [product …
valentijnscholten Jun 7, 2026
0ac89a6
refactor(finding): extract Finding/Vulnerability_Id/Finding_Group/Fin…
valentijnscholten Jun 7, 2026
2dc2e80
refactor(finding): move forms + UI filters into dojo/finding/ui/ [fin…
valentijnscholten Jun 7, 2026
3d4f36b
refactor(finding): move views + urls into dojo/finding/ui/ [finding P…
valentijnscholten Jun 7, 2026
49e1de9
refactor(finding): extract API layer into dojo/finding/api/ [finding …
valentijnscholten Jun 7, 2026
ee0d7aa
refactor(finding): fold CWE + BurpRawRequestResponse into dojo/findin…
valentijnscholten Jun 8, 2026
0453e5f
refactor(user): extract user module into dojo/user/ [user Phase 1,3,4…
valentijnscholten Jun 8, 2026
ccf8935
refactor(system_settings): extract System_Settings into dojo/system_s…
valentijnscholten Jun 8, 2026
dc76c6a
refactor(tools): extract tool_type, tool_config, tool_product into do…
valentijnscholten Jun 8, 2026
a54b1b1
refactor(endpoint): extract endpoint module into dojo/endpoint/ [endp…
valentijnscholten Jun 8, 2026
e529ec5
refactor(survey,benchmark): extract survey + benchmark modules into d…
valentijnscholten Jun 8, 2026
a571085
refactor(notes,files): extract note_type, notes, file_uploads, report…
valentijnscholten Jun 8, 2026
801c982
refactor(risk_acceptance): extract Risk_Acceptance into dojo/risk_acc…
valentijnscholten Jun 9, 2026
cf5d353
refactor(misc): extract regulations, banner, announcement, developmen…
valentijnscholten Jun 9, 2026
b8944d7
docs(agents): mark Phase 10 peripheral modules Complete + refresh mon…
valentijnscholten Jun 9, 2026
ce07ea2
refactor(reorg): add backward-compat re-exports for moved symbols
valentijnscholten Jun 17, 2026
950ccce
fix(test): retarget finding_added dispatch patch to moved serializer …
valentijnscholten Jun 17, 2026
f77846c
fix(reorg): restore disabled prefetch schema on DojoMetaViewSet
valentijnscholten Jun 18, 2026
3cfb9c4
fix(api): restore prefetch schema + serializer re-export for ProductA…
valentijnscholten Jun 24, 2026
99db9b2
refactor(object): import Product from dojo.product.models at module top
valentijnscholten Jun 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 131 additions & 26 deletions AGENTS.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dojo/announcement/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import dojo.announcement.admin # noqa: F401
6 changes: 6 additions & 0 deletions dojo/announcement/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.contrib import admin

from dojo.announcement.models import Announcement, UserAnnouncement

admin.site.register(Announcement)
admin.site.register(UserAnnouncement)
1 change: 1 addition & 0 deletions dojo/announcement/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
path = "announcements" # noqa: RUF067
21 changes: 21 additions & 0 deletions dojo/announcement/api/serializer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.db import IntegrityError
from rest_framework import serializers

from dojo.announcement.models import Announcement


class AnnouncementSerializer(serializers.ModelSerializer):

class Meta:
model = Announcement
fields = "__all__"

def create(self, validated_data):
validated_data["id"] = 1
try:
return super().create(validated_data)
except IntegrityError as e:
if 'duplicate key value violates unique constraint "dojo_announcement_pkey"' in str(e):
msg = "No more than one Announcement is allowed"
raise serializers.ValidationError(msg)
raise
7 changes: 7 additions & 0 deletions dojo/announcement/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from dojo.announcement.api import path
from dojo.announcement.api.views import AnnouncementViewSet


def add_announcement_urls(router):
router.register(path, AnnouncementViewSet, basename="announcement")
return router
20 changes: 20 additions & 0 deletions dojo/announcement/api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django_filters.rest_framework import DjangoFilterBackend

from dojo.announcement.api.serializer import AnnouncementSerializer
from dojo.announcement.models import Announcement
from dojo.api_v2.views import DojoModelViewSet
from dojo.authorization import api_permissions as permissions


# Authorization: configuration
class AnnouncementViewSet(
DojoModelViewSet,
):
serializer_class = AnnouncementSerializer
queryset = Announcement.objects.none()
filter_backends = (DjangoFilterBackend,)
filterset_fields = "__all__"
permission_classes = (permissions.UserHasConfigurationPermissionStaff,)

def get_queryset(self):
return Announcement.objects.all().order_by("id")
28 changes: 28 additions & 0 deletions dojo/announcement/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from django.db import models
from django.utils.translation import gettext as _

ANNOUNCEMENT_STYLE_CHOICES = (
("info", "Info"),
("success", "Success"),
("warning", "Warning"),
("danger", "Danger"),
)


class Announcement(models.Model):
message = models.CharField(max_length=500,
help_text=_("This dismissable message will be displayed on all pages for authenticated users. It can contain basic html tags, for example <a href='https://www.fred.com' style='color: #337ab7;' target='_blank'>https://example.com</a>"),
default="")
style = models.CharField(max_length=64, choices=ANNOUNCEMENT_STYLE_CHOICES, default="info",
help_text=_("The style of banner to display. (info, success, warning, danger)"))
dismissable = models.BooleanField(default=False,
null=False,
blank=True,
verbose_name=_("Dismissable?"),
help_text=_("Ticking this box allows users to dismiss the current announcement"),
)


class UserAnnouncement(models.Model):
announcement = models.ForeignKey("dojo.Announcement", null=True, editable=False, on_delete=models.CASCADE, related_name="user_announcement")
user = models.ForeignKey("dojo.Dojo_User", null=True, editable=False, on_delete=models.CASCADE)
3 changes: 2 additions & 1 deletion dojo/announcement/signals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.db.models.signals import post_save
from django.dispatch import receiver

from dojo.models import Announcement, Dojo_User, UserAnnouncement
from dojo.announcement.models import Announcement, UserAnnouncement
from dojo.user.models import Dojo_User


@receiver(post_save, sender=Dojo_User)
Expand Down
Empty file.
17 changes: 17 additions & 0 deletions dojo/announcement/ui/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django import forms

from dojo.announcement.models import Announcement


class AnnouncementCreateForm(forms.ModelForm):
class Meta:
model = Announcement
fields = "__all__"


class AnnouncementRemoveForm(AnnouncementCreateForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["dismissable"].disabled = True
self.fields["message"].disabled = True
self.fields["style"].disabled = True
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.urls import re_path

from dojo.announcement import views
from dojo.announcement.ui import views

urlpatterns = [
re_path(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _

from dojo.forms import AnnouncementCreateForm, AnnouncementRemoveForm
from dojo.models import Announcement, UserAnnouncement
from dojo.announcement.models import Announcement, UserAnnouncement
from dojo.announcement.ui.forms import AnnouncementCreateForm, AnnouncementRemoveForm
from dojo.utils import add_breadcrumb

logger = logging.getLogger(__name__)
Expand Down
Loading
Loading