diff options
| author | Bobby <[email protected]> | 2024-12-16 00:41:02 -0500 |
|---|---|---|
| committer | Bobby <[email protected]> | 2024-12-16 00:41:02 -0500 |
| commit | 04788ddd83c5e80a09a468d07427f0e365db71d7 (patch) | |
| tree | 5c33a8ba990f21c227dc97b5c76729a39cfe0c67 /apps | |
| parent | 5c14aa56c401915a99cf1c6f5700e8e3cb88453b (diff) | |
| download | thatcomputerscientist-04788ddd83c5e80a09a468d07427f0e365db71d7.tar.xz thatcomputerscientist-04788ddd83c5e80a09a468d07427f0e365db71d7.zip | |
pagoda realm
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/pagoda/admin.py | 3 | ||||
| -rw-r--r-- | apps/pagoda/apps.py | 2 | ||||
| -rw-r--r-- | apps/pagoda/migrations/0001_initial.py | 53 | ||||
| -rw-r--r-- | apps/pagoda/migrations/0002_rename_verficationrecordname_pagodasites_verficationrecordname_and_more.py | 29 | ||||
| -rw-r--r-- | apps/pagoda/models.py | 29 | ||||
| -rw-r--r-- | apps/pagoda/urls.py | 11 | ||||
| -rw-r--r-- | apps/pagoda/views.py | 186 |
7 files changed, 312 insertions, 1 deletions
diff --git a/apps/pagoda/admin.py b/apps/pagoda/admin.py index 8c38f3f3..94502d0f 100644 --- a/apps/pagoda/admin.py +++ b/apps/pagoda/admin.py @@ -1,3 +1,6 @@ from django.contrib import admin # Register your models here. +from apps.pagoda.models import PagodaSites + +admin.site.register(PagodaSites) diff --git a/apps/pagoda/apps.py b/apps/pagoda/apps.py index acc7a0eb..54a5ecdd 100644 --- a/apps/pagoda/apps.py +++ b/apps/pagoda/apps.py @@ -3,4 +3,4 @@ from django.apps import AppConfig class PagodaConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" - name = "pagoda" + name = "apps.pagoda" diff --git a/apps/pagoda/migrations/0001_initial.py b/apps/pagoda/migrations/0001_initial.py new file mode 100644 index 00000000..9ba0607e --- /dev/null +++ b/apps/pagoda/migrations/0001_initial.py @@ -0,0 +1,53 @@ +# Generated by Django 5.0.7 on 2024-12-16 02:41 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="PagodaSites", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=50)), + ("description", models.TextField(blank=True)), + ("url", models.URLField()), + ("verified", models.BooleanField(default=False)), + ("siteUniqueIdentifier", models.TextField(unique=True)), + ("VerficationRecordName", models.CharField(blank=True, max_length=50)), + ( + "VerificationRecordValue", + models.CharField(blank=True, max_length=50), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "owner", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name_plural": "Pagoda Sites", + "ordering": ["-created_at"], + }, + ), + ] diff --git a/apps/pagoda/migrations/0002_rename_verficationrecordname_pagodasites_verficationrecordname_and_more.py b/apps/pagoda/migrations/0002_rename_verficationrecordname_pagodasites_verficationrecordname_and_more.py new file mode 100644 index 00000000..2a22d9a4 --- /dev/null +++ b/apps/pagoda/migrations/0002_rename_verficationrecordname_pagodasites_verficationrecordname_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 5.0.7 on 2024-12-16 02:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("pagoda", "0001_initial"), + ] + + operations = [ + migrations.RenameField( + model_name="pagodasites", + old_name="VerficationRecordName", + new_name="verficationRecordName", + ), + migrations.RenameField( + model_name="pagodasites", + old_name="VerificationRecordValue", + new_name="verificationRecordValue", + ), + migrations.AddField( + model_name="pagodasites", + name="verificationMethod", + field=models.CharField( + choices=[("DNS", "DNS"), ("Meta", "Meta")], default="DNS", max_length=4 + ), + ), + ] diff --git a/apps/pagoda/models.py b/apps/pagoda/models.py index 71a83623..11657953 100644 --- a/apps/pagoda/models.py +++ b/apps/pagoda/models.py @@ -1,3 +1,32 @@ from django.db import models +from django.conf import settings + # Create your models here. +class PagodaSites(models.Model): + owner = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + ) + name = models.CharField(max_length=50) + description = models.TextField(blank=True) + url = models.URLField() + verified = models.BooleanField(default=False) + siteUniqueIdentifier = models.TextField(unique=True) + verificationMethod = models.CharField( + max_length=4, choices=((x, x) for x in ["DNS", "Meta"]), default="DNS" + ) + verficationRecordName = models.CharField(max_length=50, blank=True) + verificationRecordValue = models.CharField(max_length=50, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return self.name + + def get_sites_created_by_user(user): + return PagodaSites.objects.filter(owner=user) + + class Meta: + verbose_name_plural = "Pagoda Sites" + ordering = ["-created_at"] diff --git a/apps/pagoda/urls.py b/apps/pagoda/urls.py new file mode 100644 index 00000000..1ca11d2d --- /dev/null +++ b/apps/pagoda/urls.py @@ -0,0 +1,11 @@ +from django.urls import path + +from . import views + +app_name = "pagoda" +urlpatterns = [ + path("", views.home, name="home"), + path("m/<str:site_id>", views.site_dashboard, name="site"), + path("m/<str:site_id>/status", views.check_verification_status, name="site_status"), + path("m/<str:site_id>/delete", views.delete_site, name="delete_site"), +] diff --git a/apps/pagoda/views.py b/apps/pagoda/views.py index 91ea44a2..ad8f3079 100644 --- a/apps/pagoda/views.py +++ b/apps/pagoda/views.py @@ -1,3 +1,189 @@ from django.shortcuts import render +from thatcomputerscientist.utils import i18npatterns +from apps.pagoda.models import PagodaSites +from django.contrib.auth.decorators import login_required +from internal.pagoda_utilities import ( + pagoda_unique_site_id_generator, + pagoda_verification_record_generator, + pagoda_url_sanitizer, +) +from django.http import Http404, HttpResponseRedirect +from django.urls import reverse +from django.contrib import messages +import dns.resolver +import requests +from bs4 import BeautifulSoup + # Create your views here. +@login_required +def home(request): + META = { + "title": "The Pagoda Realm", + } + LANGUAGE_CODE = i18npatterns(request.LANGUAGE_CODE) + request.meta.update(META) + + pagoda_sites = PagodaSites.get_sites_created_by_user(request.user) + if request.method == "GET": + context = { + "pagoda_sites": pagoda_sites, + } + return render(request, f"{LANGUAGE_CODE}/pagoda/home.html", context) + elif request.method == "POST": + name = request.POST.get("site_name") + url = request.POST.get("root_url") + url = pagoda_url_sanitizer(url) + verificationMethod = request.POST.get("verification_method") + siteUniqueIdentifier = pagoda_unique_site_id_generator() + verficationRecordName, verificationRecordValue = ( + pagoda_verification_record_generator(verificationMethod) + ) + if not url: + messages.error( + request, + "The URL provided is not valid. Please provide a valid URL.", + extra_tags="pagodaError", + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER")) + + if url.replace("http://", "").replace("https://", "") in [ + site.url.replace("http://", "").replace("https://", "") + for site in pagoda_sites + ]: + messages.error( + request, + "This site can not be added to The Pagoda Realm at this moment. If you alredy have this site listed in The Pagoda Realm, please verify it or delete and re-add the website if you wish to change the verification method.", + extra_tags="pagodaError", + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER")) + + PagodaSites.objects.create( + owner=request.user, + name=name, + url=url, + siteUniqueIdentifier=siteUniqueIdentifier, + verificationMethod=verificationMethod, + verficationRecordName=verficationRecordName, + verificationRecordValue=verificationRecordValue, + ) + + return HttpResponseRedirect(reverse("pagoda:home")) + else: + pass + + return render(request, f"{LANGUAGE_CODE}/pagoda/home.html") + + +@login_required +def site_dashboard(request, site_id): + LANGUAGE_CODE = i18npatterns(request.LANGUAGE_CODE) + site = PagodaSites.objects.get(siteUniqueIdentifier=site_id, owner=request.user) + context = { + "site": site, + } + META = { + "title": f"Manage {site.name} — The Pagoda Realm", + } + request.meta.update(META) + if site.verified: + return render( + request, f"{LANGUAGE_CODE}/pagoda/site_verification.html", context + ) + elif not site.verified: + return render( + request, f"{LANGUAGE_CODE}/pagoda/site_verification.html", context + ) + else: + return Http404() + + +@login_required +def check_verification_status(request, site_id): + site = PagodaSites.objects.get(siteUniqueIdentifier=site_id, owner=request.user) + + if site.verified: + messages.success( + request, + "The site has been verified successfully.", + extra_tags="pagodaSuccess", + ) + return HttpResponseRedirect(reverse("pagoda:site", args=[site_id])) + + if site.verificationMethod == "DNS": + domain = site.url.replace("http://", "").replace("https://", "") + txt_name = site.verficationRecordName + txt_value = site.verificationRecordValue + domain = txt_name + "." + domain.split("/")[0] + + try: + txt_records = dns.resolver.resolve(domain, "TXT") + for txt_record in txt_records: + for txt_string in txt_record.strings: + if txt_string.decode("utf-8") == txt_value: + site.verified = True + site.save() + messages.success( + request, + "The site has been verified successfully.", + extra_tags="pagodaSuccess", + ) + return HttpResponseRedirect( + reverse("pagoda:site", args=[site_id]) + ) + except dns.resolver.NoAnswer: + pass + messages.error( + request, + "The site could not be verified. Please check the DNS records and try again.", + extra_tags="pagodaError", + ) + return HttpResponseRedirect(reverse("pagoda:site", args=[site_id])) + elif site.verificationMethod == "Meta": + domain = site.url + response = requests.get(domain) + soup = BeautifulSoup(response.text, "html.parser") + meta_tags = soup.find_all("meta") + for meta_tag in meta_tags: + if ( + meta_tag.get("name") == site.verficationRecordName + and meta_tag.get("content") == site.verificationRecordValue + ): + site.verified = True + site.save() + messages.success( + request, + "The site has been verified successfully.", + extra_tags="pagodaSuccess", + ) + return HttpResponseRedirect(reverse("pagoda:site", args=[site_id])) + messages.error( + request, + "The site could not be verified. Please check the Meta tags and try again.", + extra_tags="pagodaError", + ) + return HttpResponseRedirect(reverse("pagoda:site", args=[site_id])) + else: + pass + + return Http404() + + +@login_required +def delete_site(request, site_id): + site = PagodaSites.objects.get(siteUniqueIdentifier=site_id, owner=request.user) + if site: + site.delete() + messages.success( + request, + "The site has been deleted successfully.", + extra_tags="pagodaSuccess", + ) + return HttpResponseRedirect(reverse("pagoda:home")) + else: + messages.error( + request, + "The site could not be deleted. Please try again.", + extra_tags="pagodaError", + ) + return HttpResponseRedirect(reverse("pagoda:home")) |
