Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 0 additions & 3 deletions backend/apps/github/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ github-enrich-issues:
@echo "Enriching GitHub issues"
@CMD="python manage.py github_enrich_issues" $(MAKE) exec-backend-command

github-match-users:
@CMD="python manage.py github_match_users $(MATCH_MODEL)" $(MAKE) exec-backend-command

github-update-owasp-organization:
@echo "Updating OWASP GitHub organization"
@CMD="python manage.py github_update_owasp_organization" $(MAKE) exec-backend-command
Expand Down
131 changes: 0 additions & 131 deletions backend/apps/github/management/commands/github_match_users.py

This file was deleted.

3 changes: 3 additions & 0 deletions backend/apps/owasp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ owasp-process-snapshots:
@echo "Processing OWASP snapshots"
@CMD="python manage.py owasp_process_snapshots" $(MAKE) exec-backend-command

owasp-update-leaders:
@CMD="python manage.py owasp_update_leaders $(MATCH_MODEL)" $(MAKE) exec-backend-command

owasp-update-project-health-metrics:
@echo "Updating OWASP project health metrics"
@CMD="python manage.py owasp_update_project_health_metrics" $(MAKE) exec-backend-command
Expand Down
1 change: 1 addition & 0 deletions backend/apps/owasp/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from .chapter import ChapterAdmin
from .committee import CommitteeAdmin
from .entity_member import EntityMemberAdmin
from .event import EventAdmin
from .post import PostAdmin
from .project import ProjectAdmin
Expand Down
6 changes: 3 additions & 3 deletions backend/apps/owasp/admin/chapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

from apps.owasp.models.chapter import Chapter

from .mixins import GenericEntityAdminMixin, LeaderAdminMixin
from .mixins import EntityMemberInline, GenericEntityAdminMixin


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

autocomplete_fields = ("owasp_repository",)
filter_horizontal = LeaderAdminMixin.filter_horizontal
inlines = (EntityMemberInline,)
list_display = (
"name",
"created_at",
Expand Down
11 changes: 4 additions & 7 deletions backend/apps/owasp/admin/committee.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@

from apps.owasp.models.committee import Committee

from .mixins import GenericEntityAdminMixin, LeaderAdminMixin
from .mixins import EntityMemberInline, GenericEntityAdminMixin


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

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


Expand Down
118 changes: 118 additions & 0 deletions backend/apps/owasp/admin/entity_member.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please restore bulk approval action functionality.

Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
"""EntityMember admin configuration."""

from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from django.urls import reverse
from django.utils.html import format_html

from apps.owasp.models.chapter import Chapter
from apps.owasp.models.committee import Committee
from apps.owasp.models.entity_member import EntityMember
from apps.owasp.models.project import Project


class EntityMemberAdmin(admin.ModelAdmin):
"""Admin for EntityMember records (generic link to any OWASP entity)."""

actions = ("approve_members",)
autocomplete_fields = ("member",)
fields = (
"entity_type",
"entity_id",
"member",
"role",
"order",
"is_active",
"is_reviewed",
"description",
)
list_display = (
"member",
"entity",
"owasp_url",
"role",
"is_active",
"is_reviewed",
"order",
)
list_filter = (
"role",
"is_active",
"is_reviewed",
)
raw_id_fields = ("member",)
search_fields = (
"member__login",
"member__name",
"description",
)
ordering = ("member__name", "order")

@admin.action(description="Approve selected members")
def approve_members(self, request, queryset):
"""Approve selected members."""
self.message_user(
request,
f"Successfully approved {queryset.update(is_active=True, is_reviewed=True)} members.",
)

@admin.display(description="Entity", ordering="entity_type")
def entity(self, obj):
"""Return entity link."""
return (
format_html(
'<a href="{}" target="_blank">{}</a>',
reverse(
f"admin:{obj.entity_type.app_label}_{obj.entity_type.model}_change",
args=[obj.entity_id],
),
obj.entity,
)
if obj.entity
else "-"
)

@admin.display(description="OWASP URL", ordering="entity_type")
def owasp_url(self, obj):
"""Return entity OWASP site URL."""
return (
format_html('<a href="{}" target="_blank">↗️</a>', obj.entity.owasp_url)
if obj.entity
else "-"
)

def get_search_results(self, request, queryset, search_term):
"""Get search results from entity name or key."""
queryset, use_distinct = super().get_search_results(request, queryset, search_term)

if search_term:
project_ids = Project.objects.filter(
Q(name__icontains=search_term) | Q(key__icontains=search_term)
).values_list("pk", flat=True)

chapter_ids = Chapter.objects.filter(
Q(name__icontains=search_term) | Q(key__icontains=search_term)
).values_list("pk", flat=True)

committee_ids = Committee.objects.filter(
Q(name__icontains=search_term) | Q(key__icontains=search_term)
).values_list("pk", flat=True)

project_ct = ContentType.objects.get_for_model(Project)
chapter_ct = ContentType.objects.get_for_model(Chapter)
committee_ct = ContentType.objects.get_for_model(Committee)

entity_match_query = (
Q(entity_type=project_ct, entity_id__in=list(project_ids))
| Q(entity_type=chapter_ct, entity_id__in=list(chapter_ids))
| Q(entity_type=committee_ct, entity_id__in=list(committee_ids))
)

queryset |= self.model.objects.filter(entity_match_query)
use_distinct = True

return queryset, use_distinct


admin.site.register(EntityMember, EntityMemberAdmin)
Loading