Token-authenticated API - #1121
Conversation
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Complexity | 2 medium |
🟢 Metrics 0 duplication
Metric Results Duplication 0
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
anthonygego
left a comment
There was a problem hiding this comment.
I did a first pass of things that shoud be addressed before going further.
fae1614 to
be20b09
Compare
|
I have addressed your current remarks. I have on my end other questions I would like to submit to you :
|
Yes, I think we can, even if the interface doesn't change. That will invalide any old usage of the API. No need to preserve any retrocompatibility, the thing was broken for years.
No JSON's probably good.
This is not something bad I guess. This practice can be found in other software. For instance, in Grist, the endpoint for creating a new document supports the two body schema, json and multipart : https://support.getgrist.com/api/#tag/docs/operation/importDoc The main requirement remains that the API is usable through standard librairies and methods.
I guess that's enough, indeed, as long as the symmetric algorithm is robust enough for a few years. |
ecf3c1e to
83d28ba
Compare
anthonygego
left a comment
There was a problem hiding this comment.
In summary, there are 3 things that need attention here:
- The way the user is propagated between parent and children API classes.
- Tokens and hashes sent in post forms.
- The way submission input are served.
a26321f to
9835953
Compare
83d28ba to
e3c10e4
Compare
…when calling endpoint
…xpiration with timezone
…into account differrent tasks previously did not differentiate tasks. The API would send the best result for each course, but not all tasks.
… instead of session
…(without session) + fixes + use json input for post
Transform into class methods + determine method directly inside verify_hash()
nrybowski
left a comment
There was a problem hiding this comment.
All in all, this PR requires some heavy lifting.
| flask_app.add_url_rule('/api/v0/auth_methods', | ||
| view_func=APIAuthMethods.as_view('apiauthmethods')) | ||
| flask_app.add_url_rule('/api/v0/authentication', | ||
| view_func=APIAuthentication.as_view('apiauthentication')) | ||
| flask_app.add_url_rule('/api/v0/courses', view_func=APICourses.as_view('apicourses.alias'), | ||
| flask_app.add_url_rule('/api/v1/courses', view_func=APICourses.as_view('apicourses.alias'), |
There was a problem hiding this comment.
Bumping the API version is a breaking change that is not even documented in the PR description. Is the bump mandatory? If yes, document it extensively and maybe add dummy endpoints for the old version. That is the kind of silent breaking change we really do not want in production.
There was a problem hiding this comment.
In this PR we change from authentication using the flask session to a token. Using the endpoints as before will inevitably fail. Bumping the version feels to me like a good way to indicate such a big change.
Although I will grant you this is missing some documentation. Plus, when calling an non-existent url, INGInious send back an HTML page. I will implement specific messages for "/api" and "/api/v0" to indicate an endpoint is not available or is obsolete.
Should I keep legacy endpoints rather than returning an error ?
I'm uncomfortable with such a breaking change, we should deploy dummy endpoints documenting the API changes for any scripts out there in the wild that may still use the old (and maybe broken) API. Maybe some 301 with a payload rather than just plain 404 out of nowhere. Such endpoints should only be available for a single release. |
|
Regarding to https://github.com/INGInious/INGInious/pull/1121/changes#r3880972260, we could generate a token per course upon admin user request, the authorized course id would be embedded within the JWT. Hence, we should not even load to course to ensure that the user is authorized to call the submission API for the specified course. |
Yes that was planned for #1041 and #1042 but the work was not finished by the end of the internship. I was in favor of both user (mainly for submission) and course (mainly for stats) tokens. This can in practice just be implemented as scopes, I don't know. The main requirements is that students should be able to generate tokens too without being manageable by course admins. But I really think that one feature must be implemented at a time in order to move on. |
e3c10e4 to
f1ec41f
Compare
|
I chose to hardcode the algorithm used for JWT. Allowing the choice for it could become messy due to different algorithms using different values (secrets, public keys, private keys). We would need to keep track of all the algorithms as well as all the different secrets and keys used to allow old tokens. On top of that, changing from a symmetric to an asymmetric algorithm without changing the secret could lead to an algorithm-confusion attack. |
|
Closing this PR. We will implement the submissions API and the generation and use of tokens through smaller PRs. Starting with #1170. |
This PR adds two endpoints to retrieve submissions using a token and a way for a user to generate it.
The token can be generated from the user preferences, in the page "API token". It is implemented using a JWT, allowing an automatic expiration.
The endpoints :
/api/v0/token/courses/<courseid>/submissions/api/v0/token/courses/<courseid>/<taskid>/submissionsBoth are POST endpoint due to the use of parameters passed through a JSON body. Passing them as arguments or parameters through the url could become cumbersome.
That body can contain :
Yet to bee implemented :