From bbfabe530dc3a6ef613db3f9fd94777816e409e5 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Wed, 6 Jul 2022 00:46:26 +0200 Subject: use ACLs for upload authorization --- fietsboek/models/track.py | 6 ++++++ fietsboek/views/upload.py | 23 ++++++----------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/fietsboek/models/track.py b/fietsboek/models/track.py index 0235231..1b297fe 100644 --- a/fietsboek/models/track.py +++ b/fietsboek/models/track.py @@ -546,6 +546,12 @@ class Upload(Base): raise HTTPNotFound() return upload + def __acl__(self): + return [ + (Allow, 'group:admins', ALL_PERMISSIONS), + (Allow, f'user:{self.owner_id}', 'upload.finish'), + ] + @property def gpx_data(self): """Access the decompressed gpx data.""" diff --git a/fietsboek/views/upload.py b/fietsboek/views/upload.py index 59123ee..5e67aa5 100644 --- a/fietsboek/views/upload.py +++ b/fietsboek/views/upload.py @@ -2,7 +2,7 @@ import datetime import logging -from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPBadRequest +from pyramid.httpexceptions import HTTPFound, HTTPBadRequest from pyramid.response import Response from pyramid.view import view_config from pyramid.i18n import TranslationString as _ @@ -75,7 +75,7 @@ def do_upload(request): return HTTPFound(request.route_url('finish-upload', upload_id=upload.id)) -@view_config(route_name='preview', permission='upload') +@view_config(route_name='preview', permission='upload.finish') def preview(request): """Allows a preview of the uploaded track by returning the GPX data of a :class:`~fietsboek.models.track.Upload` @@ -86,13 +86,11 @@ def preview(request): :rtype: pyramid.response.Response """ upload = request.context - if upload.owner != request.identity: - return HTTPForbidden() return Response(upload.gpx_data, content_type='application/gpx+xml') @view_config(route_name='finish-upload', renderer='fietsboek:templates/finish_upload.jinja2', - request_method='GET', permission='upload') + request_method='GET', permission='upload.finish') def finish_upload(request): """Renders the form that allows the user to finish the upload. @@ -102,9 +100,6 @@ def finish_upload(request): :rtype: pyramid.response.Response """ upload = request.context - if upload.owner != request.identity: - return HTTPForbidden() - badges = request.dbsession.execute(select(models.Badge)).scalars() badges = [(False, badge) for badge in badges] gpx = gpxpy.parse(upload.gpx_data) @@ -121,7 +116,7 @@ def finish_upload(request): } -@view_config(route_name='finish-upload', request_method='POST', permission='upload') +@view_config(route_name='finish-upload', request_method='POST', permission='upload.finish') def do_finish_upload(request): """Endpoint for the "finishing upload" form. @@ -131,9 +126,6 @@ def do_finish_upload(request): :rtype: pyramid.response.Response """ upload = request.context - if upload.owner != request.identity: - return HTTPForbidden() - user_friends = request.identity.get_friends() badges = util.retrieve_multiple(request.dbsession, models.Badge, request.params, "badge[]") tagged_people = util.retrieve_multiple(request.dbsession, models.User, @@ -167,7 +159,7 @@ def do_finish_upload(request): return HTTPFound(request.route_url('details', track_id=track.id)) -@view_config(route_name='cancel-upload', permission='upload') +@view_config(route_name='cancel-upload', permission='upload.finish') def cancel_upload(request): """Cancels the upload and clears the temporary data. @@ -176,10 +168,7 @@ def cancel_upload(request): :return: The HTTP response. :rtype: pyramid.response.Response """ - query = select(models.Upload).filter_by(id=request.matchdict["id"]) - upload = request.dbsession.execute(query).scalar_one() - if upload.owner != request.identity: - return HTTPForbidden() + upload = request.context request.dbsession.delete(upload) request.session.flash(request.localizer.translate(_("flash.upload_cancelled"))) return HTTPFound(request.route_url('upload')) -- cgit v1.2.3