Validate GraphQL response on build submission

The GraphQL API does a stricter validation of the manifest then the
Python code, specifically e.g. checking the `oauth:` directive. This can
lead to the API rejecting a manifest that passed the Python validation.
However, for this case, there is currently no error handling, causing
an exception. Such a case has been reported e.g. here: [1]

This commit adds such error handling by passing down the Validation
object all the way to the GraphQL call (which already accepts it). Only
caveat is that in this case, the `field` of the resulting error is not
set to "manifest" (or any other value). Hence, add an additional output
of the manifest summary to the template. This is added near the end of
the form, as we in fact do not know whether the error is from the
manifest, or something else.

[1] https://lists.sr.ht/~sircmpwn/sr.ht-discuss/%3Ce6709b1c-8181-4182-9926-595a38b7bc57%40app.fastmail.com%3E
This commit is contained in:
Conrad Hoffmann 2024-01-04 11:43:38 +01:00 committed by Simon Ser
parent 265224537a
commit 224f51e8a9
3 changed files with 8 additions and 3 deletions

View File

@ -274,7 +274,9 @@ def submit_POST():
valid.error(str(ex), field="manifest")
return render_template("submit.html", **valid.kwargs)
job_id = submit_build(current_user, _manifest, note=note,
visibility=visibility)
visibility=visibility, valid=valid)
if not valid.ok:
return render_template("submit.html", **valid.kwargs)
return redirect("/~" + current_user.username + "/job/" + str(job_id))
@jobs.route("/cancel/<int:job_id>", methods=["POST"])

View File

@ -22,14 +22,16 @@ runner = Celery('builds', broker=builds_broker, config_source={
builds_queue_metrics_collector = RedisQueueCollector(builds_broker, "buildsrht_builds", "Number of builds currently in queue")
builds_submitted = Counter("buildsrht_builds_submitted", "Number of builds submitted")
def submit_build(user, manifest, note=None, tags=[], visibility=None):
def submit_build(user, manifest, note=None, tags=[], visibility=None, valid=None):
resp = exec_gql("builds.sr.ht", """
mutation SubmitBuild($manifest: String!, $tags: [String!], $note: String, $visibility: Visibility) {
submit(manifest: $manifest, tags: $tags, note: $note, visibility: $visibility) {
id
}
}
""", user=user, manifest=manifest, note=note, tags=tags, visibility=visibility)
""", user=user, manifest=manifest, note=note, tags=tags, visibility=visibility, valid=valid)
if valid and not valid.ok:
return None
return resp["submit"]["id"]
def requires_payment(user):

View File

@ -110,6 +110,7 @@
</label>
</div>
</fieldset>
{{valid.summary()}}
<div class="form-group">
<a
class="pull-right"