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

feat: converting existing api to drf base api ( 1st api ). get_student_progress_url #35039

Merged
merged 2 commits into from
Jul 30, 2024

Conversation

awais786
Copy link
Contributor

@awais786 awais786 commented Jun 26, 2024

Issue for tracking.

Updating api code using DRF.

  1. Added standard authentication_classes
  2. Added permission_classes
  • Test this on local before merge.

Steps to verify:

  1. Log in to the local instance and open the instructor dashboard for course.
  2. Navigate to the section labeled "View a specific learner's grades and progress."
  3. Enter a user ID (e.g., admin) and click on "view progress page."
  4. If successful, you will be redirected to the progress page, such as this example.
  5. Repeat step 3 using a user email (e.g., [email protected]) and ensure it functions correctly as well.

Screenshot 2024-07-26 at 7 53 14 PM

@awais786 awais786 mentioned this pull request Jun 26, 2024
@@ -231,6 +233,28 @@ def wrapped(*args, **kwargs):
return decorator


def verify_course_permission(permission):
Copy link
Contributor Author

@awais786 awais786 Jun 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added new decorator because in existing one they are not passing self in constructor and its not compatabile with DRF apiview.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of making a new decorator, does it make more sense to make a custom permission class instead?

Copy link
Contributor

@feanil feanil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach mostly seems sound, I think I'd like to see if we can use standard DRF permissions management as much as possible instead of making our own decorators. What do you think?

@@ -1735,21 +1779,21 @@ def get_student_progress_url(request, course_id):
'progress_url': '/../...'
}
"""
course_id = CourseKey.from_string(course_id)
user = get_student_from_identifier(request.POST.get('unique_student_identifier'))
authentication_classes = (JwtAuthentication, BearerAuthentication, SessionAuthentication)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't need to define this, since the base authentication classes should be the correct ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -231,6 +233,28 @@ def wrapped(*args, **kwargs):
return decorator


def verify_course_permission(permission):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of making a new decorator, does it make more sense to make a custom permission class instead?

@@ -1,3 +1,4 @@

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary newline.

@awais786 awais786 changed the title feat: converting existing api to drf base api. feat: 1st. converting existing api to drf base api Jul 19, 2024
@awais786
Copy link
Contributor Author

@feanil you can review this again.

Copy link
Contributor

@feanil feanil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@awais786 that looks great to me!

@awais786 awais786 changed the title feat: 1st. converting existing api to drf base api feat: converting existing api to drf base api ( 1st api ) Jul 25, 2024
@awais786 awais786 marked this pull request as ready for review July 25, 2024 08:18
assert response.status_code == 200

expected_headers = {
'Allow': 'POST, OPTIONS', # drf view brings this key.
Copy link
Contributor Author

@awais786 awais786 Jul 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DRF returns this extra key Allow. DRF code reference here.

master branch returns this header response

{
'Content-Type': 'application/json', 
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Vary': 'Cookie, Accept-Language, origin',
'X-Frame-Options': 'DENY', 
'Content-Language': 'en', 
'Content-Length': '130'
}

current branch returns this

{
'Content-Type': 'application/json',
 'Allow': 'POST, OPTIONS', 
'Cache-Control': 'no-cache, no-store, must-revalidate', 
'Vary': 'Cookie, Accept-Language, origin', 
'X-Frame-Options': 'DENY', 
'Content-Language': 'en', 
'Content-Length': '121'
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

via postman these are response header.

Current branch -------------------------------------------vs-----------------------master branch

Screenshot 2024-07-28 at 2 07 11 AM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@feanil I have only found one difference between new vs old api. Old apis are not using any IsAuthenticated method. So in case of anonymous user they return 403 which comes from permissions verification but in new API drf will return 401.

This test on this branch returns 401 which is standard DRF status code.

    def test_get_student_progress_url_with_anonymous_user(self):
        """ Test that progress_url returns 403 without credentials. """
        self.client.logout()
        url = reverse('get_student_progress_url', kwargs={'course_id': str(self.course.id)})
        data = {'unique_student_identifier': self.students[0].email}
        response = self.client.post(url, data)
        assert response.status_code == 401

But on master branch its 403 and this test fails on master.

FAILED lms/djangoapps/instructor/tests/test_api.py::TestInstructorAPILevelsDataDump::test_get_student_progress_url_with_anonymous_user - assert 403 == 401

What do you think about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its good to go now.

Adding generic permission class. Added standard authentication classes.
Copy link
Contributor

@feanil feanil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@awais786 thanks for verifying with Postman! I think you can merge this at your leisure. Don't forget to mention it in the #cc-edx-platform slack channel.

@awais786 awais786 merged commit 39dd3c0 into master Jul 30, 2024
49 checks passed
@awais786 awais786 deleted the upgrading-api-1 branch July 30, 2024 08:18
@edx-pipeline-bot
Copy link
Contributor

2U Release Notice: This PR has been deployed to the edX staging environment in preparation for a release to production.

@edx-pipeline-bot
Copy link
Contributor

2U Release Notice: This PR has been deployed to the edX production environment.

@awais786 awais786 changed the title feat: converting existing api to drf base api ( 1st api ) feat: converting existing api to drf base api ( 1st api ). get_student_progress_url Aug 7, 2024
Agrendalath pushed a commit to open-craft/edx-platform that referenced this pull request Oct 22, 2024
Adding generic permission class. Added standard authentication classes.

(cherry picked from commit 39dd3c0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants