streetsign_server.logic¶
When the views start becoming overly complex, as much as possible the logic should be split out to sane sizes functions over here in logic.
Feeds and Posts¶
streetsign_server.logic.feeds_and_posts¶
logic for feeds_and_posts views, separated out for clarity.
- streetsign_server.logic.feeds_and_posts.can_user_write_and_publish(user, post)¶
returns a tuple, expressing if ‘user’ has permission to write and publish a post.
- streetsign_server.logic.feeds_and_posts.clean_date(in_text)¶
take some input text, and return a datetime, if possible.
- streetsign_server.logic.feeds_and_posts.cleanup_orphaned_media_files()¶
Scan post_images/ and post_videos/ directories for files that have no corresponding Post record in the database, and remove them. Also removes orphaned thumbnails. Returns a dict with counts of removed files and thumbnails.
- streetsign_server.logic.feeds_and_posts.delete_post_and_run_callback(post, typemodule)¶
before a post is actually deleted, check if there is a ‘pre-delete’ callback on this post type, and run that first. This way, for uploaded images (for instance), the file can be deleted as well.
- streetsign_server.logic.feeds_and_posts.if_i_cant_write_then_i_quit(post, user)¶
checks if a post is editable by a user. If it isn’t, for whatever reason, then raise an appropriate ‘PleaseRedirect’ exception. (reasons could be that it’s in a feed we don’t have write access to, or it’s been published, and we don’t have publish permission to that feed, so the post is now ‘locked’ to us.)
- streetsign_server.logic.feeds_and_posts.import_source_posts(source)¶
Import new posts from an ExternalSource. Returns the number of new posts created. The caller is responsible for calling source.save() if needed.
- streetsign_server.logic.feeds_and_posts.post_form_intake(post, form, editor)¶
takes the values from ‘form’, passes the post contents to the editor ‘receive’ function, and adds all the values into the ‘post’ object.
NOTE: this actually modifies the post it is sent!
- streetsign_server.logic.feeds_and_posts.try_to_set_feed(post, new_feed_id, user)¶
Is this user actually allowed to set the feed of this post to what the form is saying they want to? If so, cool. Return that feed.
Connected Clients¶
streetsign_server.logic.clients¶
Tracks connected display clients and provides a “force refresh” command channel.
Display screens are anonymous browsers that poll the server for content. They
send a lightweight heartbeat (see static/screens/heartbeat.js) which
registers their IP address against the screen/alias they are showing. Admins
can bump a per-target refresh counter which the heartbeat hands back to the
client, causing it to reload.
Presence and refresh state are ephemeral and process-local, which matches the
single-process waitress deployment (see run.py). Nothing here is used for
authentication.
- streetsign_server.logic.clients.client_ip(request)¶
Real client IP for request.
When StreetSign runs behind trusted reverse proxies, the
ProxyFixmiddleware (wired up instreetsign_serverfrom theTRUSTED_PROXY_HOPSconfig) has already rewrittenrequest.remote_addrfromX-Forwarded-For. Otherwise this is the socket peer. The result is informational only; authentication and rate limiting use the samerequest.remote_addr, soTRUSTED_PROXY_HOPSmust match the real number of proxies for that value to be trustworthy.
- streetsign_server.logic.clients.connected_clients()¶
Return the list of clients seen within
SCREEN_CLIENT_TTLseconds.Stale entries are purged as a side effect. Each item is a plain dict with an ISO formatted
last_seentimestamp, ready to be JSON serialised.
- streetsign_server.logic.clients.record_heartbeat(screen_id, screen_name, alias, ip, user_agent)¶
Register a display client as connected and return its refresh state.
Returns a dict suitable for sending straight back to the client.
- streetsign_server.logic.clients.request_refresh(target='all')¶
Bump the refresh counter for target, forcing matching clients to reload on their next heartbeat. Returns the new counter value.
Raises
ValueErrorfor an unrecognised target.
- streetsign_server.logic.clients.reset()¶
Clear all presence and refresh state. Used by tests.
URL Safety¶
streetsign_server.logic.urlsafety¶
Validation helpers to guard server-side URL fetches against SSRF.
StreetSign fetches some URLs server-side (RSS feeds, externally-hosted images). Without restriction these are SSRF sinks - an admin (or anyone who can ride an admin session via CSRF) could point the server at internal services (e.g. cloud metadata at 169.254.169.254), at localhost, or at local files via file://. These helpers restrict such fetches to http(s) URLs that resolve to public addresses.
- exception streetsign_server.logic.urlsafety.UnsafeURL¶
Raised when a URL is not safe to fetch server-side.
- streetsign_server.logic.urlsafety.check_fetch_url(url, resolve=True)¶
Raise UnsafeURL if url is not safe to fetch from the server.
Checks the scheme is http(s), that there is a hostname, and (when resolve is True) that the hostname does not resolve to a private, loopback, or link-local address. Returns the url unchanged if OK.