Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
14 changes: 14 additions & 0 deletions backend/apps/owasp/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django.contrib import admin

from apps.owasp.models.project_health_requirements import ProjectHealthRequirements

from .chapter import ChapterAdmin
from .committee import CommitteeAdmin
from .event import EventAdmin
from .post import PostAdmin
from .project import ProjectAdmin
from .project_health_metrics import ProjectHealthMetricsAdmin
from .snapshot import SnapshotAdmin
from .sponsor import SponsorAdmin

admin.site.register(ProjectHealthRequirements)
30 changes: 30 additions & 0 deletions backend/apps/owasp/admin/chapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from django.contrib import admin

from apps.owasp.models.chapter import Chapter

from .mixins import GenericEntityAdminMixin, LeaderAdminMixin


class ChapterAdmin(admin.ModelAdmin, GenericEntityAdminMixin, LeaderAdminMixin):
"""Admin for Chapter model."""

autocomplete_fields = ("owasp_repository",)
filter_horizontal = LeaderAdminMixin.filter_horizontal
list_display = (
"name",
"created_at",
"updated_at",
"region",
"custom_field_owasp_url",
"custom_field_github_urls",
)
list_filter = (
"is_active",
"is_leaders_policy_compliant",
"country",
"region",
)
search_fields = ("name", "key")


admin.site.register(Chapter, ChapterAdmin)
19 changes: 19 additions & 0 deletions backend/apps/owasp/admin/committee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.contrib import admin

from apps.owasp.models.committee import Committee

from .mixins import GenericEntityAdminMixin, LeaderAdminMixin


class CommitteeAdmin(admin.ModelAdmin, GenericEntityAdminMixin, LeaderAdminMixin):
"""Admin for Committee model."""

autocomplete_fields = (
"leaders",
"owasp_repository",
)
filter_horizontal = LeaderAdminMixin.filter_horizontal
search_fields = ("name",)


admin.site.register(Committee, CommitteeAdmin)
16 changes: 16 additions & 0 deletions backend/apps/owasp/admin/event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.contrib import admin

from apps.owasp.models.event import Event


class EventAdmin(admin.ModelAdmin):
"""Admin for Event model."""

list_display = (
"name",
"suggested_location",
)
search_fields = ("name",)


admin.site.register(Event, EventAdmin)
58 changes: 58 additions & 0 deletions backend/apps/owasp/admin/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from django.contrib import admin, messages
from django.utils.safestring import mark_safe


class GenericEntityAdminMixin:
"""Mixin for generic entity admin."""

def get_queryset(self, request):
"""Get queryset."""
return super().get_queryset(request).prefetch_related("repositories")

def custom_field_github_urls(self, obj):
"""Entity GitHub URLs."""
if not hasattr(obj, "repositories"):
return mark_safe( # noqa: S308
f"<a href='https://github.com/{obj.owasp_repository.owner.login}/"
f"{obj.owasp_repository.key}' target='_blank'>↗️</a>"
)

urls = [
f"<a href='https://github.com/{repository.owner.login}/"
f"{repository.key}' target='_blank'>↗️</a>"
for repository in obj.repositories.all()
]

return mark_safe(" ".join(urls)) # noqa: S308

def custom_field_owasp_url(self, obj):
"""Entity OWASP URL."""
return mark_safe( # noqa: S308
f"<a href='https://owasp.org/{obj.key}' target='_blank'>↗️</a>"
)

custom_field_github_urls.short_description = "GitHub 🔗"
custom_field_owasp_url.short_description = "OWASP 🔗"


class LeaderAdminMixin:
"""Admin mixin for entities that can have leaders."""

actions = ("approve_suggested_leaders",)
filter_horizontal = (
"leaders",
"suggested_leaders",
)

def approve_suggested_leaders(self, request, queryset):
"""Approve suggested leaders for selected entities."""
for entity in queryset:
suggestions = entity.suggested_leaders.all()
entity.leaders.add(*suggestions)
self.message_user(
request,
f"Approved {suggestions.count()} leader suggestions for {entity.name}",
messages.SUCCESS,
)

approve_suggested_leaders.short_description = "Approve suggested leaders"
23 changes: 23 additions & 0 deletions backend/apps/owasp/admin/post.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.contrib import admin

from apps.owasp.models.post import Post


class PostAdmin(admin.ModelAdmin):
"""Admin configuration for Post model."""

list_display = (
"author_name",
"published_at",
"title",
)
search_fields = (
"author_image_url",
"author_name",
"published_at",
"title",
"url",
)


admin.site.register(Post, PostAdmin)
54 changes: 54 additions & 0 deletions backend/apps/owasp/admin/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from django.contrib import admin

from apps.owasp.models.project import Project

from .mixins import GenericEntityAdminMixin, LeaderAdminMixin


class ProjectAdmin(admin.ModelAdmin, GenericEntityAdminMixin, LeaderAdminMixin):
"""Admin for Project model."""

autocomplete_fields = (
"organizations",
"owasp_repository",
"owners",
"repositories",
)
filter_horizontal = LeaderAdminMixin.filter_horizontal
list_display = (
"custom_field_name",
"created_at",
"updated_at",
"stars_count",
"forks_count",
"commits_count",
"releases_count",
"custom_field_owasp_url",
"custom_field_github_urls",
)
list_filter = (
"is_active",
"is_leaders_policy_compliant",
"has_active_repositories",
"level",
"type",
)
ordering = ("-created_at",)
search_fields = (
"custom_tags",
"description",
"key",
"languages",
"leaders_raw",
"name",
"topics",
)

def custom_field_name(self, obj) -> str:
"""Project custom name."""
return f"{obj.name or obj.key}"

custom_field_name.short_description = "Name"


admin.site.register(Project, ProjectAdmin)
32 changes: 32 additions & 0 deletions backend/apps/owasp/admin/project_health_metrics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from django.contrib import admin

from apps.owasp.models.project_health_metrics import ProjectHealthMetrics


class ProjectHealthMetricsAdmin(admin.ModelAdmin):
"""Admin for ProjectHealthMetrics model."""

autocomplete_fields = ("project",)
list_filter = (
"project__level",
"nest_created_at",
)
list_display = (
"project",
"nest_created_at",
"score",
"contributors_count",
"stars_count",
"forks_count",
"open_issues_count",
"open_pull_requests_count",
"recent_releases_count",
)
search_fields = ("project__name",)

def project(self, obj):
"""Display project name."""
return obj.project.name if obj.project else "N/A"


admin.site.register(ProjectHealthMetrics, ProjectHealthMetricsAdmin)
38 changes: 38 additions & 0 deletions backend/apps/owasp/admin/snapshot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from django.contrib import admin

from apps.owasp.models.snapshot import Snapshot


class SnapshotAdmin(admin.ModelAdmin):
"""Admin for Snapshot model."""

autocomplete_fields = (
"new_chapters",
"new_issues",
"new_projects",
"new_releases",
"new_users",
)
list_display = (
"title",
"start_at",
"end_at",
"status",
"created_at",
"updated_at",
)
list_filter = (
"status",
"start_at",
"end_at",
)
ordering = ("-start_at",)
search_fields = (
"title",
"key",
"status",
"error_message",
)


admin.site.register(Snapshot, SnapshotAdmin)
36 changes: 36 additions & 0 deletions backend/apps/owasp/admin/sponsor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from django.contrib import admin

from apps.owasp.models.sponsor import Sponsor


class SponsorAdmin(admin.ModelAdmin):
"""Admin for Sponsor model."""

list_display = (
"name",
"sort_name",
"sponsor_type",
"is_member",
"member_type",
)

search_fields = (
"name",
"sort_name",
"description",
)

list_filter = (
"sponsor_type",
"is_member",
"member_type",
)

fieldsets = (
("Basic Information", {"fields": ("name", "sort_name", "description")}),
("URLs and Images", {"fields": ("url", "job_url", "image_url")}),
("Status", {"fields": ("is_member", "member_type", "sponsor_type")}),
)


admin.site.register(Sponsor, SponsorAdmin)