From d5dd1d471b0c16caf395e32996cb7caa25fce326 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:13:44 +0200 Subject: rename --- src-py/rhizi_server.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src-py/rhizi_server.py (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py new file mode 100644 index 00000000..5393a61e --- /dev/null +++ b/src-py/rhizi_server.py @@ -0,0 +1,59 @@ +import logging +import json +import util +import neo4j_util + +import db_controller as dbc +import rhizi_api + +class Config(object): + """ + rhizi-server configuration + """ + + @staticmethod + def init_from_file(file_path): + ret = Config() + + with open(file_path, 'r') as f: + cfg = json.loads(f.read()) + + # + # TODO: config option documentation + # + ret.neo4j_url = cfg['neo4j_url'] + ret.listen_address = cfg['listen_address'] + ret.listen_port = cfg['listen_port'] + + return ret + + @property + def db_base_url(self): + return self.neo4j_url + + @property + def tx_api_path(self): + return '/db/data/transaction' + +def init_logging(): + + log = logging.getLogger('rhizi') + log.setLevel(logging.DEBUG) + log_handler_c = logging.StreamHandler() + log_handler_f = logging.FileHandler('/tmp/rhizi-server.log') + + log.addHandler(log_handler_c) + log.addHandler(log_handler_f) + +class RhiziServer(object): + pass + +if __name__ == "__main__": + + init_logging() + + cfg = Config.init_from_file('res/etc/rhizi-server.conf') + db_ctl = dbc.DB_Controller(cfg) + + rhizi_api.db_ctl = db_ctl + rhizi_api.webapp.run(host=cfg.listen_address, port=cfg.listen_port) -- cgit v1.3.1 From 60890e054075d92be557f9a7da6f29b5e8ec9f90 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 13:32:22 +0200 Subject: config-dir command line arg --- src-py/rhizi_server.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 5393a61e..c9bc65e6 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -1,8 +1,9 @@ import logging import json import util +import os import neo4j_util - +import argparse import db_controller as dbc import rhizi_api @@ -15,6 +16,9 @@ class Config(object): def init_from_file(file_path): ret = Config() + if False == os.path.exists(file_path): + raise Exception('config file not found: ' + file_path) + with open(file_path, 'r') as f: cfg = json.loads(f.read()) @@ -50,9 +54,15 @@ class RhiziServer(object): if __name__ == "__main__": + p = argparse.ArgumentParser(description='rhizi-server') + p.add_argument('--config-dir', help='path to Rhizi config dir') + args = p.parse_args() + + cfg_dir = args.config_dir + init_logging() - cfg = Config.init_from_file('res/etc/rhizi-server.conf') + cfg = Config.init_from_file(os.path.join(cfg_dir, 'rhizi-server.conf')) db_ctl = dbc.DB_Controller(cfg) rhizi_api.db_ctl = db_ctl -- cgit v1.3.1 From 72aa3ff93981e078357ba30682b12c600b08f2df Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Mon, 17 Nov 2014 19:55:25 +0200 Subject: add default argument to --config-dir --- src-py/rhizi_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index c9bc65e6..49d762d6 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -55,7 +55,7 @@ class RhiziServer(object): if __name__ == "__main__": p = argparse.ArgumentParser(description='rhizi-server') - p.add_argument('--config-dir', help='path to Rhizi config dir') + p.add_argument('--config-dir', help='path to Rhizi config dir', default='res/etc') args = p.parse_args() cfg_dir = args.config_dir -- cgit v1.3.1 From da5792f2fc055fec121a1c552bb628bdd2dbdbd8 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 24 Nov 2014 14:32:37 +0200 Subject: rhizi_server.py: add hash bang --- src-py/rhizi_server.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 49d762d6..f085e863 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -1,3 +1,5 @@ +#!/usr/bin/python + import logging import json import util -- cgit v1.3.1 From 23bb05b2f506743bf9c0008f8a7d9dd68bfa326e Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 30 Nov 2014 12:36:10 +0200 Subject: applicative REST API init - provides logic<>web-framework decoupling --- src-py/rhizi_api.py | 12 ------------ src-py/rhizi_server.py | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 12 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 6bc77cb6..7391c90f 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -31,8 +31,6 @@ class FlaskExt(Flask): ret.headers['Access-Control-Allow-Headers'] = "Origin, Content-Type, Accept, Authorization" return ret -webapp = FlaskExt(__name__) -webapp.debug = True # injected: DB controller db_ctl = None @@ -69,7 +67,6 @@ def __common_exec(op, on_success=__common_resp_handle): log.error(traceback.print_exc()) return __common_resp_handle('error occurred') -@webapp.route("/load/node-set-by-id", methods=['POST']) def load_node_set_by_id_attr(): """ load node-set by ID attribute @@ -99,7 +96,6 @@ def __load_node_set_by_id_attr_common(id_set): log.exception(e) return __common_resp_handle(error='unable to load node with ids: {0}'.format(id_set)) -@webapp.route("/match/node-set", methods=['POST']) def match_node_set_by_attr_filter_map(attr_filter_map): """ @param attr_filter_map @@ -109,7 +105,6 @@ def match_node_set_by_attr_filter_map(attr_filter_map): op = dbc.DBO_match_node_id_set(attr_filter_map) return __common_exec(op) -@webapp.route("/load/link-set/by_link_ptr_set", methods=['POST']) def load_link_set_by_link_ptr_set(): def deserialize_param_set(param_json): @@ -130,12 +125,10 @@ def load_link_set_by_link_ptr_set(): op = dbc.DBO_load_link_set.init_from_link_ptr_set(l_ptr_set) return __common_exec(op) -@webapp.route("/graph/clone", methods=['POST']) def rz_clone(): op = dbc.DBO_rz_clone() return __common_exec(op) -@webapp.route("/graph/diff-commit-set", methods=['POST']) def diff_commit_set(): """ commit a diff set @@ -150,7 +143,6 @@ def diff_commit_set(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -@webapp.route("/graph/diff-commit-topo", methods=['POST']) def diff_commit_topo(): """ commit a graph topology diff @@ -164,7 +156,6 @@ def diff_commit_topo(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -@webapp.route("/graph/diff-commit-attr", methods=['POST']) def diff_commit_attr(): """ commit a graph attribute diff @@ -175,11 +166,9 @@ def diff_commit_attr(): op = dbc.DBO_attr_diff_commit(attr_diff) return __common_exec(op) -@webapp.route("/graph/diff-commit-vis", methods=['POST']) def diff_commit_vis(): pass -@webapp.route("/add/node-set", methods=['POST']) def add_node_set(): """ @deprecated: use topo_attr_commit @@ -192,7 +181,6 @@ def add_node_set(): op = dbc.DBO_add_node_set(node_map) return __common_exec(op) -@webapp.route("/monitor/server-info", methods=['GET']) def monitor__server_info(): """ server monitor stub diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index f085e863..cef57f36 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -54,6 +54,33 @@ def init_logging(): class RhiziServer(object): pass +def init_rest_api(flask_webapp): + """ + map REST API calls + """ + rest_entry_set = [ + rest_entry('/add/node-set' , rhizi_api.add_node_set), + rest_entry('/graph/clone', rhizi_api.rz_clone), + rest_entry('/graph/diff-commit-set', rhizi_api.diff_commit_set), + rest_entry('/graph/diff-commit-topo', rhizi_api.diff_commit_topo), + rest_entry('/graph/diff-commit-attr', rhizi_api.diff_commit_attr), + rest_entry('/graph/diff-commit-vis', rhizi_api.diff_commit_vis), + rest_entry('/index', rhizi_api.index), + rest_entry('/load/node-set-by-id', rhizi_api.load_node_set_by_id_attr), + rest_entry('/load/link-set/by_link_ptr_set', rhizi_api.load_link_set_by_link_ptr_set), + rest_entry('/login', rhizi_api.login, {'methods': ['GET', 'POST']}), + rest_entry('/logout', rhizi_api.logout), + rest_entry('/match/node-set', rhizi_api.match_node_set_by_attr_filter_map), + rest_entry('/monitor/server-info', rhizi_api.monitor__server_info), + ] + + for re in rest_entry_set: + rest_path, f, flask_args = re + route_decorator = flask_webapp.route(rest_path, **flask_args) + flask_webapp.f = route_decorator(f) + + if '/login' != rest_path: + if __name__ == "__main__": p = argparse.ArgumentParser(description='rhizi-server') -- cgit v1.3.1 From e97ade2d8cf8c0a927cd96bd07380ea35b499d98 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Tue, 2 Dec 2014 02:20:17 +0200 Subject: simplify config loading, allow missing config values --- src-py/rhizi_server.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index cef57f36..bda762a3 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -27,10 +27,16 @@ class Config(object): # # TODO: config option documentation # - ret.neo4j_url = cfg['neo4j_url'] - ret.listen_address = cfg['listen_address'] - ret.listen_port = cfg['listen_port'] + # htpasswd_path + # listen_address + # listen_port + # neo4j_url + # root_path + for k, v in cfg.items(): + ret.__setattr__(k, v) + + ret.__setattr__('config_dir', os.path.dirname(file_path)) # bypass prop restriction return ret @property @@ -41,6 +47,14 @@ class Config(object): def tx_api_path(self): return '/db/data/transaction' + @property + def config_dir_path(self): + return self.config_dir + + @property + def secret_key(self): + return self.SECRET_KEY + def init_logging(): log = logging.getLogger('rhizi') -- cgit v1.3.1 From d8af6c4be6120fab236f614fb93cb632fae174b5 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Tue, 2 Dec 2014 02:25:06 +0200 Subject: REST mapping: apply login_decorator() to all but /login paths --- src-py/rhizi_server.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index bda762a3..2edce5dd 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -72,6 +72,21 @@ def init_rest_api(flask_webapp): """ map REST API calls """ + + def rest_entry(path, f, flask_args={}): + return (path, f, flask_args) + + def login_decorator(f): + """ + check user is logged in before executing REST api call + """ + def wrapped_function(*args, **kw): + if not 'username' in session: + return redirect('/login') + return f(*args, **kw) + + return wrapped_function + rest_entry_set = [ rest_entry('/add/node-set' , rhizi_api.add_node_set), rest_entry('/graph/clone', rhizi_api.rz_clone), @@ -94,6 +109,9 @@ def init_rest_api(flask_webapp): flask_webapp.f = route_decorator(f) if '/login' != rest_path: + # currently require login on all but /login paths + flask_webapp.f = login_decorator(f) + if __name__ == "__main__": -- cgit v1.3.1 From 785610e63fb23d887764bad1094031324354c553 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Tue, 2 Dec 2014 02:27:17 +0200 Subject: refactor init functions --- src-py/rhizi_server.py | 48 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 2edce5dd..cd2b7d41 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -8,6 +8,12 @@ import neo4j_util import argparse import db_controller as dbc import rhizi_api +import flask +import crypt_util + +from flask import session +from flask import redirect +from flask import url_for class Config(object): """ @@ -55,6 +61,9 @@ class Config(object): def secret_key(self): return self.SECRET_KEY +class RhiziServer(object): + pass + def init_logging(): log = logging.getLogger('rhizi') @@ -64,9 +73,7 @@ def init_logging(): log.addHandler(log_handler_c) log.addHandler(log_handler_f) - -class RhiziServer(object): - pass + return log def init_rest_api(flask_webapp): """ @@ -112,19 +119,42 @@ def init_rest_api(flask_webapp): # currently require login on all but /login paths flask_webapp.f = login_decorator(f) +def init_webapp(cfg): + root_path = cfg.root_path + webapp = rhizi_api.FlaskExt(__name__, + static_folder='static', + template_folder=os.path.join(root_path, 'templates'), + static_url_path='') + webapp.config.from_object(cfg) + webapp.root_path = root_path # for some reason calling config.from_pyfile() + + db_ctl = dbc.DB_Controller(cfg) + rhizi_api.db_ctl = db_ctl + + webapp.rz_config = cfg + return webapp + +def init_config(cfg_dir): + cfg_path = os.path.join(cfg_dir, 'rhizi-server.conf') + cfg = Config.init_from_file(cfg_path) + return cfg + if __name__ == "__main__": p = argparse.ArgumentParser(description='rhizi-server') p.add_argument('--config-dir', help='path to Rhizi config dir', default='res/etc') + p.add_argument('--init-htpasswd-db', help='init login htpasswd db', action='store_const', const=True) args = p.parse_args() - cfg_dir = args.config_dir + log = init_logging() + cfg = init_config(args.config_dir) - init_logging() - cfg = Config.init_from_file(os.path.join(cfg_dir, 'rhizi-server.conf')) - db_ctl = dbc.DB_Controller(cfg) + webapp = init_webapp(cfg) + init_rest_api(webapp) + + log.info('launching webapp via Flusk development server') + webapp.run(host=cfg.listen_address, + port=cfg.listen_port) - rhizi_api.db_ctl = db_ctl - rhizi_api.webapp.run(host=cfg.listen_address, port=cfg.listen_port) -- cgit v1.3.1 From 52719d012c314eb03240b95c6b34e0d0c85fd08e Mon Sep 17 00:00:00 2001 From: LV-426 Date: Wed, 3 Dec 2014 16:50:08 +0200 Subject: refactor init_rest_api() --- src-py/rhizi_server.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index cd2b7d41..1efa684f 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -80,13 +80,14 @@ def init_rest_api(flask_webapp): map REST API calls """ - def rest_entry(path, f, flask_args={}): + def rest_entry(path, f, flask_args={'methods': ['POST']}): return (path, f, flask_args) def login_decorator(f): """ - check user is logged in before executing REST api call + [!] security boundary: asserd logged-in user before executing REST api call """ + @wraps(f) def wrapped_function(*args, **kw): if not 'username' in session: return redirect('/login') @@ -101,23 +102,27 @@ def init_rest_api(flask_webapp): rest_entry('/graph/diff-commit-topo', rhizi_api.diff_commit_topo), rest_entry('/graph/diff-commit-attr', rhizi_api.diff_commit_attr), rest_entry('/graph/diff-commit-vis', rhizi_api.diff_commit_vis), - rest_entry('/index', rhizi_api.index), + rest_entry('/index', rhizi_api.index, {'methods': ['GET']}), rest_entry('/load/node-set-by-id', rhizi_api.load_node_set_by_id_attr), rest_entry('/load/link-set/by_link_ptr_set', rhizi_api.load_link_set_by_link_ptr_set), rest_entry('/login', rhizi_api.login, {'methods': ['GET', 'POST']}), - rest_entry('/logout', rhizi_api.logout), + rest_entry('/logout', rhizi_api.logout, {'methods': ['GET', 'POST']}), rest_entry('/match/node-set', rhizi_api.match_node_set_by_attr_filter_map), rest_entry('/monitor/server-info', rhizi_api.monitor__server_info), ] - for re in rest_entry_set: - rest_path, f, flask_args = re - route_decorator = flask_webapp.route(rest_path, **flask_args) - flask_webapp.f = route_decorator(f) + for re_entry in rest_entry_set: + rest_path, f, flask_args = re_entry if '/login' != rest_path: # currently require login on all but /login paths - flask_webapp.f = login_decorator(f) + f = login_decorator(f) + + # [!] order seems important - apply route decorator last + route_dec = flask_webapp.route(rest_path, **flask_args) + f = route_dec(f) + + flask_webapp.f = f # assign decorated function def init_webapp(cfg): root_path = cfg.root_path -- cgit v1.3.1 From 64465e6647470731b868b87e19d995899bfd0d31 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Wed, 3 Dec 2014 16:50:31 +0200 Subject: mv server log path --- src-py/rhizi_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 1efa684f..15679db9 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -69,7 +69,7 @@ def init_logging(): log = logging.getLogger('rhizi') log.setLevel(logging.DEBUG) log_handler_c = logging.StreamHandler() - log_handler_f = logging.FileHandler('/tmp/rhizi-server.log') + log_handler_f = logging.FileHandler('/var/log/rhizi/rhizi-server.log') log.addHandler(log_handler_c) log.addHandler(log_handler_f) -- cgit v1.3.1 From ca876ae07e7d01a74e41707ec7510fc59a0445be Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sat, 6 Dec 2014 21:22:51 +0200 Subject: Config.init() - defaults, flask-key handling, type conversion --- src-py/rhizi_server.py | 58 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 15679db9..024e7246 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -18,33 +18,65 @@ from flask import url_for class Config(object): """ rhizi-server configuration + + TODO: config option documentation + + htpasswd_path + listen_address + listen_port + neo4j_url + root_path """ @staticmethod def init_from_file(file_path): - ret = Config() if False == os.path.exists(file_path): raise Exception('config file not found: ' + file_path) + # apply defaults + cfg = {} + cfg['access_control'] = True + cfg['config_dir'] = os.path.abspath(os.path.dirname(file_path)) # bypass prop restriction + cfg['development_mode'] = False + cfg['listen_address'] = '127.0.0.1' + cfg['listen_port'] = 8080 + cfg['root_path'] = os.getcwd() + cfg['static_url_path'] = '/static' + + # Flask keys + cfg['SECRET_KEY'] = '' + with open(file_path, 'r') as f: - cfg = json.loads(f.read()) + for line in f: + if re.match('(^#)|(\s+$)', line): + continue - # - # TODO: config option documentation - # - # htpasswd_path - # listen_address - # listen_port - # neo4j_url - # root_path + kv_arr = line.split('=') + if 2 != len(kv_arr): + raise Exception('failed to parse config line: ' + line) - for k, v in cfg.items(): - ret.__setattr__(k, v) + k, v = map(str.strip, kv_arr) - ret.__setattr__('config_dir', os.path.dirname(file_path)) # bypass prop restriction + if None != cfg.get(k): + # apply type conversion based on default value type + type_f = type(cfg[k]) + if bool == type_f: + v = v in ("True", "true") # workaround bool('false') = True + else: + v = type_f(v) + + # [!] we can't use k.lower() as we are loading Flask configuration + # keys which are expected to be capitalized + cfg[k] = v + + ret = Config() + ret.__dict__ = cfg # allows setting of @property attributes return ret + def __str__(self): + return '\n'.join('%s: %s' % (k, v) for k, v in self.__dict__.items()) + @property def db_base_url(self): return self.neo4j_url -- cgit v1.3.1 From f103eae07ae8a61845899879445d4bfadbb0e10d Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sat, 6 Dec 2014 21:23:20 +0200 Subject: mv FlaskExt --- src-py/rhizi_api.py | 13 ------------- src-py/rhizi_server.py | 26 +++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 16 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 95822be2..2ba25ad8 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -19,19 +19,6 @@ from datetime import datetime log = logging.getLogger('rhizi') -class FlaskExt(Flask): - """ - Flask server customization - """ - - def make_default_options_response(self): - # sup = super(Flask, self) - ret = Flask.make_default_options_response(self) - ret.headers['Access-Control-Allow-Origin'] = '*' - ret.headers['Access-Control-Allow-Headers'] = "Origin, Content-Type, Accept, Authorization" - return ret - - # injected: DB controller db_ctl = None diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 024e7246..58d4ee68 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -93,10 +93,30 @@ class Config(object): def secret_key(self): return self.SECRET_KEY -class RhiziServer(object): - pass +class FlaskExt(Flask): + """ + Flask server customization + """ + + def __init__(self, import_name, *args, **kwargs): + """ + reserved for future use + """ + super(FlaskExt, self).__init__(import_name, *args, **kwargs) -def init_logging(): + def before_request(self, *args, **kwargs): + # TODO impl + pass + + def make_default_options_response(self): + ret = Flask.make_default_options_response(self) + + ret.headers['Access-Control-Allow-Origin'] = 'http://rhizi.net' + ret.headers['Access-Control-Allow-Headers'] = "Accept, Authorization, Content-Type, Origin" + ret.headers['Access-Control-Allow-Credentials'] = 'true' + + # ret.headers['Access-Control-Allow-Methods'] = ', '.join(m_list) + return ret log = logging.getLogger('rhizi') log.setLevel(logging.DEBUG) -- cgit v1.3.1 From 79e4240cccf41de79be6bdd99aa9f0f4f68b04be Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sat, 6 Dec 2014 21:24:13 +0200 Subject: init_rest_api: dev_mode__resend_from_static() - see doc --- src-py/rhizi_server.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 58d4ee68..d93d285e 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -127,7 +127,7 @@ class FlaskExt(Flask): log.addHandler(log_handler_f) return log -def init_rest_api(flask_webapp): +def init_rest_api(cfg, flask_webapp): """ map REST API calls """ @@ -135,6 +135,22 @@ def init_rest_api(flask_webapp): def rest_entry(path, f, flask_args={'methods': ['POST']}): return (path, f, flask_args) + def dev_mode__resend_from_static(static_url): + """ + redirect broken-on-local-deploy links: + - /src -> '': handle root based files, eg. app.js + - /res, /lib -> res, lib + """ + static_folder = flask.current_app.static_folder + + static_path = request.path + if static_path.startswith('/src'): + # TODO: clean - /src/... links should not exist + static_path = static_path.replace('/src', '') + if static_path.startswith('/'): # convert to relative path + static_path = static_path[1:] + return send_from_directory(static_folder, static_path) + def login_decorator(f): """ [!] security boundary: asserd logged-in user before executing REST api call @@ -163,6 +179,15 @@ def init_rest_api(flask_webapp): rest_entry('/monitor/server-info', rhizi_api.monitor__server_info), ] + if cfg.development_mode: + dev_path_set = ['/src', '/res', '/lib'] + rest_dev_entry_set = [] + for dev_path in dev_path_set: + rest_dev_entry_set.append(rest_entry(dev_path + '/', + dev_mode__resend_from_static, + {'methods': ['GET']})) + rest_entry_set += rest_dev_entry_set + for re_entry in rest_entry_set: rest_path, f, flask_args = re_entry -- cgit v1.3.1 From 1c142b35db054df6aca833480b74a7ec2daeb34e Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sat, 6 Dec 2014 21:25:14 +0200 Subject: cfg.access_control: provide access control configuration switch --- src-py/rhizi_server.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index d93d285e..9b0b479c 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -188,10 +188,13 @@ def init_rest_api(cfg, flask_webapp): {'methods': ['GET']})) rest_entry_set += rest_dev_entry_set + if False == cfg.access_control: + log.warn('access control disabled, public access set on all URLs') + for re_entry in rest_entry_set: rest_path, f, flask_args = re_entry - if '/login' != rest_path: + if cfg.access_control and '/login' != rest_path: # currently require login on all but /login paths f = login_decorator(f) -- cgit v1.3.1 From 6c57c73430d7599ba045db4b518efa5a3c3e3641 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sat, 6 Dec 2014 21:25:52 +0200 Subject: misc --- src-py/rhizi_server.py | 31 ++++++++++++++++++++++--------- src-py/rhizi_server_fcgi.py | 7 ++++--- 2 files changed, 26 insertions(+), 12 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 9b0b479c..f7b3dbb3 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -10,10 +10,15 @@ import db_controller as dbc import rhizi_api import flask import crypt_util +import re +from flask import Flask from flask import session from flask import redirect -from flask import url_for +from flask import request +from flask import send_from_directory + +from functools import wraps class Config(object): """ @@ -118,10 +123,14 @@ class FlaskExt(Flask): # ret.headers['Access-Control-Allow-Methods'] = ', '.join(m_list) return ret +def init_log(cfg): + """ + init log file, location derived from configuration + """ log = logging.getLogger('rhizi') log.setLevel(logging.DEBUG) log_handler_c = logging.StreamHandler() - log_handler_f = logging.FileHandler('/var/log/rhizi/rhizi-server.log') + log_handler_f = logging.FileHandler(cfg.log_path) log.addHandler(log_handler_c) log.addHandler(log_handler_f) @@ -206,12 +215,12 @@ def init_rest_api(cfg, flask_webapp): def init_webapp(cfg): root_path = cfg.root_path - webapp = rhizi_api.FlaskExt(__name__, - static_folder='static', - template_folder=os.path.join(root_path, 'templates'), - static_url_path='') + webapp = FlaskExt(__name__, + static_folder='static', + template_folder=os.path.join(root_path, 'templates'), + static_url_path=cfg.static_url_path) webapp.config.from_object(cfg) - webapp.root_path = root_path # for some reason calling config.from_pyfile() + webapp.root_path = root_path # for some reason calling config.from_xxx() does not have effect db_ctl = dbc.DB_Controller(cfg) rhizi_api.db_ctl = db_ctl @@ -232,12 +241,16 @@ if __name__ == "__main__": p.add_argument('--init-htpasswd-db', help='init login htpasswd db', action='store_const', const=True) args = p.parse_args() - log = init_logging() cfg = init_config(args.config_dir) + log = init_log(cfg) + log.debug('loaded configuration:\n%s' % cfg) + if args.init_htpasswd_db: + init_pw_db(cfg) + exit(0) webapp = init_webapp(cfg) - init_rest_api(webapp) + init_rest_api(cfg, webapp) log.info('launching webapp via Flusk development server') webapp.run(host=cfg.listen_address, diff --git a/src-py/rhizi_server_fcgi.py b/src-py/rhizi_server_fcgi.py index bda8d91c..f0b9a04b 100755 --- a/src-py/rhizi_server_fcgi.py +++ b/src-py/rhizi_server_fcgi.py @@ -13,11 +13,12 @@ cgitb.enable() if __name__ == '__main__': cfg_dir = '/etc/rhizi' - cfg = rhizi_server.Config.init_from_file(os.path.join(cfg_dir, 'rhizi-server.conf')) - log = rhizi_server.init_logging() + cfg = rhizi_server.init_config(os.path.join(cfg_dir, 'rhizi-server.conf')) + log = rhizi_server.init_log() + webapp = rhizi_server.init_webapp(cfg) - rhizi_server.init_rest_api(webapp) + rhizi_server.init_rest_api(cfg, webapp) log.info('launching webapp via flup.server.fcgi.WSGIServer') -- cgit v1.3.1 From f38afeef4e0276e404be9189634b2914ff28e56c Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Sat, 6 Dec 2014 09:20:14 +0200 Subject: fix typo s/flusk/flask/ --- src-py/rhizi_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index f7b3dbb3..621868cd 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -252,7 +252,7 @@ if __name__ == "__main__": webapp = init_webapp(cfg) init_rest_api(cfg, webapp) - log.info('launching webapp via Flusk development server') + log.info('launching webapp via Flask development server') webapp.run(host=cfg.listen_address, port=cfg.listen_port) -- cgit v1.3.1 From 3ed7eae2d984493e1b295f853780556a0d4a93e4 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 8 Dec 2014 22:40:56 +0200 Subject: rename diff_commit__X according to diff type --- src-py/rhizi_api.py | 8 ++++---- src-py/rhizi_server.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 461f1e03..8d787a5c 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -142,7 +142,7 @@ def rz_clone(): op = dbc.DBO_rz_clone() return __common_exec(op) -def diff_commit_set(): +def diff_commit__set(): """ commit a diff set """ @@ -158,7 +158,7 @@ def diff_commit_set(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -def diff_commit_topo(): +def diff_commit__topo(): """ commit a graph topology diff """ @@ -173,7 +173,7 @@ def diff_commit_topo(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -def diff_commit_attr(): +def diff_commit__attr(): """ commit a graph attribute diff """ @@ -183,7 +183,7 @@ def diff_commit_attr(): op = dbc.DBO_attr_diff_commit(attr_diff) return __common_exec(op) -def diff_commit_vis(): +def diff_commit__vis(): pass def add_node_set(): diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 621868cd..4f0c7b52 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -175,10 +175,10 @@ def init_rest_api(cfg, flask_webapp): rest_entry_set = [ rest_entry('/add/node-set' , rhizi_api.add_node_set), rest_entry('/graph/clone', rhizi_api.rz_clone), - rest_entry('/graph/diff-commit-set', rhizi_api.diff_commit_set), - rest_entry('/graph/diff-commit-topo', rhizi_api.diff_commit_topo), - rest_entry('/graph/diff-commit-attr', rhizi_api.diff_commit_attr), - rest_entry('/graph/diff-commit-vis', rhizi_api.diff_commit_vis), + rest_entry('/graph/diff-commit-set', rhizi_api.diff_commit__set), + rest_entry('/graph/diff-commit-topo', rhizi_api.diff_commit__topo), + rest_entry('/graph/diff-commit-attr', rhizi_api.diff_commit__attr), + rest_entry('/graph/diff-commit-vis', rhizi_api.diff_commit__vis), rest_entry('/index', rhizi_api.index, {'methods': ['GET']}), rest_entry('/load/node-set-by-id', rhizi_api.load_node_set_by_id_attr), rest_entry('/load/link-set/by_link_ptr_set', rhizi_api.load_link_set_by_link_ptr_set), -- cgit v1.3.1 From 6ea834a5dba8017b9e3010aa6610f34f034cdbdd Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 14 Dec 2014 23:13:30 +0200 Subject: partial config validation --- src-py/rhizi_server.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src-py/rhizi_server.py') diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 4f0c7b52..168e2f53 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -77,6 +77,11 @@ class Config(object): ret = Config() ret.__dict__ = cfg # allows setting of @property attributes + + # validate config + if False == os.path.isabs(ret.root_path): + ret.root_path = os.path.abspath(ret.root_path) + return ret def __str__(self): -- cgit v1.3.1