instructure / canvas-lms

The open LMS by Instructure, Inc.
https://github.com/instructure/canvas-lms/wiki
GNU Affero General Public License v3.0
5.57k stars 2.48k forks source link

`GET /api/v1/users/:id` returns `...resource not found...` #2183

Closed murdock-grewar closed 1 year ago

murdock-grewar commented 1 year ago

Summary:

When I make a GET request to /api/v1/users/<user_id>, I receive the following response:

{'errors': [{'message': 'The specified resource does not exist.'}]}

I receive a different response when I try my own user id, and sometimes some other user ids. However, the returned response is not a User object as described by the API: https://canvas.instructure.com/doc/api/users.html#method.users.api_show It is missing most fields.

Steps to reproduce:

  1. Make GET request to /api/v1/users/<user_id> with a chosen <user_id>.

Expected behavior:

A response conforming to the API page description of a User object.

Actual behavior:

For most user ids, the response is {'errors': [{'message': 'The specified resource does not exist.'}]}. For other user ids, the response contains some of the fields of a User object but not all of them.

Additional notes:

Maybe my institution's Canvas instance is outdated? How do I check this with the API?

jstanley0 commented 1 year ago

This API endpoint intentionally returns status 404 if the user you're trying to view doesn't exist or you don't have permission to see them. We don't give you an indication of whether it's a valid user id for the same reason most websites won't tell you whether the username or password was incorrect when your login failed.

Regarding the missing fields--fields with no data may be omitted. If there are field(s) that are non-null, not subject to an include[] parameter, and missing from the result, feel free to reopen the issue and name them specifically.

murdock-grewar commented 1 year ago

@jstanley0 The users do exist, I do have permission to see them (I can get the user objects through other API calls), and there are fields missing that are non-null, not subject to an include[] parameter, and missing from the result.

jstanley0 commented 1 year ago

@murdock-grewar Some more specificity would help. What endpoint works for you where this one doesn't? The /api/v1/users/X endpoint requires manage_user_logins or read_roster permission on the account. It's possible you can see them through other contexts via other endpoints without these permissions (for example, if you have enrollments in the same course as them).

Also, if you could name the missing fields you expect to see, that'd be helpful.

murdock-grewar commented 1 year ago

@jstanley0 Hi, sorry I can't remember the specific API calls right now.

It's possible you can see them through other contexts via other endpoints without these permissions

It sounds like you're aware of the bug already. The API documentation located at https://canvas.instructure.com/doc/api/ says that if you make XYZ API call, then you'll receive XYZ response. And this isn't what's happening in practice. I don't know whether it's a documentation or API bug, but either way it is a bug.

Here is another instance where the API is not conforming to specification: The API call /courses/{course_id}/assignments/{assignment_id}/submissions is returning a paginated list of submissions and I'm able to parse them. However, those 'Submissions' do not conform to the Submission specification in the API (https://canvas.instructure.com/doc/api/submissions.html), which says that there should be an html_url key. Picking a random submission to a random assignment, here are the keys are present: ['id', 'body', 'url', 'grade', 'score', 'submitted_at', 'assignment_id', 'user_id', 'submission_type', 'workflow_state', 'grade_matches_current_submission', 'graded_at', 'grader_id', 'attempt', 'cached_due_date', 'excused', 'late_policy_status', 'points_deducted', 'grading_period_id', 'extra_attempts', 'posted_at', 'redo_request', 'late', 'missing', 'seconds_late', 'entered_grade', 'entered_score', 'preview_url', 'has_originality_report', 'turnitin_data']. No html_url is present. Also, a null value is returned for the url key. I can still see the preview_url, from which I can manually reconstruct the url by removing ?preview=..., so the missing data isn't an access control measure.