From 6ff39e9739c973412c17c0cc9d5b68722c2970ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Thu, 31 May 2018 14:19:47 +0200 Subject: [PATCH 1/6] Extend docstrings in event_handler_main --- solvable/src/event_handler_main.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/solvable/src/event_handler_main.py b/solvable/src/event_handler_main.py index 2950235..077a642 100644 --- a/solvable/src/event_handler_main.py +++ b/solvable/src/event_handler_main.py @@ -13,6 +13,10 @@ LOG = logging.getLogger(__name__) def cenator(history): + """ + Logs commands executed in terminal to messages. + !! Please remove from production code. !! + """ LOG.debug('User executed command: "%s"', history[-1]) MessageSender().send('JOHN CENA', f'You\'ve executed "{history[-1]}"') @@ -20,7 +24,7 @@ def cenator(history): class TestCommands(TerminalCommands): """ Some example commands useful for debugging. - Please remove from production code and inherit your own + !! Please remove from production code !! and inherit your own class from TerminalCommands if you need to define custom commands in your challenge. """ @@ -92,8 +96,6 @@ if __name__ == '__main__': ) eventhandlers = {ide, terminal, processmanager, logmonitor} - terminal.historymonitor.subscribe_callback(cenator) - commands = TestCommands(bashrc=f'/home/{TAOENV.USER}/.bashrc') terminal.historymonitor.subscribe_callback(commands.callback) From e5056e3ee19cb2e73e9848f1515293c5a29b9f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Thu, 31 May 2018 14:20:08 +0200 Subject: [PATCH 2/6] Comply with changes in TFW API --- solvable/src/event_handler_main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/solvable/src/event_handler_main.py b/solvable/src/event_handler_main.py index 077a642..a6ecd8e 100644 --- a/solvable/src/event_handler_main.py +++ b/solvable/src/event_handler_main.py @@ -42,7 +42,7 @@ class TestCommands(TerminalCommands): 'key': 'shell', 'data': { 'command': 'write', - 'shellcmd': f'sendmessage {message_template}' + 'value': f'sendmessage {message_template}' } }) else: @@ -61,13 +61,13 @@ class TestCommands(TerminalCommands): 'key': 'shell', 'data': { 'command': 'write', - 'shellcmd': f'{seppuku}\n' + 'value': f'{seppuku}\n' } }) uplink.send({ 'key': 'dashboard', 'data': { - 'command': 'reload_frontend' + 'command': 'reloadFrontend' } }) @@ -98,6 +98,7 @@ if __name__ == '__main__': commands = TestCommands(bashrc=f'/home/{TAOENV.USER}/.bashrc') terminal.historymonitor.subscribe_callback(commands.callback) + terminal.historymonitor.subscribe_callback(cenator) try: IOLoop.instance().start() From cf8a9d7e8158a0320772f32a7f61585f300b899d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Thu, 31 May 2018 14:22:08 +0200 Subject: [PATCH 3/6] Rename event_handlers.conf for coherency --- README.md | 4 ++-- .../{event_handlers.conf => event_handler_main.conf} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename solvable/supervisor/{event_handlers.conf => event_handler_main.conf} (100%) diff --git a/README.md b/README.md index de6f5bb..1f2ba5d 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ It also manages the FSM. As you can see this file is set up to start with the container in `solvable/supervisor/tfw_server.conf`. `event_handler_main.py` contains example usage of our pre-defined event handlers written in Python3. -As you can see they run in a separate process (set up in `solvable/supervisor/event_handlers.conf`). +As you can see they run in a separate process (set up in `solvable/supervisor/event_handler_main.conf`). These event handlers could be implemented in any language that has ZMQ bindings. Note that you don't have to use all our event handlers. @@ -204,7 +204,7 @@ When creating your own challenge the process should be the following: - Set it up to run: `solvable/supervisor/tfw_server.conf` 4. Create event handlers connecting to the `TFWServer` handling events you want to process: - Create an event handler server: `solvable/src/event_handler_main.py` - - Set it up to run: `solvable/supervisor/event_handlers.conf` + - Set it up to run: `solvable/supervisor/event_handler_main.conf` 5. Modify the frontend in `solvable/frontend` to fit your challenge - This usually involves using our pre-made components - And perhaps doing some of your own stuff, like: diff --git a/solvable/supervisor/event_handlers.conf b/solvable/supervisor/event_handler_main.conf similarity index 100% rename from solvable/supervisor/event_handlers.conf rename to solvable/supervisor/event_handler_main.conf From d7f272a535d53e729e867562bb0655436dd6b624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Mon, 4 Jun 2018 21:16:05 +0200 Subject: [PATCH 4/6] Reduce user_ops.py line length to better fit webIDE --- solvable/src/webservice/user_ops.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/solvable/src/webservice/user_ops.py b/solvable/src/webservice/user_ops.py index ac59294..c9107a6 100644 --- a/solvable/src/webservice/user_ops.py +++ b/solvable/src/webservice/user_ops.py @@ -23,9 +23,16 @@ class UserOps: :raises InvalidCredentialsError: User does not exist or password provided is invalid """ - user = self.db_session.query(User).filter(User.username == self.username).first() + user = self.db_session.query(User).filter( + User.username == self.username + ).first() - if not user or not PasswordHasher.verify(self.password, user.passwordhash): + passw_is_correct = PasswordHasher.verify( + self.password, + user.passwordhash + ) + + if not user or not passw_is_correct: self.log(f'Invalid credentials for user "{self.username}"!') raise InvalidCredentialsError @@ -39,11 +46,17 @@ class UserOps: :raises UserExistsError: A user with the provided username already exists """ - if self.db_session.query(User).filter(User.username == self.username).all(): + existing_users = self.db_session.query(User).filter( + User.username == self.username + ).all() + + if existing_users: raise UserExistsError - user = User(username=self.username, - passwordhash=PasswordHasher.hash(self.password)) + user = User( + username=self.username, + passwordhash=PasswordHasher.hash(self.password) + ) self.db_session.add(user) self.db_session.commit() From 60986fa51d0e24bc2f5da60e50d3b0c517b6b0ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Mon, 4 Jun 2018 21:48:54 +0200 Subject: [PATCH 5/6] Remove no longer used argument from IdeEH.__init__ call --- solvable/src/event_handler_main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/solvable/src/event_handler_main.py b/solvable/src/event_handler_main.py index a6ecd8e..2774505 100644 --- a/solvable/src/event_handler_main.py +++ b/solvable/src/event_handler_main.py @@ -77,8 +77,7 @@ if __name__ == '__main__': key='ide', allowed_directories=[TFWENV.IDE_WD, TFWENV.WEBSERVICE_DIR], directory=TFWENV.IDE_WD, - exclude=['*.pyc'], - additional_watched_directories=[TFWENV.WEBSERVICE_DIR] + exclude=['*.pyc'] ) terminal = TerminalEventHandler( # Web shell backend key='shell', From 12c95a198b6a47f607da2cae914f1414c31d095d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Mon, 4 Jun 2018 21:56:59 +0200 Subject: [PATCH 6/6] Harmonize code formatting style across project --- solvable/src/event_handler_main.py | 9 ++++++--- solvable/src/webservice/model.py | 8 +++++--- solvable/src/webservice/server.py | 31 +++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/solvable/src/event_handler_main.py b/solvable/src/event_handler_main.py index 2774505..297f132 100644 --- a/solvable/src/event_handler_main.py +++ b/solvable/src/event_handler_main.py @@ -2,7 +2,8 @@ from ast import literal_eval from tornado.ioloop import IOLoop -from tfw.components import IdeEventHandler, TerminalEventHandler, ProcessManagingEventHandler, BashMonitor +from tfw.components import IdeEventHandler, TerminalEventHandler +from tfw.components import ProcessManagingEventHandler, BashMonitor from tfw.components import TerminalCommands, LogMonitoringEventHandler from tfw.networking import MessageSender, TFWServerConnector from tfw.config import TFWENV @@ -54,8 +55,10 @@ class TestCommands(TerminalCommands): This can speed up development when combined with mounting volumes from host to container. """ - seppuku = ('nohup sh -c "supervisorctl restart tfwserver event_handler_main" &> /dev/null & ' - 'clear && echo "Committed seppuku! :)" && sleep infinity') + seppuku = ( + 'nohup sh -c "supervisorctl restart tfwserver event_handler_main" &> /dev/null & ' + 'clear && echo "Committed seppuku! :)" && sleep infinity' + ) uplink = TFWServerConnector() uplink.send_to_eventhandler({ 'key': 'shell', diff --git a/solvable/src/webservice/model.py b/solvable/src/webservice/model.py index f135b25..2439684 100644 --- a/solvable/src/webservice/model.py +++ b/solvable/src/webservice/model.py @@ -6,9 +6,11 @@ from sqlalchemy.orm import sessionmaker engine = create_engine('sqlite:///db.db', convert_unicode=True) -session_factory = sessionmaker(autocommit=False, - autoflush=False, - bind=engine) +session_factory = sessionmaker( + autocommit=False, + autoflush=False, + bind=engine +) @contextmanager diff --git a/solvable/src/webservice/server.py b/solvable/src/webservice/server.py index cc84ecb..6f4aab7 100644 --- a/solvable/src/webservice/server.py +++ b/solvable/src/webservice/server.py @@ -10,7 +10,9 @@ BASEURL = getenv('BASEURL', '') init_db() app = Flask(__name__) app.secret_key = urandom(32) -app.jinja_env.globals.update(get_url=lambda endpoint: f'{BASEURL}{url_for(endpoint)}') # pylint: disable=no-member +app.jinja_env.globals.update( # pylint: disable=no-member + get_url=lambda endpoint: f'{BASEURL}{url_for(endpoint)}' +) def get_db_session(): @@ -47,22 +49,33 @@ def index(): @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == 'POST': - if not all([request.form.get('username'), - request.form.get('password'), - request.form.get('passwordconfirm')]): + form_filled_out = all([ + request.form.get('username'), + request.form.get('password'), + request.form.get('passwordconfirm') + ]) + + if not form_filled_out: return render_template('register.html', alert='You need to fill everything.') if request.form['password'] != request.form['passwordconfirm']: return render_template('register.html', alert='Passwords do not match! Please try again.') try: - UserOps(request.form.get('username'), - request.form.get('password'), - get_db_session()).register() + UserOps( + request.form.get('username'), + request.form.get('password'), + get_db_session() + ).register() except UserExistsError: return render_template('register.html', alert='Username already in use.') - return render_template('login.html', success=('Account "{}" successfully registered. ' - 'You can log in now!'.format(request.form['username']))) + return render_template( + 'login.html', + success=( + 'Account "{}" successfully registered. ' + 'You can log in now!'.format(request.form['username']) + ) + ) return render_template('register.html')