from dataclasses import dataclass
from typing import Any, Callable
from base64 import b64encode, b64decode
+from binascii import Error as binascii_Exception
from http.server import BaseHTTPRequestHandler
from http.server import HTTPServer
from urllib.parse import urlparse, parse_qs
returns successfully, or right after any exception is triggered –
otherwise, race conditions become plausible.
- Note that any POST attempt, even a failed one, may end in problematic
- inconsistencies:
+ Note that otherwise any POST attempt, even a failed one, may end in
+ problematic inconsistencies:
- if the POST handler experiences an Exception, changes to objects
won't get written to the DB, but the changed objects may remain in
if hasattr(self, handler_name):
handler = getattr(self, handler_name)
redir_target = f(self, handler)
- if 'POST' != http_method:
- clear_caches()
+ if 'POST' == http_method:
+ clear_caches()
if redir_target:
self.send_response(302)
self.send_header('Location', redir_target)
msg = f'{not_found_msg}: {self._site}'
raise NotFoundException(msg)
except HandledException as error:
- if 'POST' != http_method:
- clear_caches()
+ if 'POST' == http_method:
+ clear_caches()
ctx = {'msg': error}
self._send_page(ctx, 'msg', error.http_code)
finally:
owned_ids = self._params.get_all_int('has_step')
title_64 = self._params.get_str('title_b64')
if title_64:
- title = b64decode(title_64.encode()).decode()
+ try:
+ title = b64decode(title_64.encode()).decode()
+ except binascii_Exception as exc:
+ msg = 'invalid base64 for ?title_b64='
+ raise BadFormatException(msg) from exc
process.title.set(title)
+ preset_top_step = None
owners = process.used_as_step_by(self.conn)
for step_id in owner_ids:
owners += [Process.by_id(self.conn, step_id)]
- preset_top_step = None
for process_id in owned_ids:
+ Process.by_id(self.conn, process_id) # to ensure ID exists
preset_top_step = process_id
return {'process': process, 'is_new': process.id_ is None,
'preset_top_step': preset_top_step,