add first user storage implementation

This commit is contained in:
Jakob Ketterl 2020-04-01 22:29:42 +02:00
parent c2e85ce9a6
commit 6c3bb0b520
3 changed files with 103 additions and 11 deletions

View File

@ -2,6 +2,7 @@ from .template import WebpageController
from urllib.parse import parse_qs from urllib.parse import parse_qs
from uuid import uuid4 from uuid import uuid4
from http.cookies import SimpleCookie from http.cookies import SimpleCookie
from owrx.users import UserList
class SessionStorage(object): class SessionStorage(object):
@ -40,18 +41,18 @@ class SessionController(WebpageController):
def processLoginAction(self): def processLoginAction(self):
data = parse_qs(self.get_body().decode("utf-8")) data = parse_qs(self.get_body().decode("utf-8"))
data = {k: v[0] for k, v in data.items()} data = {k: v[0] for k, v in data.items()}
userlist = UserList.getSharedInstance()
if "user" in data and "password" in data: if "user" in data and "password" in data:
# TODO actually check user and password if data["user"] in userlist:
if data["user"] == "admin" and data["password"] == "password": user = userlist[data["user"]]
if user.password.is_valid(data["password"]):
# TODO pass the final destination # TODO pass the final destination
key = SessionStorage.getSharedInstance().startSession({"user": data["user"]}) key = SessionStorage.getSharedInstance().startSession({"user": user.name})
cookie = SimpleCookie() cookie = SimpleCookie()
cookie["owrx-session"] = key cookie["owrx-session"] = key
self.send_redirect("/admin", cookies=cookie) self.send_redirect("/admin", cookies=cookie)
else: return
self.send_redirect("/login") self.send_redirect("/login")
else:
self.send_response("invalid request", code=400)
def logoutAction(self): def logoutAction(self):
self.send_redirect("logout happening here") self.send_redirect("logout happening here")

80
owrx/users.py Normal file
View File

@ -0,0 +1,80 @@
from abc import ABC, abstractmethod
import json
import logging
logger = logging.getLogger(__name__)
class PasswordException(Exception):
pass
class Password(ABC):
@staticmethod
def from_dict(d: dict):
if "encoding" not in d:
raise PasswordException("password encoding not set")
if d["encoding"] == "string":
return CleartextPassword(d)
raise PasswordException("invalid passord encoding: {0}".format(d["type"]))
def __init__(self, pwinfo: dict):
self.pwinfo = pwinfo
@abstractmethod
def is_valid(self, inp: str):
pass
class CleartextPassword(Password):
def is_valid(self, inp: str):
return self.pwinfo['value'] == inp
class User(object):
def __init__(self, name: str, enabled: bool, password: Password):
self.name = name
self.enabled = enabled
self.password = password
class UserList(object):
sharedInstance = None
@staticmethod
def getSharedInstance():
if UserList.sharedInstance is None:
UserList.sharedInstance = UserList()
return UserList.sharedInstance
def __init__(self):
self.users = self._loadUsers()
def _loadUsers(self):
for file in ["/etc/openwebrx/users.json", "users.json"]:
try:
f = open(file, "r")
users_json = json.load(f)
f.close()
return {u.name: u for u in [self.buildUser(d) for d in users_json]}
except FileNotFoundError:
pass
except json.JSONDecodeError:
logger.exception("error while parsing users file %s", file)
return {}
except Exception:
logger.exception("error while processing users from %s", file)
return {}
return {}
def buildUser(self, d):
if "user" in d and "password" in d and "enabled" in d:
return User(d["user"], d["enabled"], Password.from_dict(d["password"]))
def __getitem__(self, item):
return self.users[item]
def __contains__(self, item):
return item in self.users

11
users.json Normal file
View File

@ -0,0 +1,11 @@
[
{
"user": "admin",
"password": {
"encoding": "string",
"value": "password",
"force_change": true
},
"enabled": true
}
]