Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish flask restx migration #3205

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 20 additions & 61 deletions frontend/coprs_frontend/coprs/views/apiv3_ns/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,39 +95,6 @@ def query_params_wrapper(*args, **kwargs):
return query_params_decorator


def _shared_pagination_wrapper(**kwargs):
form = PaginationForm(flask.request.args)
if not form.validate():
raise CoprHttpException(form.errors)
kwargs.update(form.data)
return kwargs


def pagination():
def pagination_decorator(f):
@wraps(f)
def pagination_wrapper(*args, **kwargs):
kwargs = _shared_pagination_wrapper(**kwargs)
return f(*args, **kwargs)
return pagination_wrapper
return pagination_decorator


def _shared_file_upload_wrapper():
data = json.loads(flask.request.files["json"].read()) or {}
flask.request.form = ImmutableMultiDict(list(data.items()))

def file_upload():
def file_upload_decorator(f):
@wraps(f)
def file_upload_wrapper(*args, **kwargs):
if "json" in flask.request.files:
_shared_file_upload_wrapper()
return f(*args, **kwargs)
return file_upload_wrapper
return file_upload_decorator


class PaginationForm(wtforms.Form):
limit = wtforms.IntegerField("Limit", validators=[wtforms.validators.Optional()])
offset = wtforms.IntegerField("Offset", validators=[wtforms.validators.Optional()])
Expand Down Expand Up @@ -249,27 +216,6 @@ def get(self):
return objects[self.offset : limit]


def _check_if_user_can_edit_copr(ownername, projectname):
copr = get_copr(ownername, projectname)
if not flask.g.user.can_edit(copr):
raise AccessRestricted(
"User '{0}' can not see permissions for project '{1}' " \
"(missing admin rights)".format(
flask.g.user.name,
'/'.join([ownername, projectname])
)
)
return copr


def editable_copr(f):
@wraps(f)
def wrapper(ownername, projectname):
copr = _check_if_user_can_edit_copr(ownername, projectname)
return f(copr)
return wrapper


def set_defaults(formdata, form_class):
"""
Take a `formdata` which can be `flask.request.form` or an output from
Expand Down Expand Up @@ -481,42 +427,55 @@ def call_deprecated_endpoint_method(endpoint_method):
return call_deprecated_endpoint_method


def restx_editable_copr(endpoint_method):
def editable_copr(endpoint_method):
"""
Raises an exception if user don't have permissions for editing Copr repo.
Order matters! If flask.g.user is None then this will fail! If used with
@api_login_required it has to be called after it:

@api_login_required
@restx_editable_copr
@editable_copr
...
"""
@wraps(endpoint_method)
def editable_copr_getter(self, ownername, projectname):
copr = _check_if_user_can_edit_copr(ownername, projectname)
copr = get_copr(ownername, projectname)
if not flask.g.user.can_edit(copr):
raise AccessRestricted(
"User '{0}' can not see permissions for project '{1}' " \
"(missing admin rights)".format(
flask.g.user.name,
'/'.join([ownername, projectname])
)
)

nikromen marked this conversation as resolved.
Show resolved Hide resolved
return endpoint_method(self, copr)
return editable_copr_getter


def restx_pagination(endpoint_method):
def pagination(endpoint_method):
"""
Validates pagination arguments and converts pagination parameters from query to
kwargs.
"""
@wraps(endpoint_method)
def create_pagination(self, *args, **kwargs):
kwargs = _shared_pagination_wrapper(**kwargs)
form = PaginationForm(flask.request.args)
if not form.validate():
raise CoprHttpException(form.errors)
kwargs.update(form.data)
return endpoint_method(self, *args, **kwargs)
return create_pagination


def restx_file_upload(endpoint_method):
def file_upload(endpoint_method):
"""
Allow uploading a file to a form via endpoint by using this function as an endpoint decorator.
"""
@wraps(endpoint_method)
def inner(self, *args, **kwargs):
if "json" in flask.request.files:
_shared_file_upload_wrapper()
data = json.loads(flask.request.files["json"].read()) or {}
flask.request.form = ImmutableMultiDict(list(data.items()))
return endpoint_method(self, *args, **kwargs)
return inner
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
build_chroot_config_model,
nevra_packages_model,
)
from coprs.views.apiv3_ns import restx_pagination
from coprs.views.apiv3_ns import pagination
from . import Paginator


Expand Down Expand Up @@ -83,7 +83,7 @@ def get(self, build_id, chrootname):
doc={"deprecated": True, "description": "Use query parameters instead"},
)
class BuildChrootList(Resource):
@restx_pagination
@pagination
@query_to_parameters
@apiv3_bchroots_ns.doc(params=build_id_params | pagination_params)
@apiv3_bchroots_ns.marshal_list_with(pagination_build_chroot_model)
Expand Down
Loading