@@ -45,10 +45,10 @@
{% if not request.user.is_authenticated %}
- Already have an account?
Log in here
+ Already have an account?
Log in here
{% endif %}
@@ -63,4 +63,4 @@
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/ctfpad/templatetags/__init__.py b/ctfhub/templatetags/__init__.py
similarity index 100%
rename from ctfpad/templatetags/__init__.py
rename to ctfhub/templatetags/__init__.py
diff --git a/ctfpad/templatetags/ctfpad_filters.py b/ctfhub/templatetags/ctfhub_filters.py
similarity index 100%
rename from ctfpad/templatetags/ctfpad_filters.py
rename to ctfhub/templatetags/ctfhub_filters.py
diff --git a/ctfpad/tests.py b/ctfhub/tests.py
similarity index 100%
rename from ctfpad/tests.py
rename to ctfhub/tests.py
diff --git a/ctfpad/urls.py b/ctfhub/urls.py
similarity index 98%
rename from ctfpad/urls.py
rename to ctfhub/urls.py
index e1af939..3988d15 100644
--- a/ctfpad/urls.py
+++ b/ctfhub/urls.py
@@ -1,12 +1,11 @@
-from django.urls import path
+from ctfhub import views
from django.conf import settings
from django.conf.urls.static import static
-from django.views.generic.base import RedirectView
from django.contrib.staticfiles.storage import staticfiles_storage
+from django.urls import path
+from django.views.generic.base import RedirectView
-from ctfpad import views
-
-app_name = "ctfpad"
+app_name = "ctfhub"
urlpatterns = [
# /
@@ -51,7 +50,7 @@
views.users.MemberMarkAsSelectedView.as_view(),
name="users-select",
),
- path("users/login/", views.users.CtfpadLogin.as_view(), name="user-login"),
+ path("users/login/", views.users.CtfhubLogin.as_view(), name="user-login"),
path("users/logout/", views.users.logout, name="user-logout"),
path(
"users/reset/",
diff --git a/ctfpad/validators.py b/ctfhub/validators.py
similarity index 81%
rename from ctfpad/validators.py
rename to ctfhub/validators.py
index 3ce1189..c390215 100644
--- a/ctfpad/validators.py
+++ b/ctfhub/validators.py
@@ -1,6 +1,6 @@
from django.core.exceptions import ValidationError
-from ctftools.settings import CHALLENGE_FILE_MAX_SIZE
+from ctfhub_project.settings import CHALLENGE_FILE_MAX_SIZE
def challenge_file_max_size_validator(value):
diff --git a/ctfpad/views/__init__.py b/ctfhub/views/__init__.py
similarity index 84%
rename from ctfpad/views/__init__.py
rename to ctfhub/views/__init__.py
index 5b7238c..2676b30 100644
--- a/ctfpad/views/__init__.py
+++ b/ctfhub/views/__init__.py
@@ -1,6 +1,7 @@
import datetime
from typing import Optional
+from ctfhub.decorators import user
from django.contrib import messages
from django.core.paginator import Paginator
from django.http.request import HttpRequest
@@ -8,24 +9,8 @@
from django.shortcuts import redirect, render
from django.urls.base import reverse
-from ctfpad.decorators import user
-
-from ..models import (
- CtfStats,
- Member,
- SearchEngine,
- Team,
-)
-
-from . import (
- categories,
- challenges,
- ctfs,
- files,
- tags,
- teams,
- users,
-)
+from ..models import CtfStats, Member, SearchEngine, Team
+from . import categories, challenges, ctfs, files, tags, teams, users
def index(request: HttpRequest) -> HttpResponse:
@@ -34,17 +19,17 @@ def index(request: HttpRequest) -> HttpResponse:
"""
teams = Team.objects.all()
if teams.count() == 0:
- return redirect("ctfpad:team-register")
+ return redirect("ctfhub:team-register")
if Member.objects.all().count() == 0:
- return redirect("ctfpad:users-register")
+ return redirect("ctfhub:users-register")
- return redirect("ctfpad:dashboard")
+ return redirect("ctfhub:dashboard")
@user.is_authenticated
def dashboard(request: HttpRequest) -> HttpResponse:
- """Dashboard view: contains basic summary of all the info in the ctfpad
+ """Dashboard view: contains basic summary of all the info in the ctfhub
Args:
request (HttpRequest): [description]
@@ -81,12 +66,12 @@ def dashboard(request: HttpRequest) -> HttpResponse:
"next_ctf": next_ctf,
"nb_ctf_played": nb_ctf_played,
}
- return render(request, "ctfpad/dashboard/dashboard.html", context)
+ return render(request, "ctfhub/dashboard/dashboard.html", context)
@user.is_authenticated
def generate_stats(request: HttpRequest, year: Optional[int] = None) -> HttpResponse:
- """Generate some statistics of the CTFPad
+ """Generate some statistics of the CTFHub
Args:
request (HttpRequest): [description]
@@ -95,7 +80,7 @@ def generate_stats(request: HttpRequest, year: Optional[int] = None) -> HttpResp
HttpResponse: [description]
"""
if not year:
- return redirect("ctfpad:stats-detail", year=datetime.datetime.now().year)
+ return redirect("ctfhub:stats-detail", year=datetime.datetime.now().year)
stats = CtfStats(year)
context = {
@@ -108,7 +93,7 @@ def generate_stats(request: HttpRequest, year: Optional[int] = None) -> HttpResp
"year_stats": stats.year_stats(),
"year_pick": year,
}
- return render(request, "ctfpad/stats/detail.html", context)
+ return render(request, "ctfhub/stats/detail.html", context)
@user.is_authenticated
@@ -124,7 +109,7 @@ def search(request: HttpRequest) -> HttpResponse:
q = request.GET.get("q")
if not q:
messages.warning(request, f"No search pattern given")
- return redirect("ctfpad:dashboard")
+ return redirect("ctfhub:dashboard")
search = SearchEngine(q)
paginator = Paginator(search.results, 25)
@@ -151,7 +136,7 @@ def toggle_dark_mode(request: HttpRequest) -> HttpResponse:
HttpResponse: [description]
"""
val = request.POST.get("darkModeCookie")
- redirect_to = request.META.get("HTTP_REFERER") or reverse("ctfpad:dashboard")
+ redirect_to = request.META.get("HTTP_REFERER") or reverse("ctfhub:dashboard")
res = redirect(redirect_to)
if val:
res.set_cookie("theme", "dark")
diff --git a/ctfpad/views/categories.py b/ctfhub/views/categories.py
similarity index 84%
rename from ctfpad/views/categories.py
rename to ctfhub/views/categories.py
index ad2514a..f9cfb0e 100644
--- a/ctfpad/views/categories.py
+++ b/ctfhub/views/categories.py
@@ -1,19 +1,18 @@
-from ctfpad.mixins import MembersOnlyMixin
+from ctfhub.forms import CategoryCreateForm
+from ctfhub.mixins import MembersOnlyMixin
+from ctfhub.models import ChallengeCategory
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.shortcuts import render
from django.urls.base import reverse
from django.views.generic.edit import CreateView
-from ctfpad.forms import CategoryCreateForm
-from ctfpad.models import ChallengeCategory
-
class CategoryCreateView(
LoginRequiredMixin, MembersOnlyMixin, SuccessMessageMixin, CreateView
):
model = ChallengeCategory
- template_name = "ctfpad/categories/create.html"
+ template_name = "ctfhub/categories/create.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
form_class = CategoryCreateForm
@@ -34,6 +33,6 @@ def form_valid(self, form: CategoryCreateForm):
def get_success_url(self):
redirect_to = self.request.META.get("HTTP_REFERER") or reverse(
- "ctfpad:dashboard"
+ "ctfhub:dashboard"
)
return redirect_to
diff --git a/ctfpad/views/challenges.py b/ctfhub/views/challenges.py
similarity index 85%
rename from ctfpad/views/challenges.py
rename to ctfhub/views/challenges.py
index 021d12f..173f188 100644
--- a/ctfpad/views/challenges.py
+++ b/ctfhub/views/challenges.py
@@ -1,3 +1,12 @@
+from ctfhub.forms import (
+ ChallengeCreateForm,
+ ChallengeFileCreateForm,
+ ChallengeImportForm,
+ ChallengeSetFlagForm,
+ ChallengeUpdateForm,
+)
+from ctfhub.helpers import export_challenge_note, generate_github_page_header
+from ctfhub.models import Challenge, ChallengeCategory, Ctf
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
@@ -8,37 +17,24 @@
CreateView,
DeleteView,
DetailView,
+ FormView,
ListView,
UpdateView,
)
-from django.views.generic import FormView
-from ctfpad.forms import (
- ChallengeCreateForm,
- ChallengeFileCreateForm,
- ChallengeSetFlagForm,
- ChallengeUpdateForm,
- ChallengeImportForm,
-)
-from ctfpad.helpers import (
- export_challenge_note,
- generate_github_page_header,
-)
-from ctfpad.models import Challenge, Ctf
-from ctfpad.models import ChallengeCategory
-from ctftools.settings import HEDGEDOC_URL
+from ctfhub_project.settings import HEDGEDOC_URL
class ChallengeListView(LoginRequiredMixin, ListView):
model = Challenge
- template_name = "ctfpad/challenges/list.html"
+ template_name = "ctfhub/challenges/list.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
class ChallengeCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = Challenge
- template_name = "ctfpad/challenges/create.html"
+ template_name = "ctfhub/challenges/create.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
form_class = ChallengeCreateForm
@@ -75,12 +71,12 @@ def form_valid(self, form):
return super().form_valid(form)
def get_success_url(self):
- return reverse("ctfpad:challenges-detail", kwargs={"pk": self.object.pk})
+ return reverse("ctfhub:challenges-detail", kwargs={"pk": self.object.pk})
class ChallengeImportView(LoginRequiredMixin, FormView):
model = Challenge
- template_name = "ctfpad/challenges/import.html"
+ template_name = "ctfhub/challenges/import.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
form_class = ChallengeImportForm
@@ -131,12 +127,12 @@ def form_valid(self, form):
return self.form_invalid(form)
def get_success_url(self):
- return reverse("ctfpad:ctfs-detail", kwargs={"pk": self.initial["ctf"]})
+ return reverse("ctfhub:ctfs-detail", kwargs={"pk": self.initial["ctf"]})
class ChallengeDetailView(LoginRequiredMixin, DetailView):
model = Challenge
- template_name = "ctfpad/challenges/detail.html"
+ template_name = "ctfhub/challenges/detail.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
@@ -154,13 +150,13 @@ def get_context_data(self, **kwargs):
class ChallengeUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
model = Challenge
form_class = ChallengeUpdateForm
- template_name = "ctfpad/challenges/create.html"
+ template_name = "ctfhub/challenges/create.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
success_message = "Challenge successfully updated"
def get_success_url(self):
- return reverse("ctfpad:challenges-detail", kwargs={"pk": self.object.pk})
+ return reverse("ctfhub:challenges-detail", kwargs={"pk": self.object.pk})
def form_valid(self, form):
if "solvers" in form.cleaned_data:
@@ -168,22 +164,22 @@ def form_valid(self, form):
len(form.cleaned_data["solvers"]) > 0 and not form.cleaned_data["flag"]
) or (len(form.cleaned_data["solvers"]) == 0 and form.cleaned_data["flag"]):
messages.error(self.request, "Cannot set flag without solver(s)")
- return redirect("ctfpad:challenges-detail", self.object.id)
+ return redirect("ctfhub:challenges-detail", self.object.id)
return super().form_valid(form)
class ChallengeSetFlagView(ChallengeUpdateView):
form_class = ChallengeSetFlagForm
- template_name = "ctfpad/challenges/detail.html"
+ template_name = "ctfhub/challenges/detail.html"
def get_success_url(self):
- return reverse("ctfpad:challenges-detail", kwargs={"pk": self.object.pk})
+ return reverse("ctfhub:challenges-detail", kwargs={"pk": self.object.pk})
def form_valid(self, form):
if form.instance.ctf.is_finished:
messages.error(self.request, f"Cannot score when CTF is over")
- return redirect("ctfpad:challenges-detail", self.object.id)
+ return redirect("ctfhub:challenges-detail", self.object.id)
if form.instance.ctf.flag_prefix and "flag" in form.cleaned_data:
if not form.cleaned_data["flag"].startswith(form.instance.ctf.flag_prefix):
@@ -197,18 +193,18 @@ def form_valid(self, form):
class ChallengeDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
model = Challenge
- template_name = "ctfpad/challenges/confirm_delete.html"
+ template_name = "ctfhub/challenges/confirm_delete.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
success_message = "Challenge deleted successfully"
def get_success_url(self):
- return reverse("ctfpad:ctfs-detail", kwargs={"pk": self.object.ctf.id})
+ return reverse("ctfhub:ctfs-detail", kwargs={"pk": self.object.ctf.id})
class ChallengeExportAsGithubPageView(LoginRequiredMixin, DetailView):
model = Challenge
- template_name = "ctfpad/challenges/detail.html"
+ template_name = "ctfhub/challenges/detail.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
diff --git a/ctfpad/views/ctfs.py b/ctfhub/views/ctfs.py
similarity index 87%
rename from ctfpad/views/ctfs.py
rename to ctfhub/views/ctfs.py
index 5118ce7..104a2dd 100644
--- a/ctfpad/views/ctfs.py
+++ b/ctfhub/views/ctfs.py
@@ -1,37 +1,30 @@
-from ctfpad.mixins import MembersOnlyMixin
-from ctfpad.decorators import user
+from ctfhub.decorators import user
+from ctfhub.forms import CategoryCreateForm, CtfCreateUpdateForm, TagCreateForm
+from ctfhub.helpers import ctftime_ctfs, ctftime_get_ctf_info, ctftime_parse_date
+from ctfhub.mixins import MembersOnlyMixin
+from ctfhub.models import Ctf, Team
from django.contrib import messages
+from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
+from django.db.models import Q
from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.shortcuts import render
+from django.urls import reverse, reverse_lazy
from django.views.generic import (
- ListView,
+ CreateView,
+ DeleteView,
DetailView,
+ ListView,
UpdateView,
- DeleteView,
- CreateView,
)
-from django.urls import reverse, reverse_lazy
-from django.contrib.auth.mixins import LoginRequiredMixin
-from django.db.models import Q
-from ctftools.settings import (
- HEDGEDOC_URL,
-)
-
-from ctfpad.forms import (
- CategoryCreateForm,
- CtfCreateUpdateForm,
- TagCreateForm,
-)
-from ctfpad.models import Ctf, Team
-from ctfpad.helpers import ctftime_ctfs, ctftime_get_ctf_info, ctftime_parse_date
+from ctfhub_project.settings import HEDGEDOC_URL
class CtfListView(LoginRequiredMixin, MembersOnlyMixin, ListView):
model = Ctf
- template_name = "ctfpad/ctfs/list.html"
+ template_name = "ctfhub/ctfs/list.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
paginate_by = 25
@@ -53,7 +46,7 @@ class CtfCreateView(
LoginRequiredMixin, MembersOnlyMixin, SuccessMessageMixin, CreateView
):
model = Ctf
- template_name = "ctfpad/ctfs/create.html"
+ template_name = "ctfhub/ctfs/create.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
form_class = CtfCreateUpdateForm
@@ -93,7 +86,7 @@ def form_valid(self, form):
return super().form_valid(form)
def get_success_url(self):
- return reverse("ctfpad:ctfs-detail", kwargs={"pk": self.object.pk})
+ return reverse("ctfhub:ctfs-detail", kwargs={"pk": self.object.pk})
class CtfImportView(CtfCreateView):
@@ -122,7 +115,7 @@ def get(self, request, *args, **kwargs):
class CtfDetailView(LoginRequiredMixin, DetailView):
model = Ctf
- template_name = "ctfpad/ctfs/detail.html"
+ template_name = "ctfhub/ctfs/detail.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
extra_context = {
@@ -144,7 +137,7 @@ class CtfUpdateView(
):
model = Ctf
form_class = CtfCreateUpdateForm
- template_name = "ctfpad/ctfs/create.html"
+ template_name = "ctfhub/ctfs/create.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
success_message = "CTF '%(name)s' updated"
@@ -155,7 +148,7 @@ def get_context_data(self, **kwargs):
return ctx
def get_success_url(self):
- return reverse("ctfpad:ctfs-detail", kwargs={"pk": self.object.pk})
+ return reverse("ctfhub:ctfs-detail", kwargs={"pk": self.object.pk})
def form_valid(self, form):
if (
@@ -174,8 +167,8 @@ class CtfDeleteView(
LoginRequiredMixin, MembersOnlyMixin, SuccessMessageMixin, DeleteView
):
model = Ctf
- success_url = reverse_lazy("ctfpad:dashboard")
- template_name = "ctfpad/ctfs/confirm_delete.html"
+ success_url = reverse_lazy("ctfhub:dashboard")
+ template_name = "ctfhub/ctfs/confirm_delete.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
success_message = "CTF deleted"
@@ -183,7 +176,7 @@ class CtfDeleteView(
class CtfExportNotesView(LoginRequiredMixin, DetailView):
model = Ctf
- template_name = "ctfpad/ctfs/detail.html"
+ template_name = "ctfhub/ctfs/detail.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
diff --git a/ctfpad/views/files.py b/ctfhub/views/files.py
similarity index 77%
rename from ctfpad/views/files.py
rename to ctfhub/views/files.py
index e65c0d0..eb73f04 100644
--- a/ctfpad/views/files.py
+++ b/ctfhub/views/files.py
@@ -1,17 +1,17 @@
from pathlib import Path
-from django.shortcuts import render
-from django.urls import reverse
-from django.views.generic import DeleteView, CreateView, DetailView
+
+from ctfhub.forms import ChallengeFileCreateForm
+from ctfhub.models import ChallengeFile
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
-
-from ctfpad.forms import ChallengeFileCreateForm
-from ctfpad.models import ChallengeFile
+from django.shortcuts import render
+from django.urls import reverse
+from django.views.generic import CreateView, DeleteView, DetailView
class ChallengeFileCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = ChallengeFile
- template_name = "ctfpad/challenges/files/create.html"
+ template_name = "ctfhub/challenges/files/create.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
form_class = ChallengeFileCreateForm
@@ -19,20 +19,20 @@ class ChallengeFileCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateVie
def get_success_url(self):
return reverse(
- "ctfpad:challenges-detail", kwargs={"pk": self.object.challenge.id}
+ "ctfhub:challenges-detail", kwargs={"pk": self.object.challenge.id}
)
class ChallengeFileDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
model = ChallengeFile
- template_name = "ctfpad/challenges/files/confirm_delete.html"
+ template_name = "ctfhub/challenges/files/confirm_delete.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
success_message = "File deleted!"
def get_success_url(self):
return reverse(
- "ctfpad:challenges-detail", kwargs={"pk": self.object.challenge.id}
+ "ctfhub:challenges-detail", kwargs={"pk": self.object.challenge.id}
)
def post(self, request, *args, **kwargs):
@@ -46,7 +46,7 @@ def post(self, request, *args, **kwargs):
class ChallengeFileDetailView(LoginRequiredMixin, SuccessMessageMixin, DetailView):
model = ChallengeFile
- template_name = "ctfpad/challenges/files/detail.html"
+ template_name = "ctfhub/challenges/files/detail.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
initial = {}
diff --git a/ctfpad/views/tags.py b/ctfhub/views/tags.py
similarity index 79%
rename from ctfpad/views/tags.py
rename to ctfhub/views/tags.py
index 47ebf38..ed0b69a 100644
--- a/ctfpad/views/tags.py
+++ b/ctfhub/views/tags.py
@@ -1,17 +1,16 @@
-from ctfpad.mixins import MembersOnlyMixin
+from ctfhub.forms import TagCreateForm
+from ctfhub.mixins import MembersOnlyMixin
+from ctfhub.models import Tag
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.shortcuts import render
from django.urls.base import reverse, reverse_lazy
-from django.views.generic import ListView, CreateView, DeleteView
-
-from ctfpad.forms import TagCreateForm
-from ctfpad.models import Tag
+from django.views.generic import CreateView, DeleteView, ListView
class TagCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = Tag
- template_name = "ctfpad/tags/create.html"
+ template_name = "ctfhub/tags/create.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
form_class = TagCreateForm
@@ -30,14 +29,14 @@ def form_valid(self, form):
def get_success_url(self):
redirect_to = self.request.META.get("HTTP_REFERER") or reverse(
- "ctfpad:dashboard"
+ "ctfhub:dashboard"
)
return redirect_to
class TagListView(LoginRequiredMixin, MembersOnlyMixin, ListView):
model = Tag
- template_name = "ctfpad/tags/list.html"
+ template_name = "ctfhub/tags/list.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
@@ -53,8 +52,8 @@ class TagDeleteView(
LoginRequiredMixin, MembersOnlyMixin, SuccessMessageMixin, DeleteView
):
model = Tag
- template_name = "ctfpad/tags/confirm_delete.html"
+ template_name = "ctfhub/tags/confirm_delete.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
success_message = "Tag deleted successfully"
- success_url = reverse_lazy("ctfpad:tags-list")
+ success_url = reverse_lazy("ctfhub:tags-list")
diff --git a/ctfpad/views/teams.py b/ctfhub/views/teams.py
similarity index 81%
rename from ctfpad/views/teams.py
rename to ctfhub/views/teams.py
index 2abb570..eaadc70 100644
--- a/ctfpad/views/teams.py
+++ b/ctfhub/views/teams.py
@@ -1,26 +1,25 @@
-from django.views.generic import UpdateView, DeleteView, CreateView
+from ctfhub.forms import TeamCreateUpdateForm
+from ctfhub.mixins import RequireSuperPowersMixin
+from ctfhub.models import Team
from django.contrib import messages
-from ctfpad.models import Team
-from ctfpad.forms import TeamCreateUpdateForm
-from django.shortcuts import redirect
+from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
+from django.shortcuts import redirect
from django.urls import reverse_lazy
-from django.contrib.auth.mixins import LoginRequiredMixin
-
-from ctfpad.mixins import RequireSuperPowersMixin
+from django.views.generic import CreateView, DeleteView, UpdateView
class TeamCreateView(SuccessMessageMixin, CreateView):
model = Team
template_name = "team/create.html"
form_class = TeamCreateUpdateForm
- success_url = reverse_lazy("ctfpad:dashboard")
+ success_url = reverse_lazy("ctfhub:dashboard")
success_message = "Team successfully created"
def dispatch(self, request, *args, **kwargs):
if Team.objects.all().count():
messages.error(self.request, "Only one team can be created")
- return redirect("ctfpad:home")
+ return redirect("ctfhub:home")
if request.method.lower() in self.http_method_names:
handler = getattr(
self, request.method.lower(), self.http_method_not_allowed
@@ -39,7 +38,7 @@ class TeamUpdateView(
LoginRequiredMixin, RequireSuperPowersMixin, SuccessMessageMixin, UpdateView
):
model = Team
- success_url = reverse_lazy("ctfpad:dashboard")
+ success_url = reverse_lazy("ctfhub:dashboard")
template_name = "team/edit.html"
login_url = "/users/login/"
form_class = TeamCreateUpdateForm
@@ -51,7 +50,7 @@ class TeamDeleteView(
LoginRequiredMixin, RequireSuperPowersMixin, SuccessMessageMixin, DeleteView
):
model = Team
- success_url = reverse_lazy("ctfpad:team-register")
+ success_url = reverse_lazy("ctfhub:team-register")
template_name = "team/confirm_delete.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
diff --git a/ctfpad/views/users.py b/ctfhub/views/users.py
similarity index 89%
rename from ctfpad/views/users.py
rename to ctfhub/views/users.py
index d4d5a04..ca3d26b 100644
--- a/ctfpad/views/users.py
+++ b/ctfhub/views/users.py
@@ -1,3 +1,13 @@
+from ctfhub.decorators import user
+from ctfhub.forms import (
+ MemberCreateForm,
+ MemberMarkAsSelectedForm,
+ MemberUpdateForm,
+ UserUpdateForm,
+)
+from ctfhub.helpers import get_random_string_128
+from ctfhub.mixins import RequireSuperPowersMixin
+from ctfhub.models import Member, Team
from django.contrib import auth, messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
@@ -21,19 +31,8 @@
UpdateView,
)
-from ctfpad.decorators import user
-from ctfpad.forms import (
- MemberCreateForm,
- MemberMarkAsSelectedForm,
- MemberUpdateForm,
- UserUpdateForm,
-)
-from ctfpad.helpers import get_random_string_128
-from ctfpad.mixins import RequireSuperPowersMixin
-from ctfpad.models import Member, Team
-
-class CtfpadLogin(LoginView):
+class CtfhubLogin(LoginView):
template_name = "users/login.html"
redirect_authenticated_user = False
redirect_field_name = "redirect_to"
@@ -50,12 +49,12 @@ def logout(request: HttpRequest) -> HttpResponse:
HttpResponse: [description]
"""
auth.logout(request)
- return redirect("ctfpad:home")
+ return redirect("ctfhub:home")
class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
model = User
- success_url = reverse_lazy("ctfpad:dashboard")
+ success_url = reverse_lazy("ctfhub:dashboard")
template_name = "users/edit_advanced.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
@@ -75,7 +74,7 @@ def form_valid(self, form: BaseModelForm) -> HttpResponse:
password = form.cleaned_data["current_password"]
if not self.request.user.check_password(password):
messages.error(self.request, "Incorrect password")
- return redirect("ctfpad:users-update-advanced", self.request.user.member.id)
+ return redirect("ctfhub:users-update-advanced", self.request.user.member.id)
return super().form_valid(form)
@@ -83,7 +82,7 @@ class UserPasswordUpdateView(
LoginRequiredMixin, SuccessMessageMixin, PasswordChangeView
):
model = User
- success_url = reverse_lazy("ctfpad:user-logout")
+ success_url = reverse_lazy("ctfhub:user-logout")
template_name = "users/edit_advanced_change_password.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
@@ -103,7 +102,7 @@ def form_valid(self, form):
teams = Team.objects.all()
if teams.count() == 0:
messages.error(self.request, "A team must be registered first!")
- return redirect("ctfpad:team-register")
+ return redirect("ctfhub:team-register")
# validate api_key
team = teams.first()
@@ -111,7 +110,7 @@ def form_valid(self, form):
messages.error(
self.request, f"The API key for team '{team.name}' is invalid"
)
- return redirect("ctfpad:home")
+ return redirect("ctfhub:home")
# validate user uniqueness
user_cnt = User.objects.all().count()
@@ -121,7 +120,7 @@ def form_valid(self, form):
messages.error(
self.request, "Username already exists, try logging in instead"
)
- return redirect("ctfpad:home")
+ return redirect("ctfhub:home")
# create the django user
user = User.objects.create_user(
@@ -145,13 +144,13 @@ def form_valid(self, form):
def get_success_url(self):
if User.objects.all().count() == 1:
- return reverse("ctfpad:user-login")
- return reverse("ctfpad:dashboard")
+ return reverse("ctfhub:user-login")
+ return reverse("ctfhub:dashboard")
class MemberUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
model = Member
- success_url = reverse_lazy("ctfpad:dashboard")
+ success_url = reverse_lazy("ctfhub:dashboard")
template_name = "users/edit.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
@@ -194,7 +193,7 @@ class MemberMarkAsSelectedView(MemberUpdateView):
form_class = MemberMarkAsSelectedForm
def get_success_url(self):
- return reverse("ctfpad:ctfs-detail", kwargs={"pk": self.object.selected_ctf.id})
+ return reverse("ctfhub:ctfs-detail", kwargs={"pk": self.object.selected_ctf.id})
def get_success_message(self, cleaned_data):
return f"CTF {cleaned_data['selected_ctf']} mark as Current"
@@ -204,7 +203,7 @@ class MemberDeleteView(
LoginRequiredMixin, RequireSuperPowersMixin, SuccessMessageMixin, DeleteView
):
model = Member
- success_url = reverse_lazy("ctfpad:dashboard")
+ success_url = reverse_lazy("ctfhub:dashboard")
template_name = "users/confirm_delete.html"
login_url = "/users/login/"
redirect_field_name = "redirect_to"
@@ -214,7 +213,7 @@ def post(self, request, *args, **kwargs):
member = self.get_object()
if member.has_superpowers:
messages.error(request, "Refusing to delete super-user")
- return redirect("ctfpad:home")
+ return redirect("ctfhub:home")
# rotate the team api key
t = Team.objects.first()
@@ -252,7 +251,7 @@ class UserResetPassword(SuccessMessageMixin, PasswordResetView):
model = User
template_name = "users/password_reset.html"
success_message = "If a match was found, an email will be received with the password reset procedure."
- success_url = reverse_lazy("ctfpad:user-login")
+ success_url = reverse_lazy("ctfhub:user-login")
email_template_name = "users/password_reset_email.txt"
subject_template_name = "users/password_reset_subject.txt"
title = "Password Reset"
@@ -262,5 +261,5 @@ class UserChangePassword(SuccessMessageMixin, PasswordResetConfirmView):
model = User
template_name = "users/password_change.html"
success_message = "Password successfully changed."
- success_url = reverse_lazy("ctfpad:user-login")
+ success_url = reverse_lazy("ctfhub:user-login")
title = "Password Reset"
diff --git a/ctftools/__init__.py b/ctfhub_project/__init__.py
similarity index 100%
rename from ctftools/__init__.py
rename to ctfhub_project/__init__.py
diff --git a/ctftools/asgi.py b/ctfhub_project/asgi.py
similarity index 71%
rename from ctftools/asgi.py
rename to ctfhub_project/asgi.py
index bf9d8c9..04bfb85 100644
--- a/ctftools/asgi.py
+++ b/ctfhub_project/asgi.py
@@ -1,5 +1,5 @@
"""
-ASGI config for ctftools project.
+ASGI config for ctfhub_project project.
It exposes the ASGI callable as a module-level variable named ``application``.
@@ -11,6 +11,6 @@
from django.core.asgi import get_asgi_application
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ctftools.settings")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ctfhub_project.settings")
application = get_asgi_application()
diff --git a/ctftools/settings.py b/ctfhub_project/settings.py
similarity index 65%
rename from ctftools/settings.py
rename to ctfhub_project/settings.py
index 79ff451..eba2604 100644
--- a/ctftools/settings.py
+++ b/ctfhub_project/settings.py
@@ -1,6 +1,4 @@
-import django
import os
-
from pathlib import Path
@@ -17,35 +15,35 @@ def get_boolean(key: str) -> bool:
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = (
- os.getenv("CTFPAD_SECRET_KEY")
+ os.getenv("CTFHUB_SECRET_KEY")
or "ow#8y081ih3nunjqh)u^ug)ln_$xri3-upt^e)7h)&l$05-7tf"
)
# SECURITY WARNING: don't run with debug turned on in production!
-DEBUG = get_boolean("CTFPAD_DEBUG") or False
+DEBUG = get_boolean("CTFHUB_DEBUG") or False
VERSION: float = 0.1
-CTFPAD_PROTOCOL = os.getenv("CTFPAD_PROTOCOL") or "http"
-CTFPAD_DOMAIN = os.getenv("CTFPAD_DOMAIN") or "localhost"
-CTFPAD_PORT = os.getenv("CTFPAD_PORT") or "8000"
-CTFPAD_USE_SSL = CTFPAD_PROTOCOL == "https" or False
-CTFPAD_URL = (
- os.getenv("CTFPAD_URL") or f"{CTFPAD_PROTOCOL}://{CTFPAD_DOMAIN}:{CTFPAD_PORT}"
+CTFHUB_PROTOCOL = os.getenv("CTFHUB_PROTOCOL") or "http"
+CTFHUB_DOMAIN = os.getenv("CTFHUB_DOMAIN") or "localhost"
+CTFHUB_PORT = os.getenv("CTFHUB_PORT") or "8000"
+CTFHUB_USE_SSL = CTFHUB_PROTOCOL == "https" or False
+CTFHUB_URL = (
+ os.getenv("CTFHUB_URL") or f"{CTFHUB_PROTOCOL}://{CTFHUB_DOMAIN}:{CTFHUB_PORT}"
)
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
# SECURITY WARNING: harden for production!
-ALLOWED_HOSTS = [CTFPAD_DOMAIN, "localhost", "127.0.0.1"]
-CSRF_TRUSTED_ORIGINS = ["http://127.0.0.1", CTFPAD_URL]
+ALLOWED_HOSTS = [CTFHUB_DOMAIN, "localhost", "127.0.0.1"]
+CSRF_TRUSTED_ORIGINS = ["http://127.0.0.1", CTFHUB_URL]
-CSRF_COOKIE_NAME = "ctfpad-csrf"
-SESSION_COOKIE_NAME = "ctfpad-session"
+CSRF_COOKIE_NAME = "ctfhub-csrf"
+SESSION_COOKIE_NAME = "ctfhub-session"
# Application definition
INSTALLED_APPS = [
- # 'django.contrib.admin',
+ "django_rename_app",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
@@ -54,7 +52,7 @@ def get_boolean(key: str) -> bool:
"django.contrib.humanize",
"django.contrib.sites",
"model_utils",
- "ctfpad",
+ "ctfhub",
]
SITE_ID = 1
@@ -70,7 +68,7 @@ def get_boolean(key: str) -> bool:
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
-ROOT_URLCONF = "ctftools.urls"
+ROOT_URLCONF = "ctfhub_project.urls"
TEMPLATES = [
{
@@ -85,13 +83,13 @@ def get_boolean(key: str) -> bool:
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
- "ctfpad.context_processors.add_debug_context",
+ "ctfhub.context_processors.add_debug_context",
],
},
},
]
-WSGI_APPLICATION = "ctftools.wsgi.application"
+WSGI_APPLICATION = "ctfhub_project.wsgi.application"
# Database
@@ -104,11 +102,11 @@ def get_boolean(key: str) -> bool:
# }
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
- "NAME": os.getenv("CTFPAD_DB_NAME") or "ctfpad",
- "USER": os.getenv("CTFPAD_DB_USER") or "ctfpad",
- "PASSWORD": os.getenv("CTFPAD_DB_PASSWORD"),
- "HOST": os.getenv("CTFPAD_DB_HOST") or "localhost",
- "PORT": os.getenv("CTFPAD_DB_PORT") or "5432",
+ "NAME": os.getenv("CTFHUB_DB_NAME") or "ctfhub",
+ "USER": os.getenv("CTFHUB_DB_USER") or "ctfhub",
+ "PASSWORD": os.getenv("CTFHUB_DB_PASSWORD"),
+ "HOST": os.getenv("CTFHUB_DB_HOST") or "localhost",
+ "PORT": os.getenv("CTFHUB_DB_PORT") or "5432",
}
}
@@ -161,8 +159,8 @@ def get_boolean(key: str) -> bool:
USERS_FILE_PATH = "media/"
USERS_FILE_ROOT = MEDIA_ROOT / USERS_FILE_PATH
-HEDGEDOC_URL = os.getenv("CTFPAD_HEDGEDOC_URL") or "http://localhost:3000"
-USE_INTERNAL_HEDGEDOC = get_boolean("CTFPAD_HEDGEDOC_IS_INTERNAL")
+HEDGEDOC_URL = os.getenv("CTFHUB_HEDGEDOC_URL") or "http://localhost:3000"
+USE_INTERNAL_HEDGEDOC = get_boolean("CTFHUB_HEDGEDOC_IS_INTERNAL")
CTFTIME_URL = "https://ctftime.org"
CTFTIME_API_EVENTS_URL = "https://ctftime.org/api/v1/events/"
@@ -170,7 +168,7 @@ def get_boolean(key: str) -> bool:
"Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0"
)
-LOGIN_REDIRECT_URL = "ctfpad:dashboard"
+LOGIN_REDIRECT_URL = "ctfhub:dashboard"
FILE_UPLOAD_MAX_MEMORY_SIZE = 2 * 1024 * 1024
CHALLENGE_FILE_MAX_SIZE = FILE_UPLOAD_MAX_MEMORY_SIZE
@@ -178,41 +176,45 @@ def get_boolean(key: str) -> bool:
SHORT_DATE_FORMAT = "Y-m-d"
SHORT_DATETIME_FORMAT = "Y-m-d P"
-CTFPAD_DEFAULT_CTF_LOGO = "blank-ctf.png"
-CTFPAD_ACCEPTED_IMAGE_EXTENSIONS = (".png", ".jpg", ".gif", ".bmp")
+CTFHUB_DEFAULT_CTF_LOGO = "blank-ctf.png"
+CTFHUB_ACCEPTED_IMAGE_EXTENSIONS = (".png", ".jpg", ".gif", ".bmp")
# EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
# EMAIL_FILE_PATH = MEDIA_ROOT / "email_sent"
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
-EMAIL_HOST = os.getenv("CTFPAD_EMAIL_SERVER_HOST") or None
-EMAIL_PORT = os.getenv("CTFPAD_EMAIL_SERVER_PORT") or 587
-EMAIL_USE_TLS = os.getenv("CTFPAD_EMAIL_SERVER_USE_TLS") or True
-EMAIL_HOST_USER = os.getenv("CTFPAD_EMAIL_USERNAME") or None
-EMAIL_HOST_PASSWORD = os.getenv("CTFPAD_EMAIL_PASSWORD") or None
-EMAIL_SUBJECT_PREFIX = "[CTFPad] "
+EMAIL_HOST = os.getenv("CTFHUB_EMAIL_SERVER_HOST") or None
+EMAIL_PORT = os.getenv("CTFHUB_EMAIL_SERVER_PORT") or 587
+EMAIL_USE_TLS = os.getenv("CTFHUB_EMAIL_SERVER_USE_TLS") or True
+EMAIL_HOST_USER = os.getenv("CTFHUB_EMAIL_USERNAME") or None
+EMAIL_HOST_PASSWORD = os.getenv("CTFHUB_EMAIL_PASSWORD") or None
+EMAIL_SUBJECT_PREFIX = "[CTFHub] "
# Jistsi integration
-JITSI_URL = os.getenv("CTFPAD_JITSI_URL") or "https://meet.jit.si"
+JITSI_URL = os.getenv("CTFHUB_JITSI_URL") or "https://meet.jit.si"
# Discord integration
-DISCORD_WEBHOOK_URL = os.getenv("CTFPAD_DISCORD_WEBHOOK_URL") or None
-DISCORD_BOT_NAME = os.getenv("CTFPAD_DISCORD_BOT_NAME") or "SpiderBot"
+DISCORD_WEBHOOK_URL = os.getenv("CTFHUB_DISCORD_WEBHOOK_URL") or None
+DISCORD_BOT_NAME = os.getenv("CTFHUB_DISCORD_BOT_NAME") or "SpiderBot"
CHARSET_HEXA_LOWER = "abcdef0123456789"
CHARSET_HEXA_UPPER = "ABCDEF0123456789"
+CHARSET_HEXA_MIXED = "abcdefABCDEF0123456789"
+CHARSET_ALNUM_LOWER = "abcdefghijklmnopqrstuvwxyz0123456789"
+CHARSET_ALNUM_UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+CHARSET_ALNUM_MIXED = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
# Excalidraw integration
-EXCALIDRAW_URL = os.getenv("CTFPAD_EXCALIDRAW_URL") or "https://excalidraw.com"
+EXCALIDRAW_URL = os.getenv("CTFHUB_EXCALIDRAW_URL") or "https://excalidraw.com"
EXCALIDRAW_ROOM_ID_REGEX = "[0-9a-f]{20}"
EXCALIDRAW_ROOM_KEY_REGEX = "[a-zA-Z0-9_-]{22}"
EXCALIDRAW_ROOM_ID_CHARSET = CHARSET_HEXA_LOWER
EXCALIDRAW_ROOM_ID_LENGTH = 20
-EXCALIDRAW_ROOM_KEY_CHARSET = django.utils.crypto.RANDOM_STRING_CHARS + "_-"
+EXCALIDRAW_ROOM_KEY_CHARSET = CHARSET_ALNUM_MIXED + "_-"
EXCALIDRAW_ROOM_KEY_LENGTH = 22
-CTFPAD_HTTP_REQUEST_DEFAULT_TIMEOUT = 60
+CTFHUB_HTTP_REQUEST_DEFAULT_TIMEOUT = 60
diff --git a/ctftools/urls.py b/ctfhub_project/urls.py
similarity index 90%
rename from ctftools/urls.py
rename to ctfhub_project/urls.py
index 5ea2ed7..e0a6e29 100644
--- a/ctftools/urls.py
+++ b/ctfhub_project/urls.py
@@ -1,4 +1,4 @@
-"""ctftools URL Configuration
+"""ctfhub_project URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
@@ -16,8 +16,7 @@
from django.contrib import admin
from django.urls import include, path
-
urlpatterns = [
# path('admin/', admin.site.urls),
- path("", include("ctfpad.urls")),
+ path("", include("ctfhub.urls")),
]
diff --git a/ctftools/wsgi.py b/ctfhub_project/wsgi.py
similarity index 71%
rename from ctftools/wsgi.py
rename to ctfhub_project/wsgi.py
index cd46bc0..d4f3533 100644
--- a/ctftools/wsgi.py
+++ b/ctfhub_project/wsgi.py
@@ -1,5 +1,5 @@
"""
-WSGI config for ctftools project.
+WSGI config for ctfhub_project project.
It exposes the WSGI callable as a module-level variable named ``application``.
@@ -11,6 +11,6 @@
from django.core.wsgi import get_wsgi_application
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ctftools.settings")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ctfhub_project.settings")
application = get_wsgi_application()
diff --git a/ctfpad/__init__.py b/ctfpad/__init__.py
deleted file mode 100644
index 1007dab..0000000
--- a/ctfpad/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-default_app_config = "ctfpad.apps.CtfpadConfig"
diff --git a/docker-compose.yml b/docker-compose.yml
index 130816e..730981d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -7,13 +7,13 @@ services:
env_file:
- .env
environment:
- - POSTGRES_DB=${CTFPAD_DB_NAME}
- - POSTGRES_USER=${CTFPAD_DB_USER}
- - POSTGRES_PASSWORD=${CTFPAD_DB_PASSWORD}
+ - POSTGRES_DB=${CTFHUB_DB_NAME}
+ - POSTGRES_USER=${CTFHUB_DB_USER}
+ - POSTGRES_PASSWORD=${CTFHUB_DB_PASSWORD}
volumes:
- postgres-vol:/var/lib/postgresql/data
networks:
- - ctfpad
+ - ctfhub
restart: always
hedgedoc:
@@ -23,16 +23,16 @@ services:
env_file:
- .env
environment:
- - CMD_DB_URL=postgres://${CTFPAD_DB_USER}:${CTFPAD_DB_PASSWORD}@${CTFPAD_DB_HOST}:${CTFPAD_DB_PORT}/${CTFPAD_DB_NAME}
+ - CMD_DB_URL=postgres://${CTFHUB_DB_USER}:${CTFHUB_DB_PASSWORD}@${CTFHUB_DB_HOST}:${CTFHUB_DB_PORT}/${CTFHUB_DB_NAME}
- CMD_ALLOW_ANONYMOUS=false
- CMD_ALLOW_FREEURL=true
- CMD_IMAGE_UPLOAD_TYPE=filesystem
- - CMD_DOMAIN=${CTFPAD_HEDGEDOC_DOMAIN}
- - CMD_PORT=${CTFPAD_HEDGEDOC_PORT}
+ - CMD_DOMAIN=${CTFHUB_HEDGEDOC_DOMAIN}
+ - CMD_PORT=${CTFHUB_HEDGEDOC_PORT}
- CMD_URL_ADDPORT=true
- CMD_PROTOCOL_USESSL=false
networks:
- - ctfpad
+ - ctfhub
ports:
- 3000:3000
restart: always
@@ -41,8 +41,8 @@ services:
volumes:
- ./volumes/upload/hedgedoc:/hedgedoc/public/uploads
- ctfpad:
- # build: https://github.com/hugsy/ctfpad.git#master
+ ctfhub:
+ # build: https://github.com/hugsy/ctfhub.git#master
build: .
command: python manage.py runserver 0.0.0.0:8000
links:
@@ -56,15 +56,15 @@ services:
ports:
- 8000:8000
networks:
- - ctfpad
+ - ctfhub
restart: always
volumes:
- - ./volumes/upload/ctfpad:/code/uploads
- - ./ctfpad:/code/ctfpad
- - ./ctftools:/code/ctftools
+ - ./volumes/upload/ctfhub:/code/uploads
+ - ./ctfhub:/code/ctfhub
+ - ./ctfhub_project:/code/ctfhub_project
networks:
- ctfpad:
+ ctfhub:
driver: bridge
volumes:
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
index 41493cc..c431b37 100644
--- a/docker-entrypoint.sh
+++ b/docker-entrypoint.sh
@@ -2,16 +2,16 @@
set -e
-echo "[CTFPad] Database initialization..."
+echo "[CTFHub] Database initialization..."
while psql -h db 2>&1 | grep -q 'could not connect to server'; do
>&2 echo "Waiting for PostgreSQL to boot up"
sleep 1
done
-echo "[CTFPad] Database setup: makemigrations..."
+echo "[CTFHub] Database setup: makemigrations..."
python3 manage.py makemigrations --noinput
-echo "[CTFPad] Database setup: migrate..."
+echo "[CTFHub] Database setup: migrate..."
python3 manage.py migrate --noinput
exec "$@"
diff --git a/manage.py b/manage.py
index ffdab07..09abb7b 100644
--- a/manage.py
+++ b/manage.py
@@ -6,7 +6,7 @@
def main():
"""Run administrative tasks."""
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ctftools.settings")
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ctfhub_project.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
diff --git a/requirements.txt b/requirements.txt
index 6098696..eb78544 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,3 +8,4 @@ bleach
pytz
pre-commit
black
+django-rename-app
diff --git a/scripts/excalidraw/docker-compose.yml b/scripts/excalidraw/docker-compose.yml
index e7e6e70..68cc628 100644
--- a/scripts/excalidraw/docker-compose.yml
+++ b/scripts/excalidraw/docker-compose.yml
@@ -10,7 +10,7 @@ services:
args:
- NODE_ENV=${EXCALIDRAW_NODE_ENV}
networks:
- - ctfpad
+ - ctfhub
- excalidraw
ports:
- 3001:80
diff --git a/scripts/proxy/.env.nginx-proxy.example b/scripts/proxy/.env.nginx-proxy.example
index 1873939..cfd0eb7 100644
--- a/scripts/proxy/.env.nginx-proxy.example
+++ b/scripts/proxy/.env.nginx-proxy.example
@@ -1,23 +1,23 @@
-# CTFpad
-CTFPAD_DEBUG=0 # Change here
-CTFPAD_HOSTNAME=ctfpad.mydomain.com # Change here to your server public IP / FQDN
-CTFPAD_PORT=443 # Change here to your server public port for CTFPad
-CTFPAD_USE_SSL=1 # Change here to 1 if your public server uses https
-CTFPAD_SECRET_KEY=74320c04549af3a5f9fd9bc007b2e20ced8 # Change here
+# CTFHub
+CTFHUB_DEBUG=0 # Change here
+CTFHUB_HOSTNAME=ctfhub.mydomain.com # Change here to your server public IP / FQDN
+CTFHUB_PORT=443 # Change here to your server public port for CTFHub
+CTFHUB_USE_SSL=1 # Change here to 1 if your public server uses https
+CTFHUB_SECRET_KEY=74320c04549af3a5f9fd9bc007b2e20ced8 # Change here
HEDGEDOC_URL=https://hedgedoc.mydomain.com # or set this to use nginx as a HTTPS reverse proxy
USE_INTERNAL_HEDGEDOC=1
EXCALIDRAW_URL=https://excalidraw.mydomain.com # Change here
# Left blank or customize below to enable the password recovery feature by email
-CTFPAD_EMAIL_SERVER_HOST= # smtp.gmail.com or mailgun, or sendgrid etc.
-CTFPAD_EMAIL_SERVER_PORT=587
-CTFPAD_EMAIL_USERNAME=
-CTFPAD_EMAIL_PASSWORD=
+CTFHUB_EMAIL_SERVER_HOST= # smtp.gmail.com or mailgun, or sendgrid etc.
+CTFHUB_EMAIL_SERVER_PORT=587
+CTFHUB_EMAIL_USERNAME=
+CTFHUB_EMAIL_PASSWORD=
# Left blanck or customize below to enable Discord webhook notifications
-CTFPAD_WEBHOOK_URL_DISCORD=
+CTFHUB_WEBHOOK_URL_DISCORD=
# Postgres
-POSTGRES_DB=ctfpad # (opt.) Change here
-POSTGRES_USER=ctfpad # (opt.) Change here
+POSTGRES_DB=ctfhub # (opt.) Change here
+POSTGRES_USER=ctfhub # (opt.) Change here
POSTGRES_PASSWORD=tookahlaiphee2KieTeeg5ooxutang4o # Change here
# Excalidraw stack
diff --git a/scripts/proxy/docker-compose.yml b/scripts/proxy/docker-compose.yml
index 674b33a..f400384 100644
--- a/scripts/proxy/docker-compose.yml
+++ b/scripts/proxy/docker-compose.yml
@@ -3,12 +3,12 @@ services:
nginx:
image: nginx:latest
networks:
- - ctfpad
+ - ctfhub
ports:
- 80:80
- 443:443
depends_on:
- - ctfpad
+ - ctfhub
- hedgedoc
- excalidraw
- excalidraw-room