forked from Infra/risotto
simplify session's code
This commit is contained in:
parent
bb1fdcbad0
commit
b944a609a5
|
@ -13,19 +13,18 @@ from ...register import register
|
|||
from ...config import ROOT_CACHE_DIR, DATABASE_DIR, DEBUG, ROUGAIL_DTD_PATH
|
||||
from ...context import Context
|
||||
from ...utils import _
|
||||
from ...error import CallError, NotAllowedError, RegistrationError
|
||||
from ...error import CallError, RegistrationError
|
||||
from ...logger import log
|
||||
|
||||
|
||||
if not isdir(ROOT_CACHE_DIR):
|
||||
raise RegistrationError(_(f'unable to find the cache dir "{ROOT_CACHE_DIR}"'))
|
||||
|
||||
|
||||
class Risotto(Controller):
|
||||
servermodel = {}
|
||||
server = {}
|
||||
|
||||
def __init__(self) -> None:
|
||||
for dirname in [ROOT_CACHE_DIR, DATABASE_DIR, ROUGAIL_DTD_PATH]:
|
||||
if not isdir(dirname):
|
||||
raise RegistrationError(_(f'unable to find the cache dir "{dirname}"'))
|
||||
self.save_storage = Storage(engine='sqlite3', dir_database=DATABASE_DIR)
|
||||
super().__init__()
|
||||
|
||||
|
|
|
@ -21,19 +21,47 @@ class Risotto(Controller):
|
|||
def __init__(self):
|
||||
self.modify_storage = Storage(engine='dictionary')
|
||||
|
||||
def valid_user(self,
|
||||
session_id: str,
|
||||
risotto_context: Context,
|
||||
type: str) -> None:
|
||||
""" check if current user is the session owner
|
||||
def get_storage(self,
|
||||
type: str):
|
||||
if type == 'server':
|
||||
return storage_server
|
||||
return storage_servermodel
|
||||
|
||||
def get_session(self,
|
||||
session_id: str,
|
||||
type: str) -> Dict:
|
||||
""" Get session information from storage
|
||||
"""
|
||||
if type == 'server':
|
||||
storage = storage_server
|
||||
else:
|
||||
storage = storage_servermodel
|
||||
username = risotto_context.username
|
||||
if username != storage.get_session(session_id)['username']:
|
||||
raise NotAllowedError()
|
||||
return storage.get_session(session_id)
|
||||
|
||||
def get_session_informations(self,
|
||||
risotto_context: Context,
|
||||
session_id: str,
|
||||
type: str) -> Dict:
|
||||
""" format session with a session ID name
|
||||
"""
|
||||
session = self.get_session(session_id,
|
||||
type,
|
||||
risotto_context.username)
|
||||
return self.format_session(session_id,
|
||||
session)
|
||||
|
||||
def format_session(self,
|
||||
session_name: str,
|
||||
session: Dict) -> Dict:
|
||||
""" format session
|
||||
"""
|
||||
return {'session_id': session_name,
|
||||
'id': session['id'],
|
||||
'username': session['username'],
|
||||
'timestamp': session['timestamp'],
|
||||
'namespace': session['namespace'],
|
||||
'mode': session['mode'],
|
||||
'debug': session['debug']}
|
||||
|
||||
@register(['v1.session.server.start', 'v1.session.servermodel.start'], None)
|
||||
async def start_session(self,
|
||||
|
@ -46,44 +74,47 @@ class Risotto(Controller):
|
|||
if type == 'server':
|
||||
if id not in config_module.server:
|
||||
raise Exception(_(f'cannot find {type} with id {id}'))
|
||||
server = config_module.server[id]
|
||||
config = server['server']
|
||||
storage = storage_server
|
||||
config = config_module.server[id]['server']
|
||||
else:
|
||||
if id not in config_module.servermodel:
|
||||
raise Exception(_(f'cannot find {type} with id {id}'))
|
||||
config = config_module.servermodel[id]
|
||||
storage = storage_servermodel
|
||||
|
||||
# check if a session already exists, in this case returns it
|
||||
session_list = self.list_sessions(type)
|
||||
for sess in session_list:
|
||||
if sess['id'] == id and sess['username'] == risotto_context.username:
|
||||
session_id = sess['session_id']
|
||||
session = self.get_session(session_id, type)
|
||||
return self.format_session(session_id, session)
|
||||
storage = self.get_storage(type)
|
||||
|
||||
# check if a session already exists
|
||||
sessions = storage.get_sessions()
|
||||
for session in sessions.values():
|
||||
if sess['id'] == id:
|
||||
if sess['username'] == risotto_context.username:
|
||||
# same user so returns it
|
||||
return self.format_session(session['session_id'], session)
|
||||
else:
|
||||
raise CallError(_(f'{username} already edits this configuration'))
|
||||
|
||||
# create a new session
|
||||
while True:
|
||||
session_id = 'z' + hexlify(urandom(23)).decode()
|
||||
if not storage.has_session(session_id):
|
||||
if not session_id in sessions:
|
||||
break
|
||||
else:
|
||||
print('session {} already exists'.format(session_id))
|
||||
username = risotto_context.username
|
||||
storage.add_session(session_id,
|
||||
config,
|
||||
id,
|
||||
username,
|
||||
risotto_context.username,
|
||||
self.modify_storage)
|
||||
|
||||
# return session's information
|
||||
return self.get_session_informations(session_id,
|
||||
type)
|
||||
|
||||
@register(['v1.session.server.list', 'v1.session.servermodel.list'], None)
|
||||
async def list_session_server(self,
|
||||
risotto_context: Context):
|
||||
risotto_context: Context) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
return self.list_sessions(type)
|
||||
storage = self.get_storage(type,
|
||||
risotto_context.username)
|
||||
return [self.format_session(session_id, session) or session_id, session in storage.get_sessions().items()]
|
||||
|
||||
|
||||
@register(['v1.session.server.filter', 'v1.session.servermodel.filter'], None)
|
||||
async def filter_session(self,
|
||||
|
@ -93,10 +124,10 @@ class Risotto(Controller):
|
|||
mode: str,
|
||||
debug: Optional[bool]):
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
if type == 'server':
|
||||
storage = storage_server
|
||||
else:
|
||||
storage = storage_servermodel
|
||||
storage = self.get_storage(type)
|
||||
# to validate the session right
|
||||
storage.get_session(session_id,
|
||||
username)
|
||||
if namespace is not None:
|
||||
storage.set_namespace(session_id,
|
||||
namespace)
|
||||
|
@ -122,11 +153,9 @@ class Risotto(Controller):
|
|||
value_multi: Optional[List]) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
session = self.get_session(session_id,
|
||||
type)
|
||||
ret = {'session_id': session_id,
|
||||
'name': name}
|
||||
if index is not None:
|
||||
ret['index'] = index
|
||||
type,
|
||||
risotto_context.username)
|
||||
# if multi and not follower the value is in fact in value_multi
|
||||
option = session['config'].option(name).option
|
||||
if option.ismulti() and not option.isfollower():
|
||||
value = value_multi
|
||||
|
@ -138,12 +167,14 @@ class Risotto(Controller):
|
|||
update['index'] = index
|
||||
updates = {'updates': [update]}
|
||||
session['option'].updates(updates)
|
||||
ret['status'] = 'ok'
|
||||
except Exception as err:
|
||||
if DEBUG:
|
||||
print_exc()
|
||||
ret['message'] = str(err)
|
||||
ret['status'] = 'error'
|
||||
raise CallError(str(err))
|
||||
ret = {'session_id': session_id,
|
||||
'name': name}
|
||||
if index is not None:
|
||||
ret['index'] = index
|
||||
return ret
|
||||
|
||||
@register(['v1.session.server.validate', 'v1.session.servermodel.validate'], None)
|
||||
|
@ -151,37 +182,36 @@ class Risotto(Controller):
|
|||
risotto_context: Context,
|
||||
session_id: str) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
session = self.get_session(session_id, type)
|
||||
ret = {}
|
||||
session = self.get_session(session_id,
|
||||
type,
|
||||
risotto_context.username)
|
||||
try:
|
||||
session['config'].forcepermissive.option(session['namespace']).value.dict()
|
||||
except Exception as err:
|
||||
ret['status'] = 'error'
|
||||
ret['message'] = str(err)
|
||||
else:
|
||||
if type == 'server':
|
||||
mandatories = list(session['config'].forcepermissive.value.mandatory())
|
||||
if mandatories:
|
||||
ret['status'] = 'incomplete'
|
||||
ret['mandatories'] = mandatories
|
||||
raise CallError(str(err))
|
||||
if type == 'server':
|
||||
mandatories = list(session['config'].forcepermissive.value.mandatory())
|
||||
if mandatories:
|
||||
if len(mandatories) == 1:
|
||||
mandatories = mandatories[0]
|
||||
msg = _('the parameter "--{mandatories}" is mandatory')
|
||||
else:
|
||||
ret['status'] = 'ok'
|
||||
else:
|
||||
ret['status'] = 'ok'
|
||||
return ret
|
||||
mandatories = '", "--'.join(mandatories)
|
||||
msg = _('parameters "{mandatories}" are mandatories')
|
||||
raise CallError(msg)
|
||||
return self.format_session(session_id,
|
||||
session)
|
||||
|
||||
@register(['v1.session.server.get', 'v1.session.servermodel.get'], None)
|
||||
async def get_session_(self,
|
||||
risotto_context: Context,
|
||||
session_id: str) -> Dict:
|
||||
async def get_session_server(self,
|
||||
risotto_context: Context,
|
||||
session_id: str) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
info = self.get_session_informations(session_id,
|
||||
type)
|
||||
info['content'] = session_id
|
||||
session = self.get_session(session_id,
|
||||
type)
|
||||
type,
|
||||
risotto_context.username)
|
||||
info = self.format_session(session_id, session)
|
||||
info['content'] = dumps(session['option'].value.dict(fullpath=True))
|
||||
|
||||
return info
|
||||
|
||||
@register(['v1.session.server.stop', 'v1.session.servermodel.stop'], None)
|
||||
|
@ -190,18 +220,14 @@ class Risotto(Controller):
|
|||
session_id: str,
|
||||
save: bool) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
self.valid_user(session_id,
|
||||
risotto_context,
|
||||
type)
|
||||
session = self.get_session(session_id,
|
||||
type)
|
||||
storage = self.get_storage(type)
|
||||
session = storage.get_session(session_id,
|
||||
risotto_context.username)
|
||||
id_ = session['id']
|
||||
config_module = dispatcher.get_service('config')
|
||||
if type == 'server':
|
||||
storage = storage_server
|
||||
config = config_module.server[id_]['server']
|
||||
else:
|
||||
storage = storage_servermodel
|
||||
config = config_module.servermodel[id_]
|
||||
if save:
|
||||
modif_config = session['config']
|
||||
|
@ -215,66 +241,15 @@ class Risotto(Controller):
|
|||
request,
|
||||
risotto_context: Context,
|
||||
session_id: str) -> Dict:
|
||||
self.valid_user(session_id,
|
||||
risotto_context,
|
||||
'server')
|
||||
session = storage_server.get_session(session_id)
|
||||
return self.load_dict(session)
|
||||
session = storage_server.get_session(session_id,
|
||||
risotto_context.username)
|
||||
return session['option'].dict(remotable='all')
|
||||
|
||||
@register_http('v1', '/config/servermodel/{session_id}')
|
||||
async def get_servermodel_api(self,
|
||||
request,
|
||||
risotto_context: Context,
|
||||
session_id: str) -> Dict:
|
||||
self.valid_user(session_id,
|
||||
risotto_context,
|
||||
'servermodel')
|
||||
session = storage_servermodel.get_session(session_id)
|
||||
return self.load_dict(session)
|
||||
|
||||
def get_session(self,
|
||||
session_id: str,
|
||||
type: str) -> Dict:
|
||||
""" Get session information from storage
|
||||
"""
|
||||
if type == 'server':
|
||||
return storage_server.get_session(session_id)
|
||||
return storage_servermodel.get_session(session_id)
|
||||
|
||||
def get_session_informations(self,
|
||||
session_id: str,
|
||||
type: str) -> Dict:
|
||||
""" format session with a session ID name
|
||||
"""
|
||||
session = self.get_session(session_id,
|
||||
type)
|
||||
return self.format_session(session_id,
|
||||
session)
|
||||
|
||||
def format_session(self,
|
||||
session_name: str,
|
||||
session: Dict) -> Dict:
|
||||
""" format session
|
||||
"""
|
||||
return {'session_id': session_name,
|
||||
'id': session['id'],
|
||||
'username': session['username'],
|
||||
'timestamp': session['timestamp'],
|
||||
'namespace': session['namespace'],
|
||||
'mode': session['mode'],
|
||||
'debug': session['debug']}
|
||||
|
||||
def list_sessions(self,
|
||||
type: str) -> List:
|
||||
ret = []
|
||||
if type == 'server':
|
||||
storage = storage_server
|
||||
else:
|
||||
storage = storage_servermodel
|
||||
for session_id, session in storage.get_sessions().items():
|
||||
ret.append(self.format_session(session_id, session))
|
||||
return ret
|
||||
|
||||
def load_dict(self,
|
||||
session: Dict) -> Dict:
|
||||
session = storage_servermodel.get_session(session_id,
|
||||
risotto_context.username)
|
||||
return session['option'].dict(remotable='all')
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import time
|
||||
from typing import Dict
|
||||
from tiramisu import Config
|
||||
from rougail import modes
|
||||
from ...error import CallError, NotAllowedError
|
||||
|
||||
|
||||
class StorageError(Exception):
|
||||
|
@ -13,23 +15,15 @@ class Storage(object):
|
|||
def __init__(self):
|
||||
self.sessions = {}
|
||||
|
||||
def has_session(self,
|
||||
id: int):
|
||||
return id in self.sessions
|
||||
|
||||
def add_session(self,
|
||||
session_id: int,
|
||||
orig_config: Config,
|
||||
server_id: int,
|
||||
username: str,
|
||||
config_storage):
|
||||
for session in self.sessions.values():
|
||||
if session['id'] == server_id:
|
||||
raise Storage(_(f'{username} already edits this configuration'))
|
||||
prefix_id = f'{session_id}_'
|
||||
config_name = self.get_config_name(server_id)
|
||||
config_id = f'{prefix_id}{config_name}'
|
||||
print(config_id)
|
||||
|
||||
# copy Config and all it's parents
|
||||
meta = orig_config.config.deepcopy(session_id=config_id,
|
||||
|
@ -41,11 +35,12 @@ class Storage(object):
|
|||
while True:
|
||||
try:
|
||||
children = list(config.config.list())
|
||||
except:
|
||||
break
|
||||
if children:
|
||||
if not children:
|
||||
# it's an empty metaconfig
|
||||
break
|
||||
config = children[0]
|
||||
else:
|
||||
except:
|
||||
# it's a config, so no "list" method
|
||||
break
|
||||
config.property.read_write()
|
||||
# set the default owner
|
||||
|
@ -66,35 +61,12 @@ class Storage(object):
|
|||
self.set_namespace(session_id,
|
||||
'creole')
|
||||
|
||||
def set_namespace(self,
|
||||
session_id: int,
|
||||
namespace: str):
|
||||
self.sessions[session_id]['option'] = self.sessions[session_id]['config'].option(namespace)
|
||||
self.sessions[session_id]['namespace'] = namespace
|
||||
|
||||
def get_sessions(self):
|
||||
return self.sessions;
|
||||
|
||||
def del_session(self,
|
||||
id: int):
|
||||
del self.sessions[id]
|
||||
|
||||
def get_session(self,
|
||||
id: int):
|
||||
if id not in self.sessions:
|
||||
raise Exception(f'the session {id} not exists')
|
||||
return self.sessions[id]
|
||||
|
||||
def get_username(self,
|
||||
id: int):
|
||||
return self.get_session(id)['username']
|
||||
|
||||
def set_config_mode(self,
|
||||
id: int,
|
||||
mode: str):
|
||||
""" Define which edition mode to select
|
||||
"""
|
||||
config = self.get_session(id)['config']
|
||||
config = self.session[id]['config']
|
||||
for mode_level in modes.values():
|
||||
if modes[mode] < mode_level:
|
||||
config.property.add(mode_level.name)
|
||||
|
@ -105,13 +77,35 @@ class Storage(object):
|
|||
def set_config_debug(self, id_, is_debug):
|
||||
""" Enable/Disable debug mode
|
||||
"""
|
||||
config = self.get_session(id_)['config']
|
||||
config = self.session[id_]['config']
|
||||
if is_debug:
|
||||
config.property.pop('hidden')
|
||||
else:
|
||||
config.property.add('hidden')
|
||||
self.sessions[id_]['debug'] = is_debug
|
||||
|
||||
def set_namespace(self,
|
||||
session_id: int,
|
||||
namespace: str):
|
||||
self.sessions[session_id]['option'] = self.sessions[session_id]['config'].option(namespace)
|
||||
self.sessions[session_id]['namespace'] = namespace
|
||||
|
||||
def get_sessions(self):
|
||||
return self.sessions;
|
||||
|
||||
def get_session(self,
|
||||
id: int,
|
||||
username: str) -> Dict:
|
||||
if id not in self.sessions:
|
||||
raise Exception(f'the session {id} not exists')
|
||||
if username != storage.get_session(session_id)['username']:
|
||||
raise NotAllowedError()
|
||||
return self.sessions[id]
|
||||
|
||||
def del_session(self,
|
||||
id: int):
|
||||
del self.sessions[id]
|
||||
|
||||
|
||||
class StorageServer(Storage):
|
||||
def get_config_name(self,
|
||||
|
|
Loading…
Reference in New Issue