mirror of
https://github.com/avatao-content/test-tutorial-framework
synced 2024-11-14 15:47:17 +00:00
Merge branch 'message-types'
This commit is contained in:
commit
cb9e673a68
@ -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`.
|
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.
|
`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.
|
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.
|
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`
|
- Set it up to run: `solvable/supervisor/tfw_server.conf`
|
||||||
4. Create event handlers connecting to the `TFWServer` handling events you want to process:
|
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`
|
- 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
|
5. Modify the frontend in `solvable/frontend` to fit your challenge
|
||||||
- This usually involves using our pre-made components
|
- This usually involves using our pre-made components
|
||||||
- And perhaps doing some of your own stuff, like:
|
- And perhaps doing some of your own stuff, like:
|
||||||
|
@ -2,7 +2,8 @@ from ast import literal_eval
|
|||||||
|
|
||||||
from tornado.ioloop import IOLoop
|
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.components import TerminalCommands, LogMonitoringEventHandler
|
||||||
from tfw.networking import MessageSender, TFWServerConnector
|
from tfw.networking import MessageSender, TFWServerConnector
|
||||||
from tfw.config import TFWENV
|
from tfw.config import TFWENV
|
||||||
@ -13,6 +14,10 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
def cenator(history):
|
def cenator(history):
|
||||||
|
"""
|
||||||
|
Logs commands executed in terminal to messages.
|
||||||
|
!! Please remove from production code. !!
|
||||||
|
"""
|
||||||
LOG.debug('User executed command: "%s"', history[-1])
|
LOG.debug('User executed command: "%s"', history[-1])
|
||||||
MessageSender().send('JOHN CENA', f'You\'ve executed "{history[-1]}"')
|
MessageSender().send('JOHN CENA', f'You\'ve executed "{history[-1]}"')
|
||||||
|
|
||||||
@ -20,7 +25,7 @@ def cenator(history):
|
|||||||
class TestCommands(TerminalCommands):
|
class TestCommands(TerminalCommands):
|
||||||
"""
|
"""
|
||||||
Some example commands useful for debugging.
|
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
|
class from TerminalCommands if you need to define custom
|
||||||
commands in your challenge.
|
commands in your challenge.
|
||||||
"""
|
"""
|
||||||
@ -38,7 +43,7 @@ class TestCommands(TerminalCommands):
|
|||||||
'key': 'shell',
|
'key': 'shell',
|
||||||
'data': {
|
'data': {
|
||||||
'command': 'write',
|
'command': 'write',
|
||||||
'shellcmd': f'sendmessage {message_template}'
|
'value': f'sendmessage {message_template}'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
@ -50,20 +55,22 @@ class TestCommands(TerminalCommands):
|
|||||||
This can speed up development when combined with mounting
|
This can speed up development when combined with mounting
|
||||||
volumes from host to container.
|
volumes from host to container.
|
||||||
"""
|
"""
|
||||||
seppuku = ('nohup sh -c "supervisorctl restart tfwserver event_handler_main" &> /dev/null & '
|
seppuku = (
|
||||||
'clear && echo "Committed seppuku! :)" && sleep infinity')
|
'nohup sh -c "supervisorctl restart tfwserver event_handler_main" &> /dev/null & '
|
||||||
|
'clear && echo "Committed seppuku! :)" && sleep infinity'
|
||||||
|
)
|
||||||
uplink = TFWServerConnector()
|
uplink = TFWServerConnector()
|
||||||
uplink.send_to_eventhandler({
|
uplink.send_to_eventhandler({
|
||||||
'key': 'shell',
|
'key': 'shell',
|
||||||
'data': {
|
'data': {
|
||||||
'command': 'write',
|
'command': 'write',
|
||||||
'shellcmd': f'{seppuku}\n'
|
'value': f'{seppuku}\n'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
uplink.send({
|
uplink.send({
|
||||||
'key': 'dashboard',
|
'key': 'dashboard',
|
||||||
'data': {
|
'data': {
|
||||||
'command': 'reload_frontend'
|
'command': 'reloadFrontend'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -73,8 +80,7 @@ if __name__ == '__main__':
|
|||||||
key='ide',
|
key='ide',
|
||||||
allowed_directories=[TFWENV.IDE_WD, TFWENV.WEBSERVICE_DIR],
|
allowed_directories=[TFWENV.IDE_WD, TFWENV.WEBSERVICE_DIR],
|
||||||
directory=TFWENV.IDE_WD,
|
directory=TFWENV.IDE_WD,
|
||||||
exclude=['*.pyc'],
|
exclude=['*.pyc']
|
||||||
additional_watched_directories=[TFWENV.WEBSERVICE_DIR]
|
|
||||||
)
|
)
|
||||||
terminal = TerminalEventHandler( # Web shell backend
|
terminal = TerminalEventHandler( # Web shell backend
|
||||||
key='shell',
|
key='shell',
|
||||||
@ -92,10 +98,9 @@ if __name__ == '__main__':
|
|||||||
)
|
)
|
||||||
eventhandlers = {ide, terminal, processmanager, logmonitor}
|
eventhandlers = {ide, terminal, processmanager, logmonitor}
|
||||||
|
|
||||||
terminal.historymonitor.subscribe_callback(cenator)
|
|
||||||
|
|
||||||
commands = TestCommands(bashrc=f'/home/{TAOENV.USER}/.bashrc')
|
commands = TestCommands(bashrc=f'/home/{TAOENV.USER}/.bashrc')
|
||||||
terminal.historymonitor.subscribe_callback(commands.callback)
|
terminal.historymonitor.subscribe_callback(commands.callback)
|
||||||
|
terminal.historymonitor.subscribe_callback(cenator)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
IOLoop.instance().start()
|
IOLoop.instance().start()
|
||||||
|
@ -6,9 +6,11 @@ from sqlalchemy.orm import sessionmaker
|
|||||||
|
|
||||||
|
|
||||||
engine = create_engine('sqlite:///db.db', convert_unicode=True)
|
engine = create_engine('sqlite:///db.db', convert_unicode=True)
|
||||||
session_factory = sessionmaker(autocommit=False,
|
session_factory = sessionmaker(
|
||||||
|
autocommit=False,
|
||||||
autoflush=False,
|
autoflush=False,
|
||||||
bind=engine)
|
bind=engine
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
@ -10,7 +10,9 @@ BASEURL = getenv('BASEURL', '')
|
|||||||
init_db()
|
init_db()
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = urandom(32)
|
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():
|
def get_db_session():
|
||||||
@ -47,22 +49,33 @@ def index():
|
|||||||
@app.route('/register', methods=['GET', 'POST'])
|
@app.route('/register', methods=['GET', 'POST'])
|
||||||
def register():
|
def register():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
if not all([request.form.get('username'),
|
form_filled_out = all([
|
||||||
|
request.form.get('username'),
|
||||||
request.form.get('password'),
|
request.form.get('password'),
|
||||||
request.form.get('passwordconfirm')]):
|
request.form.get('passwordconfirm')
|
||||||
|
])
|
||||||
|
|
||||||
|
if not form_filled_out:
|
||||||
return render_template('register.html', alert='You need to fill everything.')
|
return render_template('register.html', alert='You need to fill everything.')
|
||||||
if request.form['password'] != request.form['passwordconfirm']:
|
if request.form['password'] != request.form['passwordconfirm']:
|
||||||
return render_template('register.html', alert='Passwords do not match! Please try again.')
|
return render_template('register.html', alert='Passwords do not match! Please try again.')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
UserOps(request.form.get('username'),
|
UserOps(
|
||||||
|
request.form.get('username'),
|
||||||
request.form.get('password'),
|
request.form.get('password'),
|
||||||
get_db_session()).register()
|
get_db_session()
|
||||||
|
).register()
|
||||||
except UserExistsError:
|
except UserExistsError:
|
||||||
return render_template('register.html', alert='Username already in use.')
|
return render_template('register.html', alert='Username already in use.')
|
||||||
|
|
||||||
return render_template('login.html', success=('Account "{}" successfully registered. '
|
return render_template(
|
||||||
'You can log in now!'.format(request.form['username'])))
|
'login.html',
|
||||||
|
success=(
|
||||||
|
'Account "{}" successfully registered. '
|
||||||
|
'You can log in now!'.format(request.form['username'])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return render_template('register.html')
|
return render_template('register.html')
|
||||||
|
|
||||||
|
@ -23,9 +23,16 @@ class UserOps:
|
|||||||
:raises InvalidCredentialsError:
|
:raises InvalidCredentialsError:
|
||||||
User does not exist or password provided is invalid
|
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}"!')
|
self.log(f'Invalid credentials for user "{self.username}"!')
|
||||||
raise InvalidCredentialsError
|
raise InvalidCredentialsError
|
||||||
|
|
||||||
@ -39,11 +46,17 @@ class UserOps:
|
|||||||
:raises UserExistsError:
|
:raises UserExistsError:
|
||||||
A user with the provided username already exists
|
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
|
raise UserExistsError
|
||||||
|
|
||||||
user = User(username=self.username,
|
user = User(
|
||||||
passwordhash=PasswordHasher.hash(self.password))
|
username=self.username,
|
||||||
|
passwordhash=PasswordHasher.hash(self.password)
|
||||||
|
)
|
||||||
self.db_session.add(user)
|
self.db_session.add(user)
|
||||||
self.db_session.commit()
|
self.db_session.commit()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user