mirror of
https://github.com/AR2000AR/openComputers_codes.git
synced 2025-09-08 22:51:14 +02:00
[icable_server] massive refactoring of python module
This commit is contained in:
@@ -13,6 +13,7 @@ from pathlib import Path
|
|||||||
from signal import SIGINT, SIGTERM, signal
|
from signal import SIGINT, SIGTERM, signal
|
||||||
from string import Template
|
from string import Template
|
||||||
from urllib.parse import parse_qs
|
from urllib.parse import parse_qs
|
||||||
|
import pathlib
|
||||||
|
|
||||||
import models.database
|
import models.database
|
||||||
import models.firewall
|
import models.firewall
|
||||||
@@ -23,7 +24,10 @@ from icable.firewall import *
|
|||||||
from icable.packet import *
|
from icable.packet import *
|
||||||
from icable.protocol import *
|
from icable.protocol import *
|
||||||
|
|
||||||
db = models.database.DatabaseHandler('icable.db')
|
dataPath = pathlib.Path(pathlib.Path.home(),'.local','share','icable')
|
||||||
|
dataPath.mkdir(parents=True,exist_ok=True)
|
||||||
|
|
||||||
|
db = models.database.DatabaseHandler(pathlib.Path(dataPath,'icable.db'))
|
||||||
users = models.user.Users(db)
|
users = models.user.Users(db)
|
||||||
webSessions = models.web.WebSessions(db)
|
webSessions = models.web.WebSessions(db)
|
||||||
networks = models.network.Networks(db)
|
networks = models.network.Networks(db)
|
||||||
@@ -340,7 +344,7 @@ class WebInterface(BaseHTTPRequestHandler):
|
|||||||
user_networks.sort()
|
user_networks.sort()
|
||||||
for network in user_networks:
|
for network in user_networks:
|
||||||
dl_button = ""
|
dl_button = ""
|
||||||
if(self.user.get_network_permission(network)==1 or models.user.User.SubnetworkPermission.OWNER in self.user.subnetwork_permission):
|
if(self.user.get_network_permission(network)==1 or models.user.SubnetworkPermission.OWNER in self.user.subnetwork_permission):
|
||||||
dl_button = f"""<form action='/network' method='post'>
|
dl_button = f"""<form action='/network' method='post'>
|
||||||
<input class='ip-cell' type='submit' value='Delete'>
|
<input class='ip-cell' type='submit' value='Delete'>
|
||||||
<input class='ip-cell' type='hidden' name='cmd' value='delete'>
|
<input class='ip-cell' type='hidden' name='cmd' value='delete'>
|
||||||
@@ -357,7 +361,7 @@ class WebInterface(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
#region firewall
|
#region firewall
|
||||||
mapping['firewallDefault']=firewalls[self.user.subnetid].action.name
|
mapping['firewallDefault']=firewalls[self.user.subnetid].action.name
|
||||||
FIREWALL_ALLOWED = models.user.User.SubnetworkPermission.FIREWALL|models.user.User.SubnetworkPermission.OWNER
|
FIREWALL_ALLOWED = models.user.SubnetworkPermission.FIREWALL|models.user.SubnetworkPermission.OWNER
|
||||||
|
|
||||||
mapping['firewallRuleList']=""
|
mapping['firewallRuleList']=""
|
||||||
for rule in firewalls[self.user.subnetid].rules:
|
for rule in firewalls[self.user.subnetid].rules:
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
from . import database
|
from . import database
|
||||||
|
from sqlite3 import Cursor
|
||||||
|
|
||||||
__all__ = ["user","network","firewall","web","database"]
|
__all__ = ["user","network","firewall","web","database"]
|
||||||
|
|
||||||
@@ -6,4 +7,4 @@ class Model():
|
|||||||
"""Abstract class for data model calss"""
|
"""Abstract class for data model calss"""
|
||||||
|
|
||||||
def __init__(self,database:database.DatabaseHandler):
|
def __init__(self,database:database.DatabaseHandler):
|
||||||
self._database = database
|
self._database = database
|
||||||
|
@@ -2,16 +2,12 @@ import threading
|
|||||||
import pathlib
|
import pathlib
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
class DatabaseHandler():
|
class DatabaseHandler(sqlite3.Connection):
|
||||||
|
|
||||||
def __init__(self,dbPath:str):
|
def __init__(self,*args,**kwargs):
|
||||||
self._semaphore = threading.BoundedSemaphore()
|
super().__init__(*args,check_same_thread=False,detect_types=sqlite3.PARSE_DECLTYPES,**kwargs)
|
||||||
dataPath = pathlib.Path(pathlib.Path.home(),'.local','share','icable')
|
|
||||||
dataPath.mkdir(parents=True,exist_ok=True)
|
|
||||||
self._database = sqlite3.connect(pathlib.Path(dataPath,dbPath),check_same_thread=False,detect_types=sqlite3.PARSE_DECLTYPES)
|
|
||||||
#self._database.row_factory = Row
|
#self._database.row_factory = Row
|
||||||
self._cursor = self._database.cursor()
|
self.executescript("""
|
||||||
self._cursor.executescript("""
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE TABLE IF NOT EXISTS "users" (
|
CREATE TABLE IF NOT EXISTS "users" (
|
||||||
login TEXT PRIMARY KEY CHECK(typeof("login") = 'text'),
|
login TEXT PRIMARY KEY CHECK(typeof("login") = 'text'),
|
||||||
@@ -46,28 +42,9 @@ class DatabaseHandler():
|
|||||||
END;
|
END;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
PRAGMA foreign_keys=ON;""")
|
PRAGMA foreign_keys=ON;""")
|
||||||
|
|
||||||
def execute(self,*args,**kwargs):
|
|
||||||
return self._cursor.execute(*args,**kwargs)
|
|
||||||
def fetchone(self,*args,**kwargs):
|
|
||||||
return self._cursor.fetchone(*args,**kwargs)
|
|
||||||
def fetchall(self,*args,**kwargs):
|
|
||||||
return self._cursor.fetchall(*args,**kwargs)
|
|
||||||
def fetchmany(self,*args,**kwargs):
|
|
||||||
return self._cursor.fetchmany(*args,**kwargs)
|
|
||||||
def commit(self,*args,**kwargs):
|
|
||||||
return self.database.commit()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def semaphore(self)->threading.BoundedSemaphore:
|
|
||||||
return self._semaphore
|
|
||||||
|
|
||||||
@property
|
|
||||||
def database(self):
|
|
||||||
return self._database
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self._cursor.execute("PRAGMA optimize;")
|
self.rollback()
|
||||||
self.database.commit()
|
self.execute("PRAGMA optimize;")
|
||||||
self._cursor.close()
|
self.commit()
|
||||||
self.database.close()
|
self.close()
|
||||||
|
@@ -4,13 +4,12 @@ from icable.firewall import Firewall
|
|||||||
class Firewalls(Model):
|
class Firewalls(Model):
|
||||||
|
|
||||||
def __getitem__(self,key:int):
|
def __getitem__(self,key:int):
|
||||||
self._database.execute("SELECT pickle FROM firewall WHERE subnetid = ?",(key,))
|
cursor=self._database.execute("SELECT pickle FROM firewall WHERE subnetid = ?",(key,))
|
||||||
res=self._database.fetchone()
|
res=cursor.fetchone()
|
||||||
if(not res):
|
if(not res):
|
||||||
return Firewall()
|
return Firewall()
|
||||||
return res[0]
|
return res[0]
|
||||||
|
|
||||||
def __setitem__(self,key:int,firewall:Firewall):
|
def __setitem__(self,key:int,firewall:Firewall):
|
||||||
with self._database.semaphore:
|
self._database.execute("INSERT OR REPLACE INTO firewall VALUES(?,?)",(key,firewall))
|
||||||
self._database.execute("INSERT OR REPLACE INTO firewall VALUES(?,?)",(key,firewall))
|
self._database.commit()
|
||||||
self._database.commit()
|
|
@@ -30,37 +30,35 @@ class Network():
|
|||||||
class Networks(Model):
|
class Networks(Model):
|
||||||
|
|
||||||
def getNetworkById(self,id:int):
|
def getNetworkById(self,id:int):
|
||||||
self._database.execute("SELECT subnetid,network,nmask FROM networks WHERE id = ?",(id,))
|
cursor=self._database.execute("SELECT subnetid,network,nmask FROM networks WHERE id = ?",(id,))
|
||||||
res = self._database.fetchone()
|
res = cursor.fetchone()
|
||||||
if(not res):
|
if(not res):
|
||||||
return False
|
return False
|
||||||
return Network(id,res[0],ipaddress.ip_network((res[1],ipaddress.ip_address(res[2]).compressed)))
|
return Network(id,res[0],ipaddress.ip_network((res[1],ipaddress.ip_address(res[2]).compressed)))
|
||||||
|
|
||||||
def getNetworksInSubnet(self,subnetid:int):
|
def getNetworksInSubnet(self,subnetid:int):
|
||||||
self._database.execute("SELECT id,subnetid,network,nmask FROM networks WHERE subnetid = ?",(subnetid,))
|
cursor=self._database.execute("SELECT id,subnetid,network,nmask FROM networks WHERE subnetid = ?",(subnetid,))
|
||||||
res = self._database.fetchall()
|
res = cursor.fetchall()
|
||||||
if(not res):
|
if(not res):
|
||||||
return list[Network]()
|
return list[Network]()
|
||||||
return [Network(net[0],subnetid,ipaddress.ip_network(net[2],ipaddress.ip_address(net[3]).compressed))for net in res]
|
return [Network(net[0],subnetid,ipaddress.ip_network(net[2],ipaddress.ip_address(net[3]).compressed))for net in res]
|
||||||
|
|
||||||
def getAllNetworks(self):
|
def getAllNetworks(self):
|
||||||
self._database.execute("SELECT id,subnetid,network,nmask FROM networks")
|
cursor=self._database.execute("SELECT id,subnetid,network,nmask FROM networks")
|
||||||
res = self._database.fetchall()
|
res = cursor.fetchall()
|
||||||
if(not res):
|
if(not res):
|
||||||
return list[Network]()
|
return list[Network]()
|
||||||
return [Network(net[0],net[1],ipaddress.ip_network((net[2],ipaddress.ip_address(net[3]).compressed)))for net in res]
|
return [Network(net[0],net[1],ipaddress.ip_network((net[2],ipaddress.ip_address(net[3]).compressed)))for net in res]
|
||||||
|
|
||||||
def createNetwork(self,subnetwork:int,network:ipaddress.IPv4Network) :
|
def createNetwork(self,subnetwork:int,network:ipaddress.IPv4Network) :
|
||||||
with self._database.semaphore:
|
self._database.execute("INSERT INTO networks(subnetid,network,nmask) VALUES(?,?,?)",(subnetwork,int(network.network_address),int(network.netmask)))
|
||||||
self._database.execute("INSERT INTO networks(subnetid,network,nmask) VALUES(?,?,?)",(subnetwork,int(network.network_address),int(network.netmask)))
|
self._database.commit()
|
||||||
self._database.commit()
|
cursor=self._database.execute("SELECT id from networks WHERE subnetid = ? AND network = ? and nmask = ?",(subnetwork,int(network.network_address),int(network.netmask)))
|
||||||
self._database.execute("SELECT id from networks WHERE subnetid = ? AND network = ? and nmask = ?",(subnetwork,int(network.network_address),int(network.netmask)))
|
res = cursor.fetchone()
|
||||||
res = self._database.fetchone()
|
|
||||||
nt = self.getNetworkById(res[0])
|
nt = self.getNetworkById(res[0])
|
||||||
assert(isinstance(nt,Network))
|
assert(isinstance(nt,Network))
|
||||||
return nt
|
return nt
|
||||||
|
|
||||||
def deleteNetwork(self,network:Network):
|
def deleteNetwork(self,network:Network):
|
||||||
with self._database.semaphore:
|
self._database.execute("DELETE FROM networks WHERE id = ?",(network.id,))
|
||||||
self._database.execute("DELETE FROM networks WHERE id = ?",(network.id,))
|
self._database.commit()
|
||||||
self._database.commit()
|
|
||||||
|
@@ -20,12 +20,11 @@ class User(Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def password(self)->str:
|
def password(self)->str:
|
||||||
self._database.execute("SELECT password FROM users WHERE login = ?",(self.login,))
|
cursor=self._database.execute("SELECT password FROM users WHERE login = ?",(self.login,))
|
||||||
return self._database.fetchone()[0]
|
return cursor.fetchone()[0]
|
||||||
|
|
||||||
@password.setter
|
@password.setter
|
||||||
def password(self,value:str):
|
def password(self,value:str):
|
||||||
with self._database.semaphore:
|
|
||||||
self._database.execute("UPDATE users SET password = ? WHERE login = ?",(self.hashpassword(value),self.login))
|
self._database.execute("UPDATE users SET password = ? WHERE login = ?",(self.hashpassword(value),self.login))
|
||||||
self._database.commit()
|
self._database.commit()
|
||||||
|
|
||||||
@@ -72,12 +71,11 @@ class User(Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def subnetid(self):
|
def subnetid(self):
|
||||||
self._database.execute("SELECT subnetid FROM users WHERE login = ?",(self.login,))
|
cursor=self._database.execute("SELECT subnetid FROM users WHERE login = ?",(self.login,))
|
||||||
return self._database.fetchone()[0]
|
return cursor.fetchone()[0]
|
||||||
|
|
||||||
@subnetid.setter
|
@subnetid.setter
|
||||||
def subnetid(self,value):
|
def subnetid(self,value):
|
||||||
with self._database.semaphore:
|
|
||||||
self._database.execute("UPDATE users SET subnetid = ? WHERE login = ?",(value,self.login))
|
self._database.execute("UPDATE users SET subnetid = ? WHERE login = ?",(value,self.login))
|
||||||
self._database.commit()
|
self._database.commit()
|
||||||
|
|
||||||
@@ -87,9 +85,9 @@ class User(Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def networks(self)->list[Network]:
|
def networks(self)->list[Network]:
|
||||||
self._database.execute("""SELECT id from networks WHERE id IN
|
cursor=self._database.execute("""SELECT id from networks WHERE id IN
|
||||||
(SELECT networkid FROM networkUsers WHERE userid = ? OR subnetid = ?);""",(self.login,self.subnetid))
|
(SELECT networkid FROM networkUsers WHERE userid = ? OR subnetid = ?);""",(self.login,self.subnetid))
|
||||||
networks = self._database.fetchall()
|
networks = cursor.fetchall()
|
||||||
networksDB = Networks(self._database)
|
networksDB = Networks(self._database)
|
||||||
return [networksDB.getNetworkById(res[0]) for res in networks]
|
return [networksDB.getNetworkById(res[0]) for res in networks]
|
||||||
|
|
||||||
@@ -98,8 +96,8 @@ class User(Model):
|
|||||||
self._database.commit()
|
self._database.commit()
|
||||||
|
|
||||||
def get_network_permission(self,net:Network)->int:
|
def get_network_permission(self,net:Network)->int:
|
||||||
self._database.execute("SELECT permissions FROM networkUsers WHERE userid = ? AND networkid = ?",(self.login,net.id))
|
cursor=self._database.execute("SELECT permissions FROM networkUsers WHERE userid = ? AND networkid = ?",(self.login,net.id))
|
||||||
perm = self._database.fetchone()
|
perm = cursor.fetchone()
|
||||||
if(not perm):
|
if(not perm):
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
@@ -107,28 +105,32 @@ class User(Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def subnetwork_permission(self)->SubnetworkPermission:
|
def subnetwork_permission(self)->SubnetworkPermission:
|
||||||
self._database.execute("SELECT subnetperm FROM users WHERE login = ?",(self.login,))
|
cursor=self._database.execute("SELECT subnetperm FROM users WHERE login = ?",(self.login,))
|
||||||
res = self._database.fetchone()
|
res = cursor.fetchone()
|
||||||
assert(res)
|
assert(res)
|
||||||
return SubnetworkPermission(res[0])
|
return SubnetworkPermission(res[0])
|
||||||
|
|
||||||
class Users():
|
class Users(Model):
|
||||||
|
|
||||||
def __init__(self,database_handler:DatabaseHandler):
|
def __init__(self,database_handler:DatabaseHandler):
|
||||||
self._database = database_handler
|
super().__init__(database_handler)
|
||||||
self._database.execute("SELECT * FROM users LIMIT 1")
|
self.initUsers()
|
||||||
if(self._database.fetchone()==None):
|
|
||||||
|
def initUsers(self):
|
||||||
|
cursor=self._database.execute("SELECT * FROM users LIMIT 1")
|
||||||
|
if(cursor.fetchone()==None):
|
||||||
self.createUser('admin','admin')
|
self.createUser('admin','admin')
|
||||||
|
|
||||||
def getUserFromLogin(self,login:str):
|
def getUserFromLogin(self,login:str):
|
||||||
self._database.execute("SELECT * FROM users WHERE login = ?",(login,))
|
cursor=self._database.execute("SELECT * FROM users WHERE login = ?",(login,))
|
||||||
if(self._database.fetchone()):
|
if(cursor.fetchone()):
|
||||||
return User(self._database,login)
|
return User(self._database,login)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_users_in_subnet(self,subnetid:int):
|
def get_users_in_subnet(self,subnetid:int):
|
||||||
self._database.execute("SELECT login FROM users WHERE subnetid = ?",(subnetid,))
|
cursor=self._database.execute("SELECT login FROM users WHERE subnetid = ?",(subnetid,))
|
||||||
return [self.getUserFromLogin(res[0]) for res in self._database.fetchall()]
|
return [self.getUserFromLogin(res[0]) for res in cursor.fetchall()]
|
||||||
|
|
||||||
def createUser(self,login:str,password:str,subnetid=None):
|
def createUser(self,login:str,password:str,subnetid=None):
|
||||||
if(self.getUserFromLogin(login)):
|
if(self.getUserFromLogin(login)):
|
||||||
@@ -139,15 +141,13 @@ class Users():
|
|||||||
subnetid = random.getrandbits(32)
|
subnetid = random.getrandbits(32)
|
||||||
subnetperm |= SubnetworkPermission.OWNER
|
subnetperm |= SubnetworkPermission.OWNER
|
||||||
#TODO : make sure subnetid is uniq
|
#TODO : make sure subnetid is uniq
|
||||||
with self._database.semaphore:
|
cursor=self._database.execute("INSERT INTO users VALUES(?,?,?,?)",(login,User.hashpassword(password),subnetid,int(subnetperm)))
|
||||||
self._database.execute("INSERT INTO users VALUES(?,?,?,?)",(login,User.hashpassword(password),subnetid,int(subnetperm)))
|
self._database.commit()
|
||||||
self._database.commit()
|
|
||||||
return self.getUserFromLogin(login)
|
return self.getUserFromLogin(login)
|
||||||
|
|
||||||
def deleteUser(self,user:User):
|
def deleteUser(self,user:User):
|
||||||
subnetwork = user.subnetid
|
subnetwork = user.subnetid
|
||||||
with self._database.semaphore:
|
self._database.execute("DELETE FROM users WHERE login = ?",(user.login,))
|
||||||
self._database.execute("DELETE FROM users WHERE login = ?",(user.login,))
|
if(not self._database.execute("SELECT * FROM users WHERE subnetid = ?",(subnetwork,)).fetchall()):
|
||||||
if(not self._database.execute("SELECT * FROM users WHERE subnetid = ?",(subnetwork,)).fetchall()):
|
self._database.execute("DELETE FROM networks WHERE subnetid = ?",(subnetwork,))
|
||||||
self._database.execute("DELETE FROM networks WHERE subnetid = ?",(subnetwork,))
|
self._database.commit()
|
||||||
self._database.commit()
|
|
@@ -6,8 +6,8 @@ class WebSessions(Model):
|
|||||||
|
|
||||||
def getSession(self,sid:int):
|
def getSession(self,sid:int):
|
||||||
"""Return the user the session belong to or False"""
|
"""Return the user the session belong to or False"""
|
||||||
self._database.execute("SELECT sid,login FROM sessions WHERE sid = ?",(sid,))
|
cursor=self._database.execute("SELECT sid,login FROM sessions WHERE sid = ?",(sid,))
|
||||||
res = self._database.fetchone()
|
res = cursor.fetchone()
|
||||||
if(res):
|
if(res):
|
||||||
return Users(self._database).getUserFromLogin(res[1])
|
return Users(self._database).getUserFromLogin(res[1])
|
||||||
else:
|
else:
|
||||||
@@ -16,12 +16,10 @@ class WebSessions(Model):
|
|||||||
def createSession(self,user:User):
|
def createSession(self,user:User):
|
||||||
"""Create a session for the user. Return the session id"""
|
"""Create a session for the user. Return the session id"""
|
||||||
sid = getrandbits(32)
|
sid = getrandbits(32)
|
||||||
with self._database.semaphore:
|
self._database.execute("INSERT INTO sessions VALUES (?,?)",(sid,user.login))
|
||||||
self._database.execute("INSERT INTO sessions VALUES (?,?)",(sid,user.login))
|
self._database.commit()
|
||||||
self._database.commit()
|
|
||||||
return sid
|
return sid
|
||||||
|
|
||||||
def deleteSession(self,sid:int):
|
def deleteSession(self,sid:int):
|
||||||
with self._database.semaphore:
|
self._database.execute("DELETE FROM sessions WHERE sid = ?",(sid,))
|
||||||
self._database.execute("DELETE FROM sessions WHERE sid = ?",(sid,))
|
self._database.commit()
|
||||||
self._database.commit()
|
|
Reference in New Issue
Block a user