Skip to content

Commit c7129e2

Browse files
authored
Merge branch 'main' into feature/Fix-map-borders-on-Chapter-and-Main-page
2 parents a50b01d + f623fc9 commit c7129e2

209 files changed

Lines changed: 2731 additions & 1703 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/run-ci-cd.yaml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,8 @@ jobs:
300300
- name: Prepare secrets
301301
run: |
302302
# Backend
303-
echo "DJANGO_ALGOLIA_APPLICATION_ID=${{ secrets.DJANGO_ALGOLIA_APPLICATION_ID }}" > .env.backend
304-
echo "DJANGO_ALGOLIA_APPLICATION_REGION=${{ secrets.DJANGO_ALGOLIA_APPLICATION_REGION }}" >> .env.backend
303+
touch .env.backend
304+
echo "DJANGO_ALGOLIA_APPLICATION_ID=${{ secrets.DJANGO_ALGOLIA_APPLICATION_ID }}" >> .env.backend
305305
echo "DJANGO_ALGOLIA_WRITE_API_KEY=${{ secrets.DJANGO_ALGOLIA_WRITE_API_KEY }}" >> .env.backend
306306
echo "DJANGO_ALLOWED_HOSTS=${{ secrets.DJANGO_ALLOWED_HOSTS }}" >> .env.backend
307307
echo "DJANGO_AWS_ACCESS_KEY_ID=${{ secrets.DJANGO_AWS_ACCESS_KEY_ID }}" >> .env.backend
@@ -322,7 +322,8 @@ jobs:
322322
echo "GITHUB_TOKEN=${{ secrets.DJANGO_GITHUB_TOKEN }}" >> .env.backend
323323
324324
# Database
325-
echo "POSTGRES_DB=${{ secrets.DJANGO_DB_NAME }}" > .env.db
325+
touch .env.db
326+
echo "POSTGRES_DB=${{ secrets.DJANGO_DB_NAME }}" >> .env.db
326327
echo "POSTGRES_PASSWORD=${{ secrets.DJANGO_DB_PASSWORD }}" >> .env.db
327328
echo "POSTGRES_USER=${{ secrets.DJANGO_DB_USER }}" >> .env.db
328329
@@ -398,6 +399,7 @@ jobs:
398399

399400
- name: Prepare frontend environment
400401
run: |
402+
touch frontend/.env
401403
echo "VITE_API_URL=${{ secrets.VITE_API_URL }}" >> frontend/.env
402404
echo "VITE_ENVIRONMENT=${{ secrets.VITE_ENVIRONMENT }}" >> frontend/.env
403405
echo "VITE_GRAPHQL_URL=${{ secrets.VITE_GRAPHQL_URL }}" >> frontend/.env
@@ -442,8 +444,8 @@ jobs:
442444
- name: Prepare secrets
443445
run: |
444446
# Backend
445-
echo "DJANGO_ALGOLIA_APPLICATION_ID=${{ secrets.DJANGO_ALGOLIA_APPLICATION_ID }}" > .env.backend
446-
echo "DJANGO_ALGOLIA_APPLICATION_REGION=${{ secrets.DJANGO_ALGOLIA_APPLICATION_REGION }}" >> .env.backend
447+
touch .env.backend
448+
echo "DJANGO_ALGOLIA_APPLICATION_ID=${{ secrets.DJANGO_ALGOLIA_APPLICATION_ID }}" >> .env.backend
447449
echo "DJANGO_ALGOLIA_WRITE_API_KEY=${{ secrets.DJANGO_ALGOLIA_WRITE_API_KEY }}" >> .env.backend
448450
echo "DJANGO_ALLOWED_HOSTS=${{ secrets.DJANGO_ALLOWED_HOSTS }}" >> .env.backend
449451
echo "DJANGO_AWS_ACCESS_KEY_ID=${{ secrets.DJANGO_AWS_ACCESS_KEY_ID }}" >> .env.backend
@@ -464,7 +466,8 @@ jobs:
464466
echo "GITHUB_TOKEN=${{ secrets.DJANGO_GITHUB_TOKEN }}" >> .env.backend
465467
466468
# Database
467-
echo "POSTGRES_DB=${{ secrets.DJANGO_DB_NAME }}" > .env.db
469+
touch .env.db
470+
echo "POSTGRES_DB=${{ secrets.DJANGO_DB_NAME }}" >> .env.db
468471
echo "POSTGRES_PASSWORD=${{ secrets.DJANGO_DB_PASSWORD }}" >> .env.db
469472
echo "POSTGRES_USER=${{ secrets.DJANGO_DB_USER }}" >> .env.db
470473

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ __pycache__
1010
.mypy_cache
1111
.npm/
1212
.pnpm-store/
13+
.psql_history
1314
.pytest_cache
1415
.python_history
1516
.python-version

backend/.env.example

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
DJANGO_ALGOLIA_APPLICATION_ID=None
2-
DJANGO_ALGOLIA_APPLICATION_REGION=None
32
DJANGO_ALGOLIA_EXCLUDED_LOCAL_INDEX_NAMES=None
43
DJANGO_ALGOLIA_WRITE_API_KEY=None
54
DJANGO_ALLOWED_HOSTS=*

backend/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enrich-data: \
2222
github-enrich-issues \
2323
owasp-enrich-chapters \
2424
owasp-enrich-committees \
25+
owasp-enrich-events \
2526
owasp-enrich-projects
2627

2728
generate-sitemap:
@@ -70,6 +71,10 @@ owasp-enrich-committees:
7071
@echo "Enriching OWASP committees"
7172
@CMD="python manage.py owasp_enrich_committees" $(MAKE) exec-backend-command
7273

74+
owasp-enrich-events:
75+
@echo "Enriching OWASP events"
76+
@CMD="python manage.py owasp_enrich_events" $(MAKE) exec-backend-command
77+
7378
owasp-enrich-projects:
7479
@echo "Enriching OWASP projects"
7580
@CMD="python manage.py owasp_enrich_projects" $(MAKE) exec-backend-command
@@ -98,6 +103,9 @@ owasp-scrape-projects:
98103
@echo "Scraping OWASP site projects data"
99104
@CMD="python manage.py owasp_scrape_projects" $(MAKE) exec-backend-command
100105

106+
owasp-sync-posts:
107+
@CMD="python manage.py owasp_sync_posts" $(MAKE) exec-backend-command-it
108+
101109
owasp-update-events:
102110
@echo "Getting OWASP events data"
103111
@CMD="python manage.py owasp_update_events" $(MAKE) exec-backend-command

backend/apps/common/constants.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Common app constants."""
22

33
NL = "\n"
4-
OWASP_NEWS_URL = "https://owasp.org/news/"
4+
OWASP_BLOG_URL = "https://owasp.org/blog"
5+
OWASP_NEWS_URL = "https://owasp.org/news"
56
OWASP_WEBSITE_URL = "https://owasp.org"
67
TAB = "\t"

backend/apps/core/api/algolia.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
from algoliasearch.http.exceptions import AlgoliaException
77
from django.conf import settings
88
from django.core.cache import cache
9+
from django.core.exceptions import ValidationError
910
from django.http import JsonResponse
1011

1112
from apps.common.index import IndexBase
1213
from apps.common.utils import get_user_ip_address
1314
from apps.core.utils.params_mapping import get_params_for_index
15+
from apps.core.validators import validate_search_params
1416

1517
CACHE_PREFIX = "algolia_proxy"
1618
CACHE_TTL_IN_SECONDS = 3600 # 1 hour
@@ -50,11 +52,16 @@ def algolia_search(request):
5052
try:
5153
data = json.loads(request.body)
5254

55+
try:
56+
validate_search_params(data)
57+
except ValidationError as error:
58+
return JsonResponse({"error": error.message}, status=400)
59+
5360
facet_filters = data.get("facetFilters", [])
5461
index_name = data.get("indexName")
5562
ip_address = get_user_ip_address(request)
56-
limit = int(data.get("hitsPerPage", 25))
57-
page = int(data.get("page", 1))
63+
limit = data.get("hitsPerPage", 25)
64+
page = data.get("page", 1)
5865
query = data.get("query", "")
5966

6067
cache_key = f"{CACHE_PREFIX}:{index_name}:{query}:{page}:{limit}"

backend/apps/core/models/prompt.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ def get_owasp_committee_summary():
7171
"""Return OWASP committee summary prompt."""
7272
return Prompt.get_text("owasp-committee-summary")
7373

74+
@staticmethod
75+
def get_owasp_event_suggested_location():
76+
"""Return OWASP event suggested location prompt."""
77+
return Prompt.get_text("owasp-event-suggested-location")
78+
79+
@staticmethod
80+
def get_owasp_event_summary():
81+
"""Return OWASP event summary prompt."""
82+
return Prompt.get_text("owasp-event-summary")
83+
7484
@staticmethod
7585
def get_owasp_project_summary():
7686
"""Return OWASP project summary prompt."""

backend/apps/core/validators.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"""Validators for the search parameters of the Algolia endpoint."""
2+
3+
import re
4+
5+
from django.core.exceptions import ValidationError
6+
from django.core.validators import validate_slug
7+
8+
9+
def validate_index_name(index_name):
10+
"""Validate index name."""
11+
if not index_name or not isinstance(index_name, str):
12+
message = "indexName is required and must be a string."
13+
raise ValidationError(message)
14+
15+
try:
16+
validate_slug(index_name)
17+
except ValidationError:
18+
message = (
19+
"Invalid indexName value provided. "
20+
"Only alphanumeric characters hyphens and underscores are allowed."
21+
)
22+
raise ValidationError(message) from None
23+
24+
25+
def validate_limit(limit):
26+
"""Validate limit."""
27+
if not isinstance(limit, int):
28+
message = "hitsPerPage must be an integer."
29+
raise ValidationError(message)
30+
31+
min_limit = 1
32+
max_limit = 1000
33+
if limit < min_limit or limit > max_limit:
34+
message = "hitsPerPage value must be between 1 and 1000."
35+
raise ValidationError(message)
36+
37+
38+
def validate_page(page):
39+
"""Validate page."""
40+
if not isinstance(page, int):
41+
message = "page value must be an integer."
42+
raise ValidationError(message)
43+
44+
if page <= 0:
45+
message = "page value must be a positive integer."
46+
raise ValidationError(message)
47+
48+
49+
def validate_query(query):
50+
"""Validate query."""
51+
if not query:
52+
return
53+
54+
if not isinstance(query, str):
55+
message = "query must be a string."
56+
raise ValidationError(message)
57+
58+
if not re.match(r"^[a-zA-Z0-9-_ ]*$", query):
59+
message = (
60+
"Invalid query value provided. "
61+
"Only alphanumeric characters, hyphens, spaces, and underscores are allowed."
62+
)
63+
raise ValidationError(message)
64+
65+
66+
def validate_facet_filters(facet_filters):
67+
"""Validate facet filters."""
68+
if not isinstance(facet_filters, list):
69+
message = "facetFilters must be a list."
70+
raise ValidationError(message)
71+
72+
73+
def validate_search_params(data):
74+
"""Validate search parameters."""
75+
validate_facet_filters(data.get("facetFilters", []))
76+
validate_index_name(data.get("indexName"))
77+
validate_limit(data.get("hitsPerPage", 25))
78+
validate_page(data.get("page", 1))
79+
validate_query(data.get("query", ""))

backend/apps/github/graphql/queries/release.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ class ReleaseQuery(BaseQuery):
1414

1515
def resolve_recent_releases(root, info, limit):
1616
"""Resolve recent release."""
17-
return Release.objects.order_by("-created_at")[:limit]
17+
return Release.objects.filter(
18+
is_draft=False,
19+
is_pre_release=False,
20+
published_at__isnull=False,
21+
).order_by("-published_at")[:limit]

backend/apps/github/models/repository.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ def project(self):
129129
@property
130130
def published_releases(self):
131131
"""Return published releases."""
132-
return self.releases.filter(is_draft=False, published_at__isnull=False)
132+
return self.releases.filter(
133+
is_draft=False,
134+
is_pre_release=False,
135+
published_at__isnull=False,
136+
)
133137

134138
@property
135139
def top_languages(self):

0 commit comments

Comments
 (0)