add first user storage implementation
This commit is contained in:
parent
c2e85ce9a6
commit
6c3bb0b520
@ -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
80
owrx/users.py
Normal 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
11
users.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"user": "admin",
|
||||||
|
"password": {
|
||||||
|
"encoding": "string",
|
||||||
|
"value": "password",
|
||||||
|
"force_change": true
|
||||||
|
},
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in New Issue
Block a user