Preparing for API-server-less login
This commit is contained in:
parent
d9d34acfda
commit
f138fb7b44
4 changed files with 42 additions and 49 deletions
|
@ -3,11 +3,15 @@ from pathlib import Path
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
from autosecretkey import AutoSecretKey
|
from autosecretkey import AutoSecretKey
|
||||||
|
from reportmonster.classes.config import MonsterConfig
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
ASK = AutoSecretKey(BASE_DIR / "settings.ini")
|
CONFIG_PATH = BASE_DIR / "settings.ini"
|
||||||
|
|
||||||
|
ASK = AutoSecretKey(CONFIG_PATH)
|
||||||
|
MONSTERCONFIG = MonsterConfig(CONFIG_PATH)
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
|
||||||
|
@ -141,10 +145,13 @@ AUTH_USER_MODEL = 'core.User'
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = [
|
AUTHENTICATION_BACKENDS = [
|
||||||
'django.contrib.auth.backends.ModelBackend',
|
'django.contrib.auth.backends.ModelBackend',
|
||||||
'core.backends.ReportMonsterBackend',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
REPORTMONSTER = ASK.config["REPORTMONSTER"]
|
if ASK.config.getboolean("REPORTMONSTER", "Login"):
|
||||||
|
LOGIN_VESSEL = ASK.config["REPORTMONSTER"]["LoginVessel"]
|
||||||
|
AUTHENTICATION_BACKENDS.append('core.backends.ReportMonsterBackend')
|
||||||
|
else:
|
||||||
|
LOGIN_VESSEL = None
|
||||||
|
|
||||||
# Login System
|
# Login System
|
||||||
|
|
||||||
|
|
|
@ -5,47 +5,15 @@ from django.conf import settings
|
||||||
|
|
||||||
from bcrypt import checkpw
|
from bcrypt import checkpw
|
||||||
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
from reportmonster_client import ReportMonsterClient
|
|
||||||
|
|
||||||
|
|
||||||
class ReportMonsterBackend(ModelBackend):
|
class ReportMonsterBackend(ModelBackend):
|
||||||
async def _fetch_data(self, username: str):
|
|
||||||
try:
|
|
||||||
client = ReportMonsterClient(
|
|
||||||
settings.REPORTMONSTER["Username"],
|
|
||||||
settings.REPORTMONSTER["Password"],
|
|
||||||
settings.REPORTMONSTER.get("Host", fallback="127.0.0.1"),
|
|
||||||
settings.REPORTMONSTER.getint("Port", fallback=6789))
|
|
||||||
|
|
||||||
try:
|
|
||||||
await client.connect()
|
|
||||||
except Exception as e:
|
|
||||||
raise Exception("Something went wrong connecting to ReportMonster: " + repr(e))
|
|
||||||
|
|
||||||
authresult = await client.auth()
|
|
||||||
|
|
||||||
if authresult.error:
|
|
||||||
raise Exception("Something went wrong authenticating with ReportMonster: " + response._raw)
|
|
||||||
|
|
||||||
response = await client.write(f"user {settings.REPORTMONSTER['Vessel']} {username}")
|
|
||||||
|
|
||||||
if response.error:
|
|
||||||
raise Exception("Something went wrong fetching user details: " + response._raw)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
messages.error(self.request, "Could not login. " + repr(e))
|
|
||||||
|
|
||||||
def authenticate(self, request, username: str = None, password:str = None):
|
def authenticate(self, request, username: str = None, password:str = None):
|
||||||
self.request = request
|
self.request = request
|
||||||
|
|
||||||
userdata = asyncio.run(asyncio.wait_for(self._fetch_data(username), 10))
|
monster = settings.MONSTERCONFIG
|
||||||
|
loginvessel = filter(lambda x: x.name = settings.LOGIN_VESSEL, monster.vessels)[0]
|
||||||
|
|
||||||
|
|
||||||
if not userdata or not userdata.content:
|
|
||||||
return
|
|
||||||
|
|
||||||
if checkpw(password.encode(), userdata.content["password"].encode()):
|
if checkpw(password.encode(), userdata.content["password"].encode()):
|
||||||
user, _ = get_user_model().objects.get_or_create(email=username)
|
user, _ = get_user_model().objects.get_or_create(email=username)
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
from django.contrib.auth.base_user import BaseUserManager
|
from django.contrib.auth.base_user import BaseUserManager
|
||||||
|
|
||||||
class UserManager(BaseUserManager):
|
class UserManager(BaseUserManager):
|
||||||
"""
|
|
||||||
Custom user model manager where email is the unique identifiers
|
|
||||||
for authentication instead of usernames.
|
|
||||||
"""
|
|
||||||
def create_user(self, email, **extra_fields):
|
def create_user(self, email, **extra_fields):
|
||||||
"""
|
|
||||||
Create and save a User with the given email and password.
|
|
||||||
"""
|
|
||||||
if not email:
|
if not email:
|
||||||
raise ValueError('The Email must be set')
|
raise ValueError('The Email must be set')
|
||||||
email = self.normalize_email(email)
|
email = self.normalize_email(email)
|
||||||
|
@ -17,9 +10,6 @@ class UserManager(BaseUserManager):
|
||||||
return user
|
return user
|
||||||
|
|
||||||
def create_superuser(self, email, **extra_fields):
|
def create_superuser(self, email, **extra_fields):
|
||||||
"""
|
|
||||||
Create and save a SuperUser with the given email and password.
|
|
||||||
"""
|
|
||||||
extra_fields.setdefault('is_staff', True)
|
extra_fields.setdefault('is_staff', True)
|
||||||
extra_fields.setdefault('is_superuser', True)
|
extra_fields.setdefault('is_superuser', True)
|
||||||
extra_fields.setdefault('is_active', True)
|
extra_fields.setdefault('is_active', True)
|
||||||
|
|
|
@ -1,2 +1,30 @@
|
||||||
[ACADEMON]
|
[ACADEMON]
|
||||||
|
|
||||||
|
[REPORTMONSTER]
|
||||||
|
Login = 1
|
||||||
LoginVessel = test
|
LoginVessel = test
|
||||||
|
|
||||||
|
[Vessel test]
|
||||||
|
Host = 10.11.12.13
|
||||||
|
Username = moodle_test
|
||||||
|
Password = 1quite_secret*indeed!
|
||||||
|
Database = moodle_test
|
||||||
|
SSH = 1 # Whether or not to tunnel the MySQL connection through SSH
|
||||||
|
# ReportMonster / AcadeMon does not handle authentication, so use SSH agent!
|
||||||
|
|
||||||
|
# Only used if anything actually enables the ReportMonster API
|
||||||
|
# [User test]
|
||||||
|
# Password = test123!
|
||||||
|
|
||||||
|
# [MySQL]
|
||||||
|
# Database = academon
|
||||||
|
# Username = academon
|
||||||
|
# Password = secret123!
|
||||||
|
# Host = localhost
|
||||||
|
# Port = 3306
|
||||||
|
|
||||||
|
# [S3]
|
||||||
|
# AccessKey = academon
|
||||||
|
# SecretKey = !!!verysecret!!!
|
||||||
|
# Bucket = academon
|
||||||
|
# Endpoint = https://minio.acade.mon
|
Loading…
Reference in a new issue