Skip to content
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
4d339f7
test: add unit tests for SortBy component
Dhirajsharma2060 Jul 31, 2025
873742c
test: update SortBy component tests for prop naming and accessibility
Dhirajsharma2060 Aug 1, 2025
ab51c73
test: import React in SortBy component tests for consistency
Dhirajsharma2060 Aug 1, 2025
9b5197d
made some chnages
Dhirajsharma2060 Aug 3, 2025
a247251
test: update SortBy component tests for improved accessibility and cl…
Dhirajsharma2060 Aug 3, 2025
1da6630
Merge branch 'main' into feature/test-sortby-component-1915
Dhirajsharma2060 Aug 3, 2025
c1de740
test: ensure order toggle button functionality in SortBy component tests
Dhirajsharma2060 Aug 3, 2025
02fc6e9
feat: add has_full_name filter to top contributors query and model
Dhirajsharma2060 Aug 6, 2025
22f2cd2
fix: update regex for user name filtering in RepositoryContributor qu…
Dhirajsharma2060 Aug 6, 2025
c466bc4
Merge branch 'main' into pr/Dhirajsharma2060/1993
arkid15r Aug 6, 2025
ffb6447
Update code
arkid15r Aug 6, 2025
f216e86
test: enhance RepositoryContributor tests with full name filter valid…
Dhirajsharma2060 Aug 7, 2025
640dc29
Merge branch 'feature/top-contributors-has-full-name-filter-1990' of …
Dhirajsharma2060 Aug 7, 2025
8907d0b
refactor: use class constants for regex pattern and mock data in Repo…
Dhirajsharma2060 Aug 7, 2025
f514db2
test: fix regex filter call in has_full_name filter validation
Dhirajsharma2060 Aug 7, 2025
30ab091
Update code
arkid15r Aug 7, 2025
e4fae6e
Update tests
arkid15r Aug 7, 2025
f2fb122
Merge branch 'main' into feature/top-contributors-has-full-name-filte…
arkid15r Aug 7, 2025
8e39dd6
Update code
arkid15r Aug 7, 2025
854fdf4
Update tests
arkid15r Aug 7, 2025
80fa7b5
Update test
arkid15r Aug 7, 2025
6d953e4
feat: periodic job to sync OWASP Employee badges (#1762)
Dhirajsharma2060 Aug 11, 2025
e0835ed
Merge remote-tracking branch 'origin/feature/daily-badge-sync-job-176…
Dhirajsharma2060 Aug 11, 2025
fa5020f
fix: optimize badge assignment logic and improve test coverage for sy…
Dhirajsharma2060 Aug 11, 2025
713a7b5
refactor: clean up comments in sync_user_badges test cases for clarity
Dhirajsharma2060 Aug 11, 2025
17000eb
refactor: remove unused mock_badge fixture from sync_user_badges test
Dhirajsharma2060 Aug 11, 2025
193af74
feat: add management command to sync OWASP Staff badges and correspon…
Dhirajsharma2060 Aug 12, 2025
e56ccdb
refactor: optimize badge assignment logic for OWASP Staff badge sync
Dhirajsharma2060 Aug 12, 2025
bcef54a
Merge branch 'main' into pr/Dhirajsharma2060/2047
arkid15r Aug 12, 2025
9fc6338
Update code
arkid15r Aug 12, 2025
56c8901
feat: add badges field to User model and update badge sync logic for …
Dhirajsharma2060 Aug 13, 2025
8631d06
feat: add badges field to User model and update related tests for bad…
Dhirajsharma2060 Aug 13, 2025
3bc74e5
test: ensure no badge operations are performed when no employees are …
Dhirajsharma2060 Aug 13, 2025
91594ed
test: enhance user filter logic and improve badge assignment messages…
Dhirajsharma2060 Aug 14, 2025
8afe47e
test: refine user filter logic for badge assignment and enhance handl…
Dhirajsharma2060 Aug 14, 2025
e88656d
test: refactor user filter logic in badge assignment tests for improv…
Dhirajsharma2060 Aug 14, 2025
348c859
test: simplify user filter logic in badge assignment tests for improv…
Dhirajsharma2060 Aug 14, 2025
b0d3e84
test: simplify user filter logic by extracting helper functions for i…
Dhirajsharma2060 Aug 14, 2025
de0872b
test: update patch paths for badge and user objects in sync_user_badg…
Dhirajsharma2060 Aug 14, 2025
f0d7376
Merge branch 'main' into pr/Dhirajsharma2060/2047
arkid15r Aug 16, 2025
e9014b9
Update code
arkid15r Aug 16, 2025
3849ea6
test: update patch paths for badge and user objects in TestSyncUserBa…
Dhirajsharma2060 Aug 16, 2025
bb4dd30
Fix #1912: Added test for SecondaryCard component (#2069)
rasesh-here Aug 15, 2025
d1e1871
test: add unit tests for GeneralCompliantComponent (#2018)
addresskrish Aug 15, 2025
cc6278c
Added Light Theme Support for Contribution HeatMap (#2072)
Abhay056 Aug 15, 2025
864e98b
feat: add comprehensive unit tests for DisplayIcon component (#2048)
RizWaaN3024 Aug 15, 2025
3c9b1d3
enhance:change-hover-color-action-button (#1978)
VijeshVS Aug 16, 2025
d468668
Test: add unit tests for BarChart component #1801 (#1904)
MohdWaqar98 Aug 16, 2025
73d4db7
Project Dasbored Drop Down Test case has been made (#2052)
SOHAMPAL23 Aug 16, 2025
a4ab5d0
fix: update command references in badge management tests
Dhirajsharma2060 Aug 16, 2025
91a2d67
Merge branch 'main' into pr/Dhirajsharma2060/2047
arkid15r Aug 16, 2025
6131c06
Update code
arkid15r Aug 16, 2025
6086707
Merge branch 'main' into feature/daily-badge-sync-job-1763
kasya Aug 17, 2025
1a9c89b
fix: update badge management command to correctly filter users by bad…
Dhirajsharma2060 Aug 18, 2025
9fe34c5
style: format code for better readability in badge assignment logic
Dhirajsharma2060 Aug 18, 2025
7c7781f
fix: update badge assignment logic to use UserBadge model and remove …
Dhirajsharma2060 Aug 18, 2025
0e70c0e
Merge branch 'feature/daily-badge-sync-job-1763' of github.com:Dhiraj…
Dhirajsharma2060 Aug 18, 2025
4b2dafd
fix: include owasp Makefile in backend Makefile
Dhirajsharma2060 Aug 18, 2025
d2d6ca7
fix: improve badge removal logic for non-OWASP employees
Dhirajsharma2060 Aug 18, 2025
caf00f7
fix: add unique constraint for user and badge in UserBadge model
Dhirajsharma2060 Aug 20, 2025
49794b6
Update code
arkid15r Aug 20, 2025
798ecfe
Revert volumes
arkid15r Aug 20, 2025
10473bb
Merge branch 'main' into feature/daily-badge-sync-job-1763
arkid15r Aug 20, 2025
4d29a6d
feat: add is_active field to UserBadge model and update badge assignm…
Dhirajsharma2060 Aug 22, 2025
5f139f9
style: format migration file for userbadge is_active field
Dhirajsharma2060 Aug 23, 2025
13791ae
test: mock return value for UserBadge get_or_create in badge sync tests
Dhirajsharma2060 Aug 23, 2025
4d95c48
fix: correct docstring for nest_update_badges management command tests
Dhirajsharma2060 Aug 23, 2025
8476044
Merge branch 'main' into pr/Dhirajsharma2060/2047
arkid15r Aug 28, 2025
d8b46a6
Update code
arkid15r Aug 28, 2025
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
1 change: 1 addition & 0 deletions backend/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include backend/apps/ai/Makefile
include backend/apps/github/Makefile
include backend/apps/nest/Makefile
include backend/apps/owasp/Makefile
include backend/apps/slack/Makefile

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 5.2.5 on 2025-08-16 02:30

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("github", "0034_merge_20250804_1817"),
]

operations = [
migrations.AlterField(
model_name="user",
name="bio",
field=models.TextField(blank=True, default="", max_length=1000, verbose_name="Bio"),
),
migrations.AlterField(
model_name="user",
name="is_owasp_staff",
field=models.BooleanField(
default=False,
help_text="Indicates if the user is OWASP Foundation staff.",
verbose_name="Is OWASP Staff",
),
),
]
6 changes: 3 additions & 3 deletions backend/apps/github/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Meta:
]
verbose_name_plural = "Users"

bio = models.TextField(verbose_name="Bio", max_length=1000, default="")
bio = models.TextField(verbose_name="Bio", max_length=1000, blank=True, default="")
is_hireable = models.BooleanField(verbose_name="Is hireable", default=False)
twitter_username = models.CharField(
verbose_name="Twitter username", max_length=50, default="", blank=True
Expand All @@ -37,8 +37,8 @@ class Meta:

is_owasp_staff = models.BooleanField(
default=False,
verbose_name="OWASP Staff",
help_text="Indicates if the user is an OWASP staff member.",
verbose_name="Is OWASP Staff",
help_text="Indicates if the user is OWASP Foundation staff.",
)

contributions_count = models.PositiveIntegerField(
Expand Down
3 changes: 3 additions & 0 deletions backend/apps/nest/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nest-update-badges:
@echo "Updating Nest user badges"
@CMD="python manage.py nest_update_badges" $(MAKE) exec-backend-command
1 change: 1 addition & 0 deletions backend/apps/nest/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from .api_key import ApiKeyAdmin
from .badge import BadgeAdmin
from .user import UserAdmin
from .user_badge import UserBadgeAdmin
47 changes: 47 additions & 0 deletions backend/apps/nest/admin/user_badge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""Admin configuration for the user badge model in the OWASP app."""

from django.contrib import admin

from apps.nest.models.user_badge import UserBadge


class UserBadgeAdmin(admin.ModelAdmin):
"""Admin for UserBadge model."""

autocomplete_fields = ("user", "badge")
fieldsets = (
(
"User and Badge",
{
"fields": (
"user",
"badge",
)
},
),
("Note", {"fields": ("note",)}),
(
"Timestamps",
{
"fields": (
"nest_created_at",
"nest_updated_at",
)
},
),
)
list_display = (
"user",
"badge",
"note",
"nest_created_at",
"nest_updated_at",
)
readonly_fields = (
"nest_created_at",
"nest_updated_at",
)
search_fields = ("user__login", "badge__name", "note")


admin.site.register(UserBadge, UserBadgeAdmin)
Empty file.
Empty file.
70 changes: 70 additions & 0 deletions backend/apps/nest/management/commands/nest_update_badges.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Management command to sync badges for users based on their roles/attributes."""

import logging

from django.core.management.base import BaseCommand

from apps.github.models.user import User
from apps.nest.models.badge import Badge
from apps.nest.models.user_badge import UserBadge

logger = logging.getLogger(__name__)

OWASP_STAFF_BADGE_NAME = "OWASP Staff"


class Command(BaseCommand):
"""Sync badges for users based on their roles and attributes."""

help = "Sync badges for users based on their roles and attributes"

def handle(self, *args, **options):
"""Execute the command."""
self.stdout.write("Syncing user badges...")
self.update_owasp_staff_badge()
self.stdout.write(self.style.SUCCESS("User badges sync completed"))

def update_owasp_staff_badge(self):
"""Sync OWASP Staff badge for users."""
# Get or create the OWASP Staff badge
badge, created = Badge.objects.get_or_create(
name=OWASP_STAFF_BADGE_NAME,
defaults={
"description": "Official OWASP Staff",
"css_class": "fa-user-shield",
"weight": 100, # High weight for importance
},
)

if created:
logger.info("Created '%s' badge", OWASP_STAFF_BADGE_NAME)
self.stdout.write(f"Created badge: {badge.name}")

# Assign badge to employees who don't have it.
employees_without_badge = User.objects.filter(is_owasp_staff=True).exclude(
badges__badge=badge
)
count = employees_without_badge.count()

if count:
for user in employees_without_badge:
UserBadge.objects.get_or_create(user=user, badge=badge)

logger.info("Added '%s' badge to %s users", OWASP_STAFF_BADGE_NAME, count)
self.stdout.write(f"Added badge to {count} employees")

# Remove badge from non-OWASP employees.
non_employees = User.objects.filter(
is_owasp_staff=False,
badges__badge=badge,
).distinct()
removed_count = non_employees.count()

if removed_count:
UserBadge.objects.filter(
user_id__in=non_employees.values_list("id", flat=True),
badge=badge,
).delete()

logger.info("Removed '%s' badge from %s users", OWASP_STAFF_BADGE_NAME, removed_count)
self.stdout.write(f"Removed badge from {removed_count} non-employees")
65 changes: 65 additions & 0 deletions backend/apps/nest/migrations/0004_userbadge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Generated by Django 5.2.5 on 2025-08-16 02:30

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("github", "0035_alter_user_bio_alter_user_is_owasp_staff"),
("nest", "0003_badge"),
]

operations = [
migrations.CreateModel(
name="UserBadge",
fields=[
(
"id",
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("nest_created_at", models.DateTimeField(auto_now_add=True)),
("nest_updated_at", models.DateTimeField(auto_now=True)),
(
"note",
models.CharField(
blank=True,
default="",
help_text="Optional note of the user badge.",
max_length=255,
verbose_name="Note",
),
),
(
"badge",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="users",
to="nest.badge",
verbose_name="Badge",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="badges",
to="github.user",
verbose_name="User",
),
),
],
options={
"verbose_name_plural": "User badges",
"db_table": "nest_user_badges",
"constraints": [
models.UniqueConstraint(
fields=["user", "badge"],
name="uq_userbadge_user_badge",
)
],
},
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generated by Django 5.2.5 on 2025-08-18 13:27

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("nest", "0004_userbadge"),
]

operations = [
migrations.RemoveConstraint(
model_name="userbadge",
name="uq_userbadge_user_badge",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 5.2.5 on 2025-08-18 17:35

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("github", "0035_alter_user_bio_alter_user_is_owasp_staff"),
("nest", "0005_remove_userbadge_uq_userbadge_user_badge"),
]

operations = [
migrations.AddConstraint(
model_name="userbadge",
constraint=models.UniqueConstraint(
fields=("user", "badge"), name="uq_userbadge_user_badge"
),
),
]
1 change: 1 addition & 0 deletions backend/apps/nest/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .api_key import ApiKey
from .badge import Badge
from .user import User
from .user_badge import UserBadge
47 changes: 47 additions & 0 deletions backend/apps/nest/models/user_badge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""A model representing badges linked to users (GitHub user entity)."""

from __future__ import annotations

from django.db import models

from apps.common.models import BulkSaveModel, TimestampedModel


class UserBadge(BulkSaveModel, TimestampedModel):
"""Represents a user badge relation."""

class Meta:
db_table = "nest_user_badges"
verbose_name_plural = "User badges"
constraints = [
models.UniqueConstraint(
fields=["user", "badge"],
name="uq_userbadge_user_badge",
),
]

note = models.CharField(
verbose_name="Note",
max_length=255,
blank=True,
default="",
help_text="Optional note of the user badge.",
)

# FKs.
badge = models.ForeignKey(
"nest.Badge",
related_name="users",
on_delete=models.CASCADE,
verbose_name="Badge",
)
user = models.ForeignKey(
"github.User",
related_name="badges",
on_delete=models.CASCADE,
verbose_name="User",
)

def __str__(self) -> str:
"""Return a human-readable representation of the user badge."""
return f"{self.user.login} - {self.badge.name}"
Empty file.
Empty file.
Loading