Add system user, prevent circular refs in author
This commit is contained in:
parent
5fffbf59f5
commit
f6efbeb54a
|
|
@ -39,6 +39,9 @@ def bootstrap():
|
||||||
"""
|
"""
|
||||||
app.check_state()
|
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
|
# create the top-level pages
|
||||||
root = app.db.save(schema.Page(name=app.config.VIEW_URI, body=b"This is the home page", uri=""))
|
root = app.db.save(schema.Page(name=app.config.VIEW_URI, body=b"This is the home page", uri=""))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,11 @@ class Form:
|
||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
for key, value in self.data.items():
|
for key, value in self.data.items():
|
||||||
# filter out fields that cannot be set by the user
|
|
||||||
if key in self.read_only:
|
if key in self.read_only:
|
||||||
continue
|
continue
|
||||||
if self.record[key] != value:
|
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[key] = value
|
||||||
self.record.author = g.user
|
self.record.author = None if self.record == g.user else g.user
|
||||||
return self.record
|
return self.record
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,13 @@ from grung.types import (
|
||||||
from tinydb import where
|
from tinydb import where
|
||||||
|
|
||||||
|
|
||||||
|
def app_context():
|
||||||
|
import ttfrog.app
|
||||||
|
|
||||||
|
ttfrog.app.check_state()
|
||||||
|
return ttfrog.app
|
||||||
|
|
||||||
|
|
||||||
class Permissions(StrEnum):
|
class Permissions(StrEnum):
|
||||||
READ = "r"
|
READ = "r"
|
||||||
WRITE = "w"
|
WRITE = "w"
|
||||||
|
|
@ -58,20 +65,21 @@ class Page(Record):
|
||||||
]
|
]
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
def parent(self, db):
|
def parent(self):
|
||||||
if self.uri == "":
|
if self.uri == "":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
app = app_context()
|
||||||
|
|
||||||
parent_uri = ""
|
parent_uri = ""
|
||||||
if "/" in self.uri:
|
if "/" in self.uri:
|
||||||
parent_uri = self.uri.rsplit("/", 1)[0]
|
parent_uri = self.uri.rsplit("/", 1)[0]
|
||||||
print(f"Checking for parent at {parent_uri=}")
|
for table_name in app.db.tables():
|
||||||
for table_name in db.tables():
|
page = app.db.table(table_name).get(where("uri") == parent_uri, recurse=False)
|
||||||
page = db.table(table_name).get(where('uri') == parent_uri, recurse=False)
|
|
||||||
if page:
|
if page:
|
||||||
return page
|
return page
|
||||||
|
|
||||||
def before_insert(self, db):
|
def before_insert(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Make the following adjustments before saving this record:
|
Make the following adjustments before saving this record:
|
||||||
* Derive the URI from the hierarchy of the parent.
|
* Derive the URI from the hierarchy of the parent.
|
||||||
|
|
@ -79,16 +87,20 @@ class Page(Record):
|
||||||
if not self.name:
|
if not self.name:
|
||||||
raise Exception("Must provide a 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()
|
now = datetime.utcnow()
|
||||||
if not self.doc_id and self.created < now:
|
if not self.doc_id and self.created < now:
|
||||||
self.created = now
|
self.created = now
|
||||||
|
|
||||||
def add_member(self, child: Record):
|
def add_member(self, child: Record):
|
||||||
from ttfrog import app
|
app = app_context()
|
||||||
|
|
||||||
app.check_state()
|
|
||||||
prefix = (self.uri + "/") if self.uri else ""
|
prefix = (self.uri + "/") if self.uri else ""
|
||||||
new_uri = f"{prefix}{child.name}"
|
new_uri = f"{prefix}{child.name}"
|
||||||
if child.uri != new_uri:
|
if child.uri != new_uri:
|
||||||
|
|
@ -105,9 +117,7 @@ class Page(Record):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set_permissions(self, entity: Entity, permissions: List) -> str:
|
def set_permissions(self, entity: Entity, permissions: List) -> str:
|
||||||
from ttfrog import app
|
app = app_context()
|
||||||
|
|
||||||
app.check_state()
|
|
||||||
|
|
||||||
perms = "".join(permissions)
|
perms = "".join(permissions)
|
||||||
self.acl[entity.reference] = perms
|
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
|
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.
|
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 = app_context()
|
||||||
|
|
||||||
app.check_state()
|
|
||||||
|
|
||||||
def find_acl(obj):
|
def find_acl(obj):
|
||||||
if hasattr(obj, "acl"):
|
if hasattr(obj, "acl"):
|
||||||
|
|
@ -139,7 +147,7 @@ class Page(Record):
|
||||||
return group_grants
|
return group_grants
|
||||||
|
|
||||||
if hasattr(obj, "parent"):
|
if hasattr(obj, "parent"):
|
||||||
return find_acl(obj.parent(app.db))
|
return find_acl(obj.parent())
|
||||||
return {"": ""}
|
return {"": ""}
|
||||||
|
|
||||||
return find_acl(self)
|
return find_acl(self)
|
||||||
|
|
@ -184,20 +192,20 @@ class User(Entity):
|
||||||
def check_credentials(self, username: str, password: str) -> bool:
|
def check_credentials(self, username: str, password: str) -> bool:
|
||||||
return username == self.name and self._metadata.fields["password"].compare(password, self.password)
|
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
|
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.
|
correct URI. This ensures that if a page is moved from one collection to another, the URI is updated.
|
||||||
"""
|
"""
|
||||||
super().after_insert(db)
|
app = app_context()
|
||||||
for name, _field in self._metadata.fields.items():
|
|
||||||
_field.after_insert(db, self)
|
super().after_insert(app.db)
|
||||||
if not hasattr(self, "members"):
|
if not hasattr(self, "members"):
|
||||||
return
|
return
|
||||||
for child in self.members:
|
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}"
|
obj.uri = f"{self.uri}/{obj.name}"
|
||||||
child = db.save(obj)
|
child = app.db.save(obj)
|
||||||
|
|
||||||
|
|
||||||
class Group(Entity):
|
class Group(Entity):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user