Merge pull request #265 from eReuse/feature/#3100-wb-settings
Feature/#3100 wb settings
This commit is contained in:
commit
282b9490fb
|
@ -64,6 +64,16 @@
|
||||||
<hr class="dropdown-divider">
|
<hr class="dropdown-divider">
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item d-flex align-items-center" href="{{ url_for('workbench.settings') }}">
|
||||||
|
<i class="bi bi-tools"></i>
|
||||||
|
<span>Workbench Settings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<hr class="dropdown-divider">
|
||||||
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item d-flex align-items-center" href="https://help.usody.com/" target="_blank">
|
<a class="dropdown-item d-flex align-items-center" href="https://help.usody.com/" target="_blank">
|
||||||
<i class="bi bi-question-circle"></i>
|
<i class="bi bi-question-circle"></i>
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
{% extends "ereuse_devicehub/base_site.html" %}
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
<div class="pagetitle">
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
<nav>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">{{ page_title }}</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div><!-- End Page Title -->
|
||||||
|
|
||||||
|
<section class="section profile">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-6">
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<div class="pt-6 pb-2">
|
||||||
|
<h5 class="card-title text-center pb-0 fs-4">Download your settings for Workbench</h5>
|
||||||
|
<p class="text-center small">Please select one of this options</p>
|
||||||
|
<div class="row pt-3">
|
||||||
|
<div class="col-5">
|
||||||
|
<a href="{{ url_for('workbench.settings') }}?opt=register" class="btn btn-primary">Register devices</a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<p class="small">Download the settings only for register devices.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xl-8">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock main %}
|
|
@ -0,0 +1,4 @@
|
||||||
|
[settings]
|
||||||
|
|
||||||
|
TOKEN = {{ token }}
|
||||||
|
URL = {{ url }}
|
|
@ -0,0 +1,76 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
import flask
|
||||||
|
from flask import Blueprint
|
||||||
|
from flask import current_app as app
|
||||||
|
from flask import g, make_response, request
|
||||||
|
from flask_login import login_required
|
||||||
|
|
||||||
|
from ereuse_devicehub import auth
|
||||||
|
from ereuse_devicehub.db import db
|
||||||
|
from ereuse_devicehub.resources.enums import SessionType
|
||||||
|
from ereuse_devicehub.resources.user.models import Session
|
||||||
|
from ereuse_devicehub.views import GenericMixView
|
||||||
|
|
||||||
|
workbench = Blueprint('workbench', __name__, url_prefix='/workbench')
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsView(GenericMixView):
|
||||||
|
decorators = [login_required]
|
||||||
|
template_name = 'workbench/settings.html'
|
||||||
|
page_title = "Workbench Settings"
|
||||||
|
|
||||||
|
def dispatch_request(self):
|
||||||
|
self.get_context()
|
||||||
|
self.context.update(
|
||||||
|
{
|
||||||
|
'page_title': self.page_title,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.opt = request.values.get('opt')
|
||||||
|
if self.opt in ['register']:
|
||||||
|
return self.download()
|
||||||
|
|
||||||
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
|
def download(self):
|
||||||
|
url = "https://{}/api/inventory/".format(app.config['HOST'])
|
||||||
|
self.wbContext = {
|
||||||
|
'token': self.get_token(),
|
||||||
|
'url': url,
|
||||||
|
}
|
||||||
|
options = {"register": self.register}
|
||||||
|
return options[self.opt]()
|
||||||
|
|
||||||
|
def register(self):
|
||||||
|
data = flask.render_template('workbench/wbSettings.ini', **self.wbContext)
|
||||||
|
return self.response_download(data)
|
||||||
|
|
||||||
|
def response_download(self, data):
|
||||||
|
bfile = str.encode(data)
|
||||||
|
output = make_response(bfile)
|
||||||
|
output.headers['Content-Disposition'] = 'attachment; filename=settings.ini'
|
||||||
|
output.headers['Content-type'] = 'text/plain'
|
||||||
|
return output
|
||||||
|
|
||||||
|
def get_token(self):
|
||||||
|
if not g.user.sessions:
|
||||||
|
ses = Session(user=g.user)
|
||||||
|
db.session.add(ses)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
tk = ''
|
||||||
|
now = time.time()
|
||||||
|
for s in g.user.sessions:
|
||||||
|
if s.type == SessionType.Internal and (s.expired == 0 or s.expired > now):
|
||||||
|
tk = s.token
|
||||||
|
break
|
||||||
|
|
||||||
|
assert tk != ''
|
||||||
|
|
||||||
|
token = auth.Auth.encode(tk)
|
||||||
|
return token
|
||||||
|
|
||||||
|
|
||||||
|
workbench.add_url_rule('/settings/', view_func=SettingsView.as_view('settings'))
|
|
@ -10,11 +10,13 @@ from ereuse_devicehub.devicehub import Devicehub
|
||||||
from ereuse_devicehub.inventory.views import devices
|
from ereuse_devicehub.inventory.views import devices
|
||||||
from ereuse_devicehub.labels.views import labels
|
from ereuse_devicehub.labels.views import labels
|
||||||
from ereuse_devicehub.views import core
|
from ereuse_devicehub.views import core
|
||||||
|
from ereuse_devicehub.workbench.views import workbench
|
||||||
|
|
||||||
app = Devicehub(inventory=DevicehubConfig.DB_SCHEMA)
|
app = Devicehub(inventory=DevicehubConfig.DB_SCHEMA)
|
||||||
app.register_blueprint(core)
|
app.register_blueprint(core)
|
||||||
app.register_blueprint(devices)
|
app.register_blueprint(devices)
|
||||||
app.register_blueprint(labels)
|
app.register_blueprint(labels)
|
||||||
|
app.register_blueprint(workbench)
|
||||||
|
|
||||||
# configure & enable CSRF of Flask-WTF
|
# configure & enable CSRF of Flask-WTF
|
||||||
# NOTE: enable by blueprint to exclude API views
|
# NOTE: enable by blueprint to exclude API views
|
||||||
|
|
|
@ -24,6 +24,7 @@ from ereuse_devicehub.resources.enums import SessionType
|
||||||
from ereuse_devicehub.resources.tag import Tag
|
from ereuse_devicehub.resources.tag import Tag
|
||||||
from ereuse_devicehub.resources.user.models import Session, User
|
from ereuse_devicehub.resources.user.models import Session, User
|
||||||
from ereuse_devicehub.views import core
|
from ereuse_devicehub.views import core
|
||||||
|
from ereuse_devicehub.workbench.views import workbench
|
||||||
|
|
||||||
STARTT = datetime(year=2000, month=1, day=1, hour=1)
|
STARTT = datetime(year=2000, month=1, day=1, hour=1)
|
||||||
"""A dummy starting time to use in tests."""
|
"""A dummy starting time to use in tests."""
|
||||||
|
@ -58,6 +59,7 @@ def _app(config: TestConfig) -> Devicehub:
|
||||||
app.register_blueprint(core)
|
app.register_blueprint(core)
|
||||||
app.register_blueprint(devices)
|
app.register_blueprint(devices)
|
||||||
app.register_blueprint(labels)
|
app.register_blueprint(labels)
|
||||||
|
app.register_blueprint(workbench)
|
||||||
app.config["SQLALCHEMY_RECORD_QUERIES"] = True
|
app.config["SQLALCHEMY_RECORD_QUERIES"] = True
|
||||||
app.config['PROFILE'] = True
|
app.config['PROFILE'] = True
|
||||||
# app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30])
|
# app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30])
|
||||||
|
|
|
@ -19,7 +19,7 @@ def test_dependencies():
|
||||||
# Simplejson has a different signature than stdlib json
|
# Simplejson has a different signature than stdlib json
|
||||||
# should be fixed though
|
# should be fixed though
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
import simplejson
|
import simplejson # noqa: F401
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyArgumentList
|
# noinspection PyArgumentList
|
||||||
|
@ -87,6 +87,7 @@ def test_api_docs(client: Client):
|
||||||
'/users/login/',
|
'/users/login/',
|
||||||
'/users/logout/',
|
'/users/logout/',
|
||||||
'/versions/',
|
'/versions/',
|
||||||
|
'/workbench/settings/',
|
||||||
}
|
}
|
||||||
assert docs['info'] == {'title': 'Devicehub', 'version': '0.2'}
|
assert docs['info'] == {'title': 'Devicehub', 'version': '0.2'}
|
||||||
assert docs['components']['securitySchemes']['bearerAuth'] == {
|
assert docs['components']['securitySchemes']['bearerAuth'] == {
|
||||||
|
|
|
@ -842,3 +842,26 @@ def test_action_datawipe(user3: UserClientFlask):
|
||||||
assert dev.actions[-1].type == 'DataWipe'
|
assert dev.actions[-1].type == 'DataWipe'
|
||||||
assert 'Action "DataWipe" created successfully!' in body
|
assert 'Action "DataWipe" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.mvp
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_wb_settings(user3: UserClientFlask):
|
||||||
|
uri = '/workbench/settings/'
|
||||||
|
body, status = user3.get(uri)
|
||||||
|
|
||||||
|
assert status == '200 OK'
|
||||||
|
assert "Download your settings for Workbench" in body
|
||||||
|
assert "Workbench Settings" in body
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.mvp
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_wb_settings_register(user3: UserClientFlask):
|
||||||
|
uri = '/workbench/settings/?opt=register'
|
||||||
|
body, status = user3.get(uri)
|
||||||
|
|
||||||
|
assert status == '200 OK'
|
||||||
|
assert "TOKEN = " in body
|
||||||
|
assert "URL = https://" in body
|
||||||
|
assert "/api/inventory/" in body
|
||||||
|
|
Reference in New Issue