Make permissions hierarchical
This commit is contained in:
parent
0e8fd9a1b0
commit
582fd2d9a1
|
@ -145,18 +145,17 @@ VIEW_URI=/
|
|||
admins = self.add_member(groups, admins)
|
||||
admin = self.add_member(admins, admin)
|
||||
|
||||
groups.set_permissions(admins, permissions=[
|
||||
schema.Permissions.READ,
|
||||
schema.Permissions.WRITE,
|
||||
schema.Permissions.DELETE
|
||||
], db=self.db)
|
||||
|
||||
users.set_permissions(admins, permissions=[
|
||||
schema.Permissions.READ,
|
||||
schema.Permissions.WRITE,
|
||||
schema.Permissions.DELETE
|
||||
], db=self.db)
|
||||
groups.set_permissions(
|
||||
admins,
|
||||
permissions=[schema.Permissions.READ, schema.Permissions.WRITE, schema.Permissions.DELETE],
|
||||
db=self.db,
|
||||
)
|
||||
|
||||
users.set_permissions(
|
||||
admins,
|
||||
permissions=[schema.Permissions.READ, schema.Permissions.WRITE, schema.Permissions.DELETE],
|
||||
db=self.db,
|
||||
)
|
||||
|
||||
|
||||
sys.modules[__name__] = ApplicationContext()
|
||||
|
|
|
@ -76,10 +76,20 @@ class Page(Record):
|
|||
|
||||
|
||||
class Entity(Page):
|
||||
def has_permission(self, record: Record, requested: str, db) -> bool:
|
||||
def has_permission(self, record: Record, requested: str, db) -> bool | None:
|
||||
|
||||
# if there's no ACL at all, the record is world-readable.
|
||||
if not getattr(record, "acl", None):
|
||||
# Find a non-empty ACL to use by starting with the requested reecord and traversing
|
||||
# the hierarchy upwards. If we get to the root and there's no ACL anywhere, default
|
||||
# to READ permissions.
|
||||
def find_acl(obj):
|
||||
if hasattr(obj, 'acl') and obj.acl:
|
||||
return obj.acl
|
||||
if not hasattr(obj, "parent"):
|
||||
return None
|
||||
return find_acl(obj.parent)
|
||||
|
||||
acl = find_acl(record)
|
||||
if not acl:
|
||||
return requested == Permissions.READ
|
||||
|
||||
# Use the grant specific to this entity, if there is one
|
||||
|
@ -87,9 +97,11 @@ class Entity(Page):
|
|||
if entry.entity.uid == self.uid:
|
||||
return requested in entry.grants
|
||||
|
||||
# Check for grants for each of the entity's groups, if any
|
||||
for group in db.Group.search(Query()["members"].any([self.reference])):
|
||||
if group.has_permission(record, requested, db):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def can_read(self, record: Record, db):
|
||||
|
@ -106,7 +118,6 @@ class User(Entity):
|
|||
"""
|
||||
A website user, editable as a wiki page.
|
||||
"""
|
||||
|
||||
def check_credentials(self, username: str, password: str) -> bool:
|
||||
return username == self.name and self._metadata.fields["password"].compare(password, self.password)
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
{% if session['user_id'] == 1 %}
|
||||
Welcome, {{ user['name'] }}. [ <a href="{{ url_for('login') }}">LOGIN</a> ]
|
||||
{% else %}
|
||||
Welcome, <a href="{{ url_for('User/' + user['name']) }}">{{ user['name'] }}</a>.
|
||||
Welcome, <a href="{{ url_for('view', path='User/' + user['name']) }}">{{ user['name'] }}</a>.
|
||||
{% endif %}
|
||||
<nav>
|
||||
Menu:
|
||||
|
|
|
@ -64,7 +64,7 @@ def get_page(path: str = "", table: str = "Page", create_okay: bool = False):
|
|||
def rendered(page: schema.Record, template: str = "page.html"):
|
||||
if not page:
|
||||
return Response("Page not found", status=404)
|
||||
return render_template(template, page=page, app=app, breadcrumbs=breadcrumbs(), user=session['user'], g=g)
|
||||
return render_template(template, page=page, app=app, breadcrumbs=breadcrumbs(), user=session["user"], g=g)
|
||||
|
||||
|
||||
def get_static(path):
|
||||
|
@ -94,13 +94,16 @@ def do_login(username: str, password: str) -> bool:
|
|||
Update the session with the user record if the credenteials are valid.
|
||||
"""
|
||||
if not (username and password):
|
||||
app.web.logger.debug("Need both username and password to login")
|
||||
return False
|
||||
|
||||
user = app.db.User.get(where("name") == "username")
|
||||
user = app.db.User.get(where("name") == username)
|
||||
if not user:
|
||||
app.web.logger.debug(f"No user matching {username}")
|
||||
return False
|
||||
|
||||
if not user.check_credentials(username, password):
|
||||
app.web.logger.debug(f"Invalid credentials for {username}")
|
||||
return False
|
||||
|
||||
app.web.logger.debug(f"Session for {user.name} ({user.doc_id}) started.")
|
||||
|
@ -113,7 +116,6 @@ def do_login(username: str, password: str) -> bool:
|
|||
@app.web.route("/login", methods=["GET", "POST"])
|
||||
def login():
|
||||
app.web.session_interface.regenerate(session)
|
||||
|
||||
if request.method == "POST":
|
||||
username = request.form.get("username")
|
||||
password = request.form.get("password")
|
||||
|
|
Loading…
Reference in New Issue
Block a user