commit b119f1ef7118f1a71a66f153712d59d1a7c9b229 Author: Kumi Date: Tue Aug 2 10:29:58 2022 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a2028f --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.pyc +__pycache__/ +db.sqlite3 +db.sqlite3-journal +venv/ +config.ini \ No newline at end of file diff --git a/config.dist.ini b/config.dist.ini new file mode 100644 index 0000000..9ed0b0b --- /dev/null +++ b/config.dist.ini @@ -0,0 +1,10 @@ +[App] +Debug = 0 +Hosts = ["kumidc.local"] + +# [MySQL] +# Database = kumidc +# Username = kumidc +# Password = secret123! +# Host = localhost +# Port = 3306 \ No newline at end of file diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/admin.py b/core/admin.py new file mode 100644 index 0000000..9b4d940 --- /dev/null +++ b/core/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin +from django.contrib.auth.models import Group + +from .models import User + + +admin.site.unregister(Group) +admin.site.register(User) \ No newline at end of file diff --git a/core/apps.py b/core/apps.py new file mode 100644 index 0000000..8115ae6 --- /dev/null +++ b/core/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CoreConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'core' diff --git a/core/managers/__init__.py b/core/managers/__init__.py new file mode 100644 index 0000000..7bcbdd8 --- /dev/null +++ b/core/managers/__init__.py @@ -0,0 +1 @@ +from .auth import UserManager \ No newline at end of file diff --git a/core/managers/auth.py b/core/managers/auth.py new file mode 100644 index 0000000..fe02604 --- /dev/null +++ b/core/managers/auth.py @@ -0,0 +1,23 @@ +from django.contrib.auth.base_user import BaseUserManager + + +class UserManager(BaseUserManager): + def create_user(self, email, password, **extra_fields): + if not email: + raise ValueError('Email must be set') + email = self.normalize_email(email) + user = self.model(email=email, **extra_fields) + user.set_password(password) + user.save() + return user + + def create_superuser(self, email, password, **extra_fields): + extra_fields.setdefault('is_staff', True) + extra_fields.setdefault('is_superuser', True) + extra_fields.setdefault('is_active', True) + + if extra_fields.get('is_staff') is not True: + raise ValueError('Superuser must have is_staff=True.') + if extra_fields.get('is_superuser') is not True: + raise ValueError('Superuser must have is_superuser=True.') + return self.create_user(email, password, **extra_fields) diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..d6cc939 --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.14 on 2022-08-01 13:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('email', models.EmailField(max_length=254, unique=True)), + ('is_staff', models.BooleanField(default=False)), + ('is_active', models.BooleanField(default=True)), + ('date_joined', models.DateTimeField(auto_now_add=True)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/core/migrations/__init__.py b/core/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/models/__init__.py b/core/models/__init__.py new file mode 100644 index 0000000..611c4d8 --- /dev/null +++ b/core/models/__init__.py @@ -0,0 +1 @@ +from .auth import User \ No newline at end of file diff --git a/core/models/auth.py b/core/models/auth.py new file mode 100644 index 0000000..f9745b3 --- /dev/null +++ b/core/models/auth.py @@ -0,0 +1,20 @@ +from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin +from django.db import models +from django.utils import timezone + +from ..managers import UserManager + + +class User(AbstractBaseUser, PermissionsMixin): + email = models.EmailField(unique=True) + is_staff = models.BooleanField(default=False) + is_active = models.BooleanField(default=True) + date_joined = models.DateTimeField(auto_now_add=True) + + USERNAME_FIELD = 'email' + REQUIRED_FIELDS = [] + + objects = UserManager() + + def __str__(self): + return self.email diff --git a/core/tests.py b/core/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/core/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/core/views.py b/core/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/core/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/kumidc/__init__.py b/kumidc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kumidc/asgi.py b/kumidc/asgi.py new file mode 100644 index 0000000..d7826de --- /dev/null +++ b/kumidc/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for kumidc project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kumidc.settings') + +application = get_asgi_application() diff --git a/kumidc/settings.py b/kumidc/settings.py new file mode 100644 index 0000000..ae56868 --- /dev/null +++ b/kumidc/settings.py @@ -0,0 +1,127 @@ +from pathlib import Path + +import json + +from autosecretkey import AutoSecretKey + + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +CONFIG_FILE = AutoSecretKey(BASE_DIR / "config.ini", template="config.dist.ini") +SECRET_KEY = CONFIG_FILE.secret_key + +DEBUG = CONFIG_FILE.config["App"]["Debug"] + +ALLOWED_HOSTS = json.loads(CONFIG_FILE.config["App"]["Hosts"]) + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'core', + 'oidc_provider', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'kumidc.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'kumidc.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.0/ref/settings/#databases + +if "MySQL" in CONFIG_FILE.config: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': CONFIG_FILE.config.get("MySQL", "Database"), + 'USER': CONFIG_FILE.config.get("MySQL", "Username"), + 'PASSWORD': CONFIG_FILE.config.get("MySQL", "Password"), + 'HOST': CONFIG_FILE.config.get("MySQL", "Host", fallback="localhost"), + 'PORT': CONFIG_FILE.config.getint("MySQL", "Port", fallback=3306) + } + } + +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } + } + +# Password validation +# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators + +AUTH_USER_MODEL = "core.User" + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.0/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.0/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/kumidc/urls.py b/kumidc/urls.py new file mode 100644 index 0000000..1377d55 --- /dev/null +++ b/kumidc/urls.py @@ -0,0 +1,7 @@ +from django.contrib import admin +from django.urls import path, re_path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + re_path(r'^openid/', include('oidc_provider.urls', namespace='oidc_provider')), +] diff --git a/kumidc/wsgi.py b/kumidc/wsgi.py new file mode 100644 index 0000000..4c049e8 --- /dev/null +++ b/kumidc/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for kumidc project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kumidc.settings') + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..82f1713 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kumidc.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0f71646 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +Django<4 + +git+https://github.com/juanifioren/django-oidc-provider + +dbsettings +django-autosecretkey + +# For MySQL: + +mysqlclient