mirror of
https://github.com/onionshare/onionshare.git
synced 2024-10-01 01:35:40 -04:00
Merge pull request #752 from mig5/receiver-mode-gui-hold-timeout-share-open-til-upload-finished
Hold a share open if its timer has expired but a file is still uploading.
This commit is contained in:
commit
c7ef1bba39
@ -209,6 +209,13 @@ def main(cwd=None):
|
|||||||
print(strings._("close_on_timeout"))
|
print(strings._("close_on_timeout"))
|
||||||
web.stop(app.port)
|
web.stop(app.port)
|
||||||
break
|
break
|
||||||
|
if mode == 'receive':
|
||||||
|
if web.receive_mode.upload_count == 0 or not web.receive_mode.uploads_in_progress:
|
||||||
|
print(strings._("close_on_timeout"))
|
||||||
|
web.stop(app.port)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
web.receive_mode.can_upload = False
|
||||||
# Allow KeyboardInterrupt exception to be handled with threads
|
# Allow KeyboardInterrupt exception to be handled with threads
|
||||||
# https://stackoverflow.com/questions/3788208/python-threading-ignores-keyboardinterrupt-exception
|
# https://stackoverflow.com/questions/3788208/python-threading-ignores-keyboardinterrupt-exception
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
@ -94,7 +94,6 @@ class Settings(object):
|
|||||||
'slug': '',
|
'slug': '',
|
||||||
'hidservauth_string': '',
|
'hidservauth_string': '',
|
||||||
'downloads_dir': self.build_default_downloads_dir(),
|
'downloads_dir': self.build_default_downloads_dir(),
|
||||||
'receive_allow_receiver_shutdown': True,
|
|
||||||
'locale': None # this gets defined in fill_in_defaults()
|
'locale': None # this gets defined in fill_in_defaults()
|
||||||
}
|
}
|
||||||
self._settings = {}
|
self._settings = {}
|
||||||
|
@ -17,7 +17,9 @@ class ReceiveModeWeb(object):
|
|||||||
|
|
||||||
self.web = web
|
self.web = web
|
||||||
|
|
||||||
|
self.can_upload = True
|
||||||
self.upload_count = 0
|
self.upload_count = 0
|
||||||
|
self.uploads_in_progress = []
|
||||||
|
|
||||||
self.define_routes()
|
self.define_routes()
|
||||||
|
|
||||||
@ -30,25 +32,25 @@ class ReceiveModeWeb(object):
|
|||||||
|
|
||||||
if self.common.settings.get('public_mode'):
|
if self.common.settings.get('public_mode'):
|
||||||
upload_action = '/upload'
|
upload_action = '/upload'
|
||||||
close_action = '/close'
|
|
||||||
else:
|
else:
|
||||||
upload_action = '/{}/upload'.format(self.web.slug)
|
upload_action = '/{}/upload'.format(self.web.slug)
|
||||||
close_action = '/{}/close'.format(self.web.slug)
|
|
||||||
|
|
||||||
r = make_response(render_template(
|
r = make_response(render_template(
|
||||||
'receive.html',
|
'receive.html',
|
||||||
upload_action=upload_action,
|
upload_action=upload_action))
|
||||||
close_action=close_action,
|
|
||||||
receive_allow_receiver_shutdown=self.common.settings.get('receive_allow_receiver_shutdown')))
|
|
||||||
return self.web.add_security_headers(r)
|
return self.web.add_security_headers(r)
|
||||||
|
|
||||||
@self.web.app.route("/<slug_candidate>")
|
@self.web.app.route("/<slug_candidate>")
|
||||||
def index(slug_candidate):
|
def index(slug_candidate):
|
||||||
|
if not self.can_upload:
|
||||||
|
return self.web.error403()
|
||||||
self.web.check_slug_candidate(slug_candidate)
|
self.web.check_slug_candidate(slug_candidate)
|
||||||
return index_logic()
|
return index_logic()
|
||||||
|
|
||||||
@self.web.app.route("/")
|
@self.web.app.route("/")
|
||||||
def index_public():
|
def index_public():
|
||||||
|
if not self.can_upload:
|
||||||
|
return self.web.error403()
|
||||||
if not self.common.settings.get('public_mode'):
|
if not self.common.settings.get('public_mode'):
|
||||||
return self.web.error404()
|
return self.web.error404()
|
||||||
return index_logic()
|
return index_logic()
|
||||||
@ -144,43 +146,41 @@ class ReceiveModeWeb(object):
|
|||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
flash('Sent {}'.format(filename), 'info')
|
flash('Sent {}'.format(filename), 'info')
|
||||||
|
|
||||||
if self.common.settings.get('public_mode'):
|
if self.can_upload:
|
||||||
return redirect('/')
|
if self.common.settings.get('public_mode'):
|
||||||
|
path = '/'
|
||||||
|
else:
|
||||||
|
path = '/{}'.format(slug_candidate)
|
||||||
|
|
||||||
|
return redirect('{}'.format(path))
|
||||||
else:
|
else:
|
||||||
return redirect('/{}'.format(slug_candidate))
|
# It was the last upload and the timer ran out
|
||||||
|
if self.common.settings.get('public_mode'):
|
||||||
|
return thankyou_logic(slug_candidate)
|
||||||
|
else:
|
||||||
|
return thankyou_logic()
|
||||||
|
|
||||||
|
def thankyou_logic(slug_candidate=''):
|
||||||
|
r = make_response(render_template(
|
||||||
|
'thankyou.html'))
|
||||||
|
return self.web.add_security_headers(r)
|
||||||
|
|
||||||
@self.web.app.route("/<slug_candidate>/upload", methods=['POST'])
|
@self.web.app.route("/<slug_candidate>/upload", methods=['POST'])
|
||||||
def upload(slug_candidate):
|
def upload(slug_candidate):
|
||||||
|
if not self.can_upload:
|
||||||
|
return self.web.error403()
|
||||||
self.web.check_slug_candidate(slug_candidate)
|
self.web.check_slug_candidate(slug_candidate)
|
||||||
return upload_logic(slug_candidate)
|
return upload_logic(slug_candidate)
|
||||||
|
|
||||||
@self.web.app.route("/upload", methods=['POST'])
|
@self.web.app.route("/upload", methods=['POST'])
|
||||||
def upload_public():
|
def upload_public():
|
||||||
|
if not self.can_upload:
|
||||||
|
return self.web.error403()
|
||||||
if not self.common.settings.get('public_mode'):
|
if not self.common.settings.get('public_mode'):
|
||||||
return self.web.error404()
|
return self.web.error404()
|
||||||
return upload_logic()
|
return upload_logic()
|
||||||
|
|
||||||
|
|
||||||
def close_logic(slug_candidate=''):
|
|
||||||
if self.common.settings.get('receive_allow_receiver_shutdown'):
|
|
||||||
self.web.force_shutdown()
|
|
||||||
r = make_response(render_template('closed.html'))
|
|
||||||
self.web.add_request(self.web.REQUEST_CLOSE_SERVER, request.path)
|
|
||||||
return self.web.add_security_headers(r)
|
|
||||||
else:
|
|
||||||
return redirect('/{}'.format(slug_candidate))
|
|
||||||
|
|
||||||
@self.web.app.route("/<slug_candidate>/close", methods=['POST'])
|
|
||||||
def close(slug_candidate):
|
|
||||||
self.web.check_slug_candidate(slug_candidate)
|
|
||||||
return close_logic(slug_candidate)
|
|
||||||
|
|
||||||
@self.web.app.route("/close", methods=['POST'])
|
|
||||||
def close_public():
|
|
||||||
if not self.common.settings.get('public_mode'):
|
|
||||||
return self.web.error404()
|
|
||||||
return close_logic()
|
|
||||||
|
|
||||||
|
|
||||||
class ReceiveModeWSGIMiddleware(object):
|
class ReceiveModeWSGIMiddleware(object):
|
||||||
"""
|
"""
|
||||||
@ -256,28 +256,34 @@ class ReceiveModeRequest(Request):
|
|||||||
# A dictionary that maps filenames to the bytes uploaded so far
|
# A dictionary that maps filenames to the bytes uploaded so far
|
||||||
self.progress = {}
|
self.progress = {}
|
||||||
|
|
||||||
# Create an upload_id, attach it to the request
|
# Prevent new uploads if we've said so (timer expired)
|
||||||
self.upload_id = self.web.receive_mode.upload_count
|
if self.web.receive_mode.can_upload:
|
||||||
self.web.receive_mode.upload_count += 1
|
|
||||||
|
|
||||||
# Figure out the content length
|
# Create an upload_id, attach it to the request
|
||||||
try:
|
self.upload_id = self.web.receive_mode.upload_count
|
||||||
self.content_length = int(self.headers['Content-Length'])
|
|
||||||
except:
|
|
||||||
self.content_length = 0
|
|
||||||
|
|
||||||
print("{}: {}".format(
|
self.web.receive_mode.upload_count += 1
|
||||||
datetime.now().strftime("%b %d, %I:%M%p"),
|
|
||||||
strings._("receive_mode_upload_starting").format(self.web.common.human_readable_filesize(self.content_length))
|
|
||||||
))
|
|
||||||
|
|
||||||
# Tell the GUI
|
# Figure out the content length
|
||||||
self.web.add_request(self.web.REQUEST_STARTED, self.path, {
|
try:
|
||||||
'id': self.upload_id,
|
self.content_length = int(self.headers['Content-Length'])
|
||||||
'content_length': self.content_length
|
except:
|
||||||
})
|
self.content_length = 0
|
||||||
|
|
||||||
self.previous_file = None
|
print("{}: {}".format(
|
||||||
|
datetime.now().strftime("%b %d, %I:%M%p"),
|
||||||
|
strings._("receive_mode_upload_starting").format(self.web.common.human_readable_filesize(self.content_length))
|
||||||
|
))
|
||||||
|
|
||||||
|
# Tell the GUI
|
||||||
|
self.web.add_request(self.web.REQUEST_STARTED, self.path, {
|
||||||
|
'id': self.upload_id,
|
||||||
|
'content_length': self.content_length
|
||||||
|
})
|
||||||
|
|
||||||
|
self.web.receive_mode.uploads_in_progress.append(self.upload_id)
|
||||||
|
|
||||||
|
self.previous_file = None
|
||||||
|
|
||||||
def _get_file_stream(self, total_content_length, content_type, filename=None, content_length=None):
|
def _get_file_stream(self, total_content_length, content_type, filename=None, content_length=None):
|
||||||
"""
|
"""
|
||||||
@ -297,11 +303,15 @@ class ReceiveModeRequest(Request):
|
|||||||
Closing the request.
|
Closing the request.
|
||||||
"""
|
"""
|
||||||
super(ReceiveModeRequest, self).close()
|
super(ReceiveModeRequest, self).close()
|
||||||
if self.upload_request:
|
try:
|
||||||
|
upload_id = self.upload_id
|
||||||
# Inform the GUI that the upload has finished
|
# Inform the GUI that the upload has finished
|
||||||
self.web.add_request(self.web.REQUEST_UPLOAD_FINISHED, self.path, {
|
self.web.add_request(self.web.REQUEST_UPLOAD_FINISHED, self.path, {
|
||||||
'id': self.upload_id
|
'id': upload_id
|
||||||
})
|
})
|
||||||
|
self.web.receive_mode.uploads_in_progress.remove(upload_id)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def file_write_func(self, filename, length):
|
def file_write_func(self, filename, length):
|
||||||
"""
|
"""
|
||||||
|
@ -142,6 +142,12 @@ class Web(object):
|
|||||||
r = make_response(render_template('404.html'), 404)
|
r = make_response(render_template('404.html'), 404)
|
||||||
return self.add_security_headers(r)
|
return self.add_security_headers(r)
|
||||||
|
|
||||||
|
def error403(self):
|
||||||
|
self.add_request(Web.REQUEST_OTHER, request.path)
|
||||||
|
|
||||||
|
r = make_response(render_template('403.html'), 403)
|
||||||
|
return self.add_security_headers(r)
|
||||||
|
|
||||||
def add_security_headers(self, r):
|
def add_security_headers(self, r):
|
||||||
"""
|
"""
|
||||||
Add security headers to a request
|
Add security headers to a request
|
||||||
|
@ -96,8 +96,16 @@ class ReceiveMode(Mode):
|
|||||||
"""
|
"""
|
||||||
The shutdown timer expired, should we stop the server? Returns a bool
|
The shutdown timer expired, should we stop the server? Returns a bool
|
||||||
"""
|
"""
|
||||||
# TODO: wait until the final upload is done before stoppign the server?
|
# If there were no attempts to upload files, or all uploads are done, we can stop
|
||||||
return True
|
if self.web.receive_mode.upload_count == 0 or not self.web.receive_mode.uploads_in_progress:
|
||||||
|
self.server_status.stop_server()
|
||||||
|
self.server_status_label.setText(strings._('close_on_timeout'))
|
||||||
|
return True
|
||||||
|
# An upload is probably still running - hold off on stopping the share, but block new shares.
|
||||||
|
else:
|
||||||
|
self.server_status_label.setText(strings._('timeout_upload_still_running'))
|
||||||
|
self.web.receive_mode.can_upload = False
|
||||||
|
return False
|
||||||
|
|
||||||
def start_server_custom(self):
|
def start_server_custom(self):
|
||||||
"""
|
"""
|
||||||
|
@ -186,15 +186,9 @@ class SettingsDialog(QtWidgets.QDialog):
|
|||||||
downloads_layout.addWidget(self.downloads_dir_lineedit)
|
downloads_layout.addWidget(self.downloads_dir_lineedit)
|
||||||
downloads_layout.addWidget(downloads_button)
|
downloads_layout.addWidget(downloads_button)
|
||||||
|
|
||||||
# Allow the receiver to shutdown the server
|
|
||||||
self.receive_allow_receiver_shutdown_checkbox = QtWidgets.QCheckBox()
|
|
||||||
self.receive_allow_receiver_shutdown_checkbox.setCheckState(QtCore.Qt.Checked)
|
|
||||||
self.receive_allow_receiver_shutdown_checkbox.setText(strings._("gui_settings_receive_allow_receiver_shutdown_checkbox"))
|
|
||||||
|
|
||||||
# Receiving options layout
|
# Receiving options layout
|
||||||
receiving_group_layout = QtWidgets.QVBoxLayout()
|
receiving_group_layout = QtWidgets.QVBoxLayout()
|
||||||
receiving_group_layout.addLayout(downloads_layout)
|
receiving_group_layout.addLayout(downloads_layout)
|
||||||
receiving_group_layout.addWidget(self.receive_allow_receiver_shutdown_checkbox)
|
|
||||||
receiving_group = QtWidgets.QGroupBox(strings._("gui_settings_receiving_label"))
|
receiving_group = QtWidgets.QGroupBox(strings._("gui_settings_receiving_label"))
|
||||||
receiving_group.setLayout(receiving_group_layout)
|
receiving_group.setLayout(receiving_group_layout)
|
||||||
|
|
||||||
@ -506,12 +500,6 @@ class SettingsDialog(QtWidgets.QDialog):
|
|||||||
downloads_dir = self.old_settings.get('downloads_dir')
|
downloads_dir = self.old_settings.get('downloads_dir')
|
||||||
self.downloads_dir_lineedit.setText(downloads_dir)
|
self.downloads_dir_lineedit.setText(downloads_dir)
|
||||||
|
|
||||||
receive_allow_receiver_shutdown = self.old_settings.get('receive_allow_receiver_shutdown')
|
|
||||||
if receive_allow_receiver_shutdown:
|
|
||||||
self.receive_allow_receiver_shutdown_checkbox.setCheckState(QtCore.Qt.Checked)
|
|
||||||
else:
|
|
||||||
self.receive_allow_receiver_shutdown_checkbox.setCheckState(QtCore.Qt.Unchecked)
|
|
||||||
|
|
||||||
public_mode = self.old_settings.get('public_mode')
|
public_mode = self.old_settings.get('public_mode')
|
||||||
if public_mode:
|
if public_mode:
|
||||||
self.public_mode_checkbox.setCheckState(QtCore.Qt.Checked)
|
self.public_mode_checkbox.setCheckState(QtCore.Qt.Checked)
|
||||||
@ -965,7 +953,6 @@ class SettingsDialog(QtWidgets.QDialog):
|
|||||||
settings.set('hidservauth_string', '')
|
settings.set('hidservauth_string', '')
|
||||||
|
|
||||||
settings.set('downloads_dir', self.downloads_dir_lineedit.text())
|
settings.set('downloads_dir', self.downloads_dir_lineedit.text())
|
||||||
settings.set('receive_allow_receiver_shutdown', self.receive_allow_receiver_shutdown_checkbox.isChecked())
|
|
||||||
settings.set('public_mode', self.public_mode_checkbox.isChecked())
|
settings.set('public_mode', self.public_mode_checkbox.isChecked())
|
||||||
settings.set('use_stealth', self.stealth_checkbox.isChecked())
|
settings.set('use_stealth', self.stealth_checkbox.isChecked())
|
||||||
# Always unset the HidServAuth if Stealth mode is unset
|
# Always unset the HidServAuth if Stealth mode is unset
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"close_on_timeout": "Stopped because auto-stop timer ran out",
|
"close_on_timeout": "Stopped because auto-stop timer ran out",
|
||||||
"closing_automatically": "Stopped because download finished",
|
"closing_automatically": "Stopped because download finished",
|
||||||
"timeout_download_still_running": "Waiting for download to complete",
|
"timeout_download_still_running": "Waiting for download to complete",
|
||||||
|
"timeout_upload_still_running": "Waiting for upload to complete",
|
||||||
"large_filesize": "Warning: Sending a large share could take hours",
|
"large_filesize": "Warning: Sending a large share could take hours",
|
||||||
"systray_menu_exit": "Quit",
|
"systray_menu_exit": "Quit",
|
||||||
"systray_download_started_title": "OnionShare Download Started",
|
"systray_download_started_title": "OnionShare Download Started",
|
||||||
@ -165,7 +166,6 @@
|
|||||||
"gui_settings_receiving_label": "Receiving settings",
|
"gui_settings_receiving_label": "Receiving settings",
|
||||||
"gui_settings_downloads_label": "Save files to",
|
"gui_settings_downloads_label": "Save files to",
|
||||||
"gui_settings_downloads_button": "Browse",
|
"gui_settings_downloads_button": "Browse",
|
||||||
"gui_settings_receive_allow_receiver_shutdown_checkbox": "Receive mode can be stopped by the sender",
|
|
||||||
"gui_settings_public_mode_checkbox": "Public mode",
|
"gui_settings_public_mode_checkbox": "Public mode",
|
||||||
"systray_close_server_title": "OnionShare Server Closed",
|
"systray_close_server_title": "OnionShare Server Closed",
|
||||||
"systray_close_server_message": "A user closed the server",
|
"systray_close_server_message": "A user closed the server",
|
||||||
|
16
share/templates/403.html
Normal file
16
share/templates/403.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>OnionShare: 403 Forbidden</title>
|
||||||
|
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon" />
|
||||||
|
<link href="/static/css/style.css" rel="stylesheet" type="text/css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="info-wrapper">
|
||||||
|
<div class="info">
|
||||||
|
<p><img class="logo" src="/static/img/logo_large.png" title="OnionShare"></p>
|
||||||
|
<p class="info-header">You are not allowed to perform that action at this time.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -34,14 +34,5 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if receive_allow_receiver_shutdown %}
|
|
||||||
{% with messages = get_flashed_messages() %}
|
|
||||||
{% if messages %}
|
|
||||||
<form method="post" action="{{ close_action }}">
|
|
||||||
<input type="submit" class="close-button" value="I'm Finished Sending" />
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endif %}
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -85,11 +85,6 @@ class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest):
|
|||||||
|
|
||||||
# receive mode
|
# receive mode
|
||||||
self.gui.downloads_dir_lineedit.setText('/tmp/OnionShareSettingsTest')
|
self.gui.downloads_dir_lineedit.setText('/tmp/OnionShareSettingsTest')
|
||||||
# allow receiver shutdown is on
|
|
||||||
self.assertTrue(self.gui.receive_allow_receiver_shutdown_checkbox.isChecked())
|
|
||||||
# disable receiver shutdown
|
|
||||||
QtTest.QTest.mouseClick(self.gui.receive_allow_receiver_shutdown_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.receive_allow_receiver_shutdown_checkbox.height()/2))
|
|
||||||
self.assertFalse(self.gui.receive_allow_receiver_shutdown_checkbox.isChecked())
|
|
||||||
|
|
||||||
|
|
||||||
# bundled mode is enabled
|
# bundled mode is enabled
|
||||||
@ -168,7 +163,6 @@ class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest):
|
|||||||
self.assertTrue(data["save_private_key"])
|
self.assertTrue(data["save_private_key"])
|
||||||
self.assertTrue(data["use_stealth"])
|
self.assertTrue(data["use_stealth"])
|
||||||
self.assertEqual(data["downloads_dir"], "/tmp/OnionShareSettingsTest")
|
self.assertEqual(data["downloads_dir"], "/tmp/OnionShareSettingsTest")
|
||||||
self.assertFalse(data["receive_allow_receiver_shutdown"])
|
|
||||||
self.assertFalse(data["close_after_first_download"])
|
self.assertFalse(data["close_after_first_download"])
|
||||||
self.assertEqual(data["connection_type"], "bundled")
|
self.assertEqual(data["connection_type"], "bundled")
|
||||||
self.assertFalse(data["tor_bridges_use_obfs4"])
|
self.assertFalse(data["tor_bridges_use_obfs4"])
|
||||||
|
@ -65,7 +65,6 @@ class TestSettings:
|
|||||||
'slug': '',
|
'slug': '',
|
||||||
'hidservauth_string': '',
|
'hidservauth_string': '',
|
||||||
'downloads_dir': os.path.expanduser('~/OnionShare'),
|
'downloads_dir': os.path.expanduser('~/OnionShare'),
|
||||||
'receive_allow_receiver_shutdown': True,
|
|
||||||
'public_mode': False
|
'public_mode': False
|
||||||
}
|
}
|
||||||
for key in settings_obj._settings:
|
for key in settings_obj._settings:
|
||||||
|
@ -139,36 +139,6 @@ class TestWeb:
|
|||||||
res.get_data()
|
res.get_data()
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
|
|
||||||
def test_receive_mode_allow_receiver_shutdown_on(self, common_obj):
|
|
||||||
web = web_obj(common_obj, 'receive')
|
|
||||||
|
|
||||||
common_obj.settings.set('receive_allow_receiver_shutdown', True)
|
|
||||||
|
|
||||||
assert web.running == True
|
|
||||||
|
|
||||||
with web.app.test_client() as c:
|
|
||||||
# Load close page
|
|
||||||
res = c.post('/{}/close'.format(web.slug))
|
|
||||||
res.get_data()
|
|
||||||
# Should return ok, and server should stop
|
|
||||||
assert res.status_code == 200
|
|
||||||
assert web.running == False
|
|
||||||
|
|
||||||
def test_receive_mode_allow_receiver_shutdown_off(self, common_obj):
|
|
||||||
web = web_obj(common_obj, 'receive')
|
|
||||||
|
|
||||||
common_obj.settings.set('receive_allow_receiver_shutdown', False)
|
|
||||||
|
|
||||||
assert web.running == True
|
|
||||||
|
|
||||||
with web.app.test_client() as c:
|
|
||||||
# Load close page
|
|
||||||
res = c.post('/{}/close'.format(web.slug))
|
|
||||||
res.get_data()
|
|
||||||
# Should redirect to index, and server should still be running
|
|
||||||
assert res.status_code == 302
|
|
||||||
assert web.running == True
|
|
||||||
|
|
||||||
def test_public_mode_on(self, common_obj):
|
def test_public_mode_on(self, common_obj):
|
||||||
web = web_obj(common_obj, 'receive')
|
web = web_obj(common_obj, 'receive')
|
||||||
common_obj.settings.set('public_mode', True)
|
common_obj.settings.set('public_mode', True)
|
||||||
|
Loading…
Reference in New Issue
Block a user