Implement authentication, etc.
This commit is contained in:
parent
8771e425ed
commit
5cfeb46141
22 changed files with 351 additions and 46 deletions
8
api/urls/__init__.py
Normal file
8
api/urls/__init__.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("AdonisWebServices/CrewPortalWebService.svc/", include("api.urls.crewportal")),
|
||||||
|
path("AIWS/AdonisIntegrationWebService.svc/", include("api.urls.integration")),
|
||||||
|
]
|
9
api/urls/crewportal.py
Normal file
9
api/urls/crewportal.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
|
||||||
|
from ..views.base import BaseAuthenticationView
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("GNL_API_AUTHENTICATION", BaseAuthenticationView.as_view()),
|
||||||
|
]
|
9
api/urls/integration.py
Normal file
9
api/urls/integration.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
|
||||||
|
from ..views.base import BaseAuthenticationView
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("GNL_API_AUTHENTICATION", BaseAuthenticationView.as_view()),
|
||||||
|
]
|
|
@ -1,3 +0,0 @@
|
||||||
from django.shortcuts import render
|
|
||||||
|
|
||||||
# Create your views here.
|
|
0
api/views/__init__.py
Normal file
0
api/views/__init__.py
Normal file
91
api/views/base.py
Normal file
91
api/views/base.py
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
from django.views import View
|
||||||
|
from django.http import HttpRequest, JsonResponse
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from datastore.models import APIToken, APIUser
|
||||||
|
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class BaseAPIView(View):
|
||||||
|
http_method_names: List[str] = ["post"]
|
||||||
|
|
||||||
|
unwrap_request: bool = True
|
||||||
|
wrap_response: bool = True
|
||||||
|
public: bool = False
|
||||||
|
|
||||||
|
view_name: Optional[str]
|
||||||
|
data: Optional[dict]
|
||||||
|
token: Optional[APIToken]
|
||||||
|
|
||||||
|
def get_view_name(self) -> str:
|
||||||
|
return self.view_name or self.request.get_raw_uri().split("/")[-1] or self.__class__.__name__[:-4]
|
||||||
|
|
||||||
|
def wrapper(self, indict: dict, force: bool = False):
|
||||||
|
if self.wrap_response or force:
|
||||||
|
return {
|
||||||
|
f"{self.get_view_name()}Result": indict
|
||||||
|
}
|
||||||
|
|
||||||
|
def authentication_error(self, message: str) -> JsonResponse:
|
||||||
|
response_data: dict = {
|
||||||
|
"Authentication_Approved": False,
|
||||||
|
"Authentication_ReasonDenied": message
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonResponse(wrapper(response_data))
|
||||||
|
|
||||||
|
def error(self, message: str) -> dict:
|
||||||
|
response_data: dict = {
|
||||||
|
"ErrorText": message
|
||||||
|
}
|
||||||
|
|
||||||
|
return response_data
|
||||||
|
|
||||||
|
def handle_request(self, request: HttpRequest, *args, **kwargs) -> dict:
|
||||||
|
raise NotImplementedError(
|
||||||
|
f"Class {self.__class__.__name__} does not implement handle_request()!")
|
||||||
|
|
||||||
|
def post(self, request: HttpRequest, *args, **kwargs) -> JsonResponse:
|
||||||
|
self.data: dict = json.loads(request.body)
|
||||||
|
|
||||||
|
if self.unwrap_request:
|
||||||
|
self.data = self.data["request"]
|
||||||
|
|
||||||
|
if not self.public:
|
||||||
|
if not self.data["Authentication_Token"]:
|
||||||
|
return self.authentication_error("Authentication token required for non-public API endpoint")
|
||||||
|
if not (tokens := APIToken.objects.filter(value=self.data["Authentication_Token"], expiry__lte=timezone.now())).exists():
|
||||||
|
return self.authentication_error("Authentication token does not exist or has expired")
|
||||||
|
|
||||||
|
self.token = tokens.first()
|
||||||
|
|
||||||
|
response_data = self.handle_request(request, *args, **kwargs)
|
||||||
|
response_data["Authentication_Approved"] = True
|
||||||
|
|
||||||
|
return JsonResponse(wrapper(response_data))
|
||||||
|
|
||||||
|
|
||||||
|
class BaseAuthenticationView(BaseAPIView):
|
||||||
|
unwrap_request = False
|
||||||
|
wrap_response = False
|
||||||
|
public = True
|
||||||
|
|
||||||
|
def handle_request(self, request, *args, **kwargs) -> dict:
|
||||||
|
if (not "credentials" in self.data) or (not "Login" in self.data["credentials"]) or (not "Password" in self.data["credentials"]):
|
||||||
|
return self.error("You need to pass credentials including Login and Password")
|
||||||
|
|
||||||
|
if (not (users := APIUser.objects.filter(username=self.data["credentials"]["Login"])).exists()) or not (user := users.first()).check_password(self.data["credentials"]["Password"]):
|
||||||
|
return self.error("Username or password incorrect")
|
||||||
|
|
||||||
|
validity = timezone.timedelta(seconds=int(
|
||||||
|
self.data["credentials"].get("LifeTime", 0)))
|
||||||
|
|
||||||
|
token = APIToken.objects.create(
|
||||||
|
user=user, expiry=timezone.now() + validity)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"Authentication_Token": token.value
|
||||||
|
}
|
0
api/views/crewportal/__init__.py
Normal file
0
api/views/crewportal/__init__.py
Normal file
0
api/views/integration/__init__.py
Normal file
0
api/views/integration/__init__.py
Normal file
|
@ -1,3 +1,20 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
|
||||||
# Register your models here.
|
from .models.auth import User, APIUser, APIToken
|
||||||
|
from .models.crew import CrewMember, Address, Phone, Email
|
||||||
|
from .models.places import Airport, Country, Nationality, PhoneCode, ZipPlace
|
||||||
|
from .models.competences import Competence, Role, Certificate
|
||||||
|
from .forms.auth import APIUserForm
|
||||||
|
|
||||||
|
|
||||||
|
for model in [User, APIToken, CrewMember, Address, Phone, Email, Airport, Country, Nationality, PhoneCode, ZipPlace, Competence, Role, Certificate]:
|
||||||
|
admin.site.register(model)
|
||||||
|
|
||||||
|
class APIUserAdmin(admin.ModelAdmin):
|
||||||
|
model = APIUser
|
||||||
|
form = APIUserForm
|
||||||
|
|
||||||
|
admin.site.register(APIUser, APIUserAdmin)
|
||||||
|
|
||||||
|
admin.site.unregister(Group)
|
|
@ -1,5 +1,5 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth.hashers import make_password
|
from django.contrib.auth.hashers import make_password, identify_hasher
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
from ..models.auth import APIUser
|
from ..models.auth import APIUser
|
||||||
|
@ -15,4 +15,8 @@ class APIUserForm(forms.ModelForm):
|
||||||
if not raw:
|
if not raw:
|
||||||
return ValidationError("You did not enter a password.")
|
return ValidationError("You did not enter a password.")
|
||||||
|
|
||||||
return make_password(raw)
|
try:
|
||||||
|
identify_hasher(raw)
|
||||||
|
return make_password(raw)
|
||||||
|
except:
|
||||||
|
return raw
|
17
datastore/migrations/0007_rename_zipplaces_zipplace.py
Normal file
17
datastore/migrations/0007_rename_zipplaces_zipplace.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 4.1 on 2022-08-09 07:45
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('datastore', '0006_alter_competence_shortname_certificate'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameModel(
|
||||||
|
old_name='ZipPlaces',
|
||||||
|
new_name='ZipPlace',
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Generated by Django 4.1 on 2022-09-26 06:17
|
||||||
|
|
||||||
|
import datastore.helpers.uploads
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('datastore', '0007_rename_zipplaces_zipplace'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='profile_picture',
|
||||||
|
field=models.ImageField(blank=True, null=True, upload_to=datastore.helpers.uploads.get_upload_path),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='closest_airport',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='crew_first', to='datastore.airport'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='country_of_birth',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='datastore.country'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='first_address',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='crew_first', to='datastore.address'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='nationality',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='datastore.nationality'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='place_of_birth',
|
||||||
|
field=models.CharField(blank=True, max_length=128, null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,54 @@
|
||||||
|
# Generated by Django 4.1 on 2022-09-26 06:50
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('datastore', '0008_crewmember_profile_picture_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='closest_airport',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='crew_first', to='datastore.airport'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='competences',
|
||||||
|
field=models.ManyToManyField(blank=True, null=True, to='datastore.competence'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='country_of_birth',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='datastore.country'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='first_address',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='crew_first', to='datastore.address'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='nationality',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='datastore.nationality'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='roles',
|
||||||
|
field=models.ManyToManyField(blank=True, null=True, to='datastore.role'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='second_address',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='crew_second', to='datastore.address'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='crewmember',
|
||||||
|
name='second_airport',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='crew_second', to='datastore.airport'),
|
||||||
|
),
|
||||||
|
]
|
18
datastore/migrations/0010_alter_apiuser_username.py
Normal file
18
datastore/migrations/0010_alter_apiuser_username.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 4.1 on 2022-09-26 11:02
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('datastore', '0009_alter_crewmember_closest_airport_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='apiuser',
|
||||||
|
name='username',
|
||||||
|
field=models.CharField(max_length=256, unique=True),
|
||||||
|
),
|
||||||
|
]
|
19
datastore/migrations/0011_alter_apitoken_value.py
Normal file
19
datastore/migrations/0011_alter_apitoken_value.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 4.1 on 2022-09-26 11:03
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('datastore', '0010_alter_apiuser_username'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='apitoken',
|
||||||
|
name='value',
|
||||||
|
field=models.UUIDField(default=uuid.uuid4, unique=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,4 +1,4 @@
|
||||||
from .auth import User
|
from .auth import User, APIUser, APIToken
|
||||||
from .crew import CrewMember
|
from .crew import CrewMember, Address, Phone, Email
|
||||||
from .places import Airport, Country, Nationality, PhoneCode, ZipPlaces
|
from .places import Airport, Country, Nationality, PhoneCode, ZipPlace
|
||||||
from .competences import Competence, Role, Certificate
|
from .competences import Competence, Role, Certificate
|
|
@ -24,15 +24,18 @@ class User(AbstractBaseUser, PermissionsMixin):
|
||||||
|
|
||||||
|
|
||||||
class APIUser(models.Model):
|
class APIUser(models.Model):
|
||||||
username = models.CharField(max_length=256)
|
username = models.CharField(max_length=256, unique=True)
|
||||||
password = models.CharField(max_length=256)
|
password = models.CharField(max_length=256)
|
||||||
|
|
||||||
def check_password(self, password):
|
def check_password(self, password):
|
||||||
return check_password(password, self.password)
|
return check_password(password, self.password)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.username
|
||||||
|
|
||||||
|
|
||||||
class APIToken(models.Model):
|
class APIToken(models.Model):
|
||||||
value = models.UUIDField(default=uuid.uuid4)
|
value = models.UUIDField(default=uuid.uuid4, unique=True)
|
||||||
user = models.ForeignKey(APIUser, models.CASCADE)
|
user = models.ForeignKey(APIUser, models.CASCADE)
|
||||||
expiry = models.DateTimeField()
|
expiry = models.DateTimeField()
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from .places import Nationality, ZipPlaces, Country, Airport, PhoneCode
|
from .places import Nationality, ZipPlace, Country, Airport, PhoneCode
|
||||||
from .competences import Competence, Role
|
from .competences import Competence, Role
|
||||||
|
from ..helpers.uploads import get_upload_path
|
||||||
|
|
||||||
|
|
||||||
class Address(models.Model):
|
class Address(models.Model):
|
||||||
address = models.TextField()
|
address = models.TextField()
|
||||||
zipplace = models.ForeignKey(ZipPlaces, models.PROTECT)
|
zipplace = models.ForeignKey(ZipPlace, models.PROTECT)
|
||||||
|
|
||||||
|
|
||||||
class CrewMember(models.Model):
|
class CrewMember(models.Model):
|
||||||
pin = models.IntegerField(primary_key=True)
|
pin = models.IntegerField(primary_key=True)
|
||||||
|
|
||||||
first_name = models.CharField(max_length=128)
|
first_name = models.CharField(max_length=128)
|
||||||
middle_name = models.CharField(max_length=128, null=True, blank=True)
|
middle_name = models.CharField(max_length=128, null=True, blank=True)
|
||||||
last_name = models.CharField(max_length=128)
|
last_name = models.CharField(max_length=128)
|
||||||
|
@ -18,21 +21,34 @@ class CrewMember(models.Model):
|
||||||
title = models.CharField(max_length=128, null=True, blank=True)
|
title = models.CharField(max_length=128, null=True, blank=True)
|
||||||
initials = models.CharField(max_length=16, null=True, blank=True)
|
initials = models.CharField(max_length=16, null=True, blank=True)
|
||||||
|
|
||||||
nationality = models.ForeignKey(Nationality, models.PROTECT)
|
profile_picture = models.ImageField(
|
||||||
place_of_birth = models.CharField(max_length=128)
|
upload_to=get_upload_path, null=True, blank=True)
|
||||||
country_of_birth = models.ForeignKey(Country, models.PROTECT)
|
|
||||||
first_address = models.ForeignKey(Address, models.PROTECT, related_name="crew_first")
|
|
||||||
second_address = models.ForeignKey(Address, models.PROTECT, null=True, related_name="crew_second")
|
|
||||||
closest_airport = models.ForeignKey(Airport, models.PROTECT, related_name="crew_first")
|
|
||||||
second_airport = models.ForeignKey(Airport, models.PROTECT, null=True, related_name="crew_second")
|
|
||||||
|
|
||||||
roles = models.ManyToManyField(Role, null=True)
|
nationality = models.ForeignKey(
|
||||||
competences = models.ManyToManyField(Competence, null=True)
|
Nationality, models.PROTECT, null=True, blank=True)
|
||||||
|
place_of_birth = models.CharField(max_length=128, null=True, blank=True)
|
||||||
|
country_of_birth = models.ForeignKey(
|
||||||
|
Country, models.PROTECT, null=True, blank=True)
|
||||||
|
first_address = models.ForeignKey(
|
||||||
|
Address, models.PROTECT, related_name="crew_first", null=True, blank=True)
|
||||||
|
second_address = models.ForeignKey(
|
||||||
|
Address, models.PROTECT, null=True, related_name="crew_second", blank=True)
|
||||||
|
closest_airport = models.ForeignKey(
|
||||||
|
Airport, models.PROTECT, related_name="crew_first", null=True, blank=True)
|
||||||
|
second_airport = models.ForeignKey(
|
||||||
|
Airport, models.PROTECT, null=True, related_name="crew_second", blank=True)
|
||||||
|
|
||||||
|
roles = models.ManyToManyField(Role, null=True, blank=True)
|
||||||
|
competences = models.ManyToManyField(Competence, null=True, blank=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def all_competences(self):
|
def all_competences(self):
|
||||||
return self.competences.all().union(*[role.competences.all() for role in self.roles.all()])
|
return self.competences.all().union(*[role.competences.all() for role in self.roles.all()])
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.pin}: {self.first_name} {self.last_name}"
|
||||||
|
|
||||||
|
|
||||||
class Phone(models.Model):
|
class Phone(models.Model):
|
||||||
crew = models.ForeignKey(CrewMember, models.CASCADE)
|
crew = models.ForeignKey(CrewMember, models.CASCADE)
|
||||||
idc = models.ForeignKey(PhoneCode, models.PROTECT, null=True)
|
idc = models.ForeignKey(PhoneCode, models.PROTECT, null=True)
|
||||||
|
@ -40,8 +56,15 @@ class Phone(models.Model):
|
||||||
confirmed = models.BooleanField(default=True)
|
confirmed = models.BooleanField(default=True)
|
||||||
priority = models.IntegerField(default=0)
|
priority = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.crew.pin}: {self.number}"
|
||||||
|
|
||||||
|
|
||||||
class Email(models.Model):
|
class Email(models.Model):
|
||||||
crew = models.ForeignKey(CrewMember, models.CASCADE)
|
crew = models.ForeignKey(CrewMember, models.CASCADE)
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
confirmed = models.BooleanField(default=True)
|
confirmed = models.BooleanField(default=True)
|
||||||
priority = models.IntegerField(default=0)
|
priority = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.crew.pin}: {self.email}"
|
||||||
|
|
|
@ -8,6 +8,8 @@ from ..helpers.uploads import get_upload_path
|
||||||
"""
|
"""
|
||||||
These models are used by Adonis to return tens of thousands of
|
These models are used by Adonis to return tens of thousands of
|
||||||
lines of unneeded data.
|
lines of unneeded data.
|
||||||
|
|
||||||
|
Not currently needed, but prepared.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Country(models.Model):
|
class Country(models.Model):
|
||||||
|
@ -23,7 +25,7 @@ class Airport(models.Model):
|
||||||
country_name = models.CharField(max_length=256, null=True, blank=True)
|
country_name = models.CharField(max_length=256, null=True, blank=True)
|
||||||
name = models.CharField(max_length=256, null=True, blank=True)
|
name = models.CharField(max_length=256, null=True, blank=True)
|
||||||
|
|
||||||
class ZipPlaces(models.Model):
|
class ZipPlace(models.Model):
|
||||||
postcode = models.CharField(max_length=64)
|
postcode = models.CharField(max_length=64)
|
||||||
postplace = models.CharField(max_length=256)
|
postplace = models.CharField(max_length=256)
|
||||||
country = models.ForeignKey(Nationality, models.PROTECT)
|
country = models.ForeignKey(Nationality, models.PROTECT)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from json import loads
|
||||||
|
|
||||||
from autosecretkey import AutoSecretKey
|
from autosecretkey import AutoSecretKey
|
||||||
|
|
||||||
|
@ -10,10 +11,15 @@ CONFIG_PATH = BASE_DIR / "settings.ini"
|
||||||
|
|
||||||
ASK = AutoSecretKey(CONFIG_PATH)
|
ASK = AutoSecretKey(CONFIG_PATH)
|
||||||
|
|
||||||
|
SECRET_KEY = ASK.secret_key
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = ASK.config.getboolean("DUMUZID", "Debug", fallback=False)
|
DEBUG = ASK.config.getboolean("DUMUZID", "Debug", fallback=False)
|
||||||
|
|
||||||
ALLOWED_HOSTS = []
|
ALLOWED_HOSTS = ["*"]
|
||||||
|
|
||||||
|
if "TrustedOrigins" in ASK.config["DUMUZID"]:
|
||||||
|
CSRF_TRUSTED_ORIGINS = loads(ASK.config["DUMUZID"]["TrustedOrigins"])
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
@ -121,10 +127,6 @@ USE_TZ = True
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/4.1/howto/static-files/
|
# https://docs.djangoproject.com/en/4.1/howto/static-files/
|
||||||
|
|
||||||
STATICFILES_DIRS = [
|
|
||||||
BASE_DIR / "frontend/static/",
|
|
||||||
]
|
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
STATIC_ROOT = None if DEBUG else ASK.config.get("RESTOROO", "StaticRoot", fallback=BASE_DIR / "static")
|
STATIC_ROOT = None if DEBUG else ASK.config.get("RESTOROO", "StaticRoot", fallback=BASE_DIR / "static")
|
||||||
|
|
|
@ -1,21 +1,7 @@
|
||||||
"""dumuzid URL Configuration
|
|
||||||
|
|
||||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
|
||||||
https://docs.djangoproject.com/en/4.1/topics/http/urls/
|
|
||||||
Examples:
|
|
||||||
Function views
|
|
||||||
1. Add an import: from my_app import views
|
|
||||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
|
||||||
Class-based views
|
|
||||||
1. Add an import: from other_app.views import Home
|
|
||||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
|
||||||
Including another URLconf
|
|
||||||
1. Import the include() function: from django.urls import include, path
|
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
|
||||||
"""
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('', include("api.urls")),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
[DUMUZID]
|
[DUMUZID]
|
||||||
Debug = 0
|
Debug = 0
|
||||||
|
TrustedOrigins = ["https://dumuzid/"]
|
||||||
|
|
||||||
# [MySQL]
|
# [MySQL]
|
||||||
# Database = dumuzid
|
# Database = dumuzid
|
||||||
|
|
Loading…
Reference in a new issue