diff --git a/src/ttfrog/bootstrap.py b/src/ttfrog/bootstrap.py index 731cc88..c18470a 100644 --- a/src/ttfrog/bootstrap.py +++ b/src/ttfrog/bootstrap.py @@ -39,6 +39,9 @@ def bootstrap(): """ app.check_state() + # the system user does not get added to the list of Users. + app.db.save(schema.User(name="__system__")) + # create the top-level pages root = app.db.save(schema.Page(name=app.config.VIEW_URI, body=b"This is the home page", uri="")) diff --git a/src/ttfrog/forms.py b/src/ttfrog/forms.py index c925eea..4d91563 100644 --- a/src/ttfrog/forms.py +++ b/src/ttfrog/forms.py @@ -30,13 +30,11 @@ class Form: def prepare(self): for key, value in self.data.items(): - # filter out fields that cannot be set by the user if key in self.read_only: continue if self.record[key] != value: - logger.debug(f"Updating {self.record.__class__.__name__}[{self.record.doc_id}] {key}={value}") self.record[key] = value - self.record.author = g.user + self.record.author = None if self.record == g.user else g.user return self.record diff --git a/src/ttfrog/schema.py b/src/ttfrog/schema.py index 93b89f1..93109e0 100644 --- a/src/ttfrog/schema.py +++ b/src/ttfrog/schema.py @@ -20,6 +20,13 @@ from grung.types import ( from tinydb import where +def app_context(): + import ttfrog.app + + ttfrog.app.check_state() + return ttfrog.app + + class Permissions(StrEnum): READ = "r" WRITE = "w" @@ -58,20 +65,21 @@ class Page(Record): ] # fmt: on - def parent(self, db): + def parent(self): if self.uri == "": return None + app = app_context() + parent_uri = "" if "/" in self.uri: parent_uri = self.uri.rsplit("/", 1)[0] - print(f"Checking for parent at {parent_uri=}") - for table_name in db.tables(): - page = db.table(table_name).get(where('uri') == parent_uri, recurse=False) + for table_name in app.db.tables(): + page = app.db.table(table_name).get(where("uri") == parent_uri, recurse=False) if page: return page - def before_insert(self, db): + def before_insert(self, *args, **kwargs): """ Make the following adjustments before saving this record: * Derive the URI from the hierarchy of the parent. @@ -79,16 +87,20 @@ class Page(Record): if not self.name: raise Exception("Must provide a name") - super().before_insert(db) + app = app_context() + + super().before_insert(app.db) + + if not self.author: + self.author = app.db.User.get(where('name') == '__system__') now = datetime.utcnow() if not self.doc_id and self.created < now: self.created = now def add_member(self, child: Record): - from ttfrog import app + app = app_context() - app.check_state() prefix = (self.uri + "/") if self.uri else "" new_uri = f"{prefix}{child.name}" if child.uri != new_uri: @@ -105,9 +117,7 @@ class Page(Record): return None def set_permissions(self, entity: Entity, permissions: List) -> str: - from ttfrog import app - - app.check_state() + app = app_context() perms = "".join(permissions) self.acl[entity.reference] = perms @@ -119,9 +129,7 @@ class Page(Record): Search upward through the page hierarchy looking for one with an ACL that either has a grant for the entity we care about, or at least one group in which the entity is a member. """ - from ttfrog import app - - app.check_state() + app = app_context() def find_acl(obj): if hasattr(obj, "acl"): @@ -139,7 +147,7 @@ class Page(Record): return group_grants if hasattr(obj, "parent"): - return find_acl(obj.parent(app.db)) + return find_acl(obj.parent()) return {"": ""} return find_acl(self) @@ -184,20 +192,20 @@ class User(Entity): def check_credentials(self, username: str, password: str) -> bool: return username == self.name and self._metadata.fields["password"].compare(password, self.password) - def after_insert(self, db): + def after_insert(self, *args, **kwargs): """ After saving this record, ensure that any page in the members collection is updated with the correct URI. This ensures that if a page is moved from one collection to another, the URI is updated. """ - super().after_insert(db) - for name, _field in self._metadata.fields.items(): - _field.after_insert(db, self) + app = app_context() + + super().after_insert(app.db) if not hasattr(self, "members"): return for child in self.members: - obj = BackReference.dereference(child, db, recurse=False) + obj = BackReference.dereference(child, app.db, recurse=False) obj.uri = f"{self.uri}/{obj.name}" - child = db.save(obj) + child = app.db.save(obj) class Group(Entity):