Files
edx-platform/common/djangoapps/third_party_auth/samlproviderdata/views.py
Binod Pant 167d8f278f ENT-3007 : round 2 API endpoints for samlproviderconfig and samlproviderdata (#24456)
* ENT-3007 auth/saml/v0/saml/providerdata and auth/saml/v0/saml/providerconfig endpoints

Move code to subfolder for samlproviderconfig

extra comma

undo accidental remove of import

GET works for a single config now

Use ModelViewSet to get all CRUD method. Test still fails

Add auth/saml/v0/providerdata endpoints

fixup reverse and test issue, remove leading caret

just triggering run, why is it failing in CI?

pycodelint fixes

Skip auth tests unless feature is on

Tests for post/put for samlproviderdata

move urls to their own folders

api tests for post samlprovierconfig

create 1 providerconfig test case

lint fixes

lint

lint

cleanup code local urls /samlproviderconfig works

note needed right now

Fix import errors

lint

unused import

wip: first attempt at rbac auth and jwt cookie in test

round 2 with enterprise uuid as url param for samlproviderconfig

improve tests, still dont pass

fix test by using system role, wip other test

fix create test

add get/post tests for providerdata

isort fixes

string lint fix

Cleanup based on feedback round1

move utils to tests package

Move util fn to openedx.feature area

lint

ENT-3007 : Round 2 of work on auth/saml/v0/providerconfig and auth/saml/v0/providerdata endpoints

* Fix test issue use string uuid for permission obj

* snake case changes provider_config

* snake case

* provider_data, tests and lint

* patch and delete tests for providerdata

* snake_case

* snake_case

* snake_case

* make patch test stronger

* 404 if invalid uuid for get param

* common util for validate uuid4

* unused import

* lint fixes for pycodestyle

* 400 when uuid is missing

* 400 instead of 404 for missing uuid

* spell fix

* update docstring for api usage

* docstring clarify
2020-07-15 10:34:26 -04:00

79 lines
3.4 KiB
Python

"""
Viewset for auth/saml/v0/samlproviderdata
"""
from django.shortcuts import get_object_or_404
from edx_rbac.mixins import PermissionRequiredMixin
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from rest_framework import permissions, viewsets
from rest_framework.authentication import SessionAuthentication
from rest_framework.exceptions import ParseError
from enterprise.models import EnterpriseCustomerIdentityProvider
from third_party_auth.utils import validate_uuid4_string
from ..models import SAMLProviderConfig, SAMLProviderData
from .serializers import SAMLProviderDataSerializer
class SAMLProviderDataMixin(object):
authentication_classes = [JwtAuthentication, SessionAuthentication]
permission_classes = [permissions.IsAuthenticated]
serializer_class = SAMLProviderDataSerializer
class SAMLProviderDataViewSet(PermissionRequiredMixin, SAMLProviderDataMixin, viewsets.ModelViewSet):
"""
A View to handle SAMLProviderData CRUD.
Uses the edx-rbac mixin PermissionRequiredMixin to apply enterprise authorization
Usage:
NOTE: Only the GET request requires a request parameter, otherwise pass the uuid as part
of the post body
GET /auth/saml/v0/provider_data/?enterprise-id=uuid
POST /auth/saml/v0/provider_data/ -d postData (must contain 'enterprise_customer_uuid')
DELETE /auth/saml/v0/provider_data/:pk -d postData (must contain 'enterprise_customer_uuid')
PATCH /auth/saml/v0/provider_data/:pk -d postData (must contain 'enterprise_customer_uuid')
"""
permission_required = 'enterprise.can_access_admin_dashboard'
def get_queryset(self):
"""
Find and return the matching providerid for the given enterprise uuid
Note: There is no direct association between samlproviderdata and enterprisecustomer.
So we make that association in code via samlproviderdata > samlproviderconfig ( via entity_id )
then, we fetch enterprisecustomer via samlproviderconfig > enterprisecustomer ( via association table )
"""
if self.requested_enterprise_uuid is None:
raise ParseError('Required enterprise_customer_uuid is missing')
enterprise_customer_idp = get_object_or_404(
EnterpriseCustomerIdentityProvider,
enterprise_customer__uuid=self.requested_enterprise_uuid
)
saml_provider = SAMLProviderConfig.objects.get(pk=enterprise_customer_idp.provider_id)
return SAMLProviderData.objects.filter(entity_id=saml_provider.entity_id)
@property
def requested_enterprise_uuid(self):
"""
The enterprise customer uuid from request params or post body
"""
if self.request.method in ('POST', 'PATCH', 'DELETE'):
uuid_str = self.request.POST.get('enterprise_customer_uuid')
if uuid_str is None:
raise ParseError('Required enterprise_customer_uuid is missing')
return uuid_str
else:
uuid_str = self.request.query_params.get('enterprise_customer_uuid')
if validate_uuid4_string(uuid_str) is False:
raise ParseError('Invalid UUID enterprise_customer_id')
return uuid_str
def get_permission_object(self):
"""
Retrieve an EnterpriseCustomer to do auth against
"""
return self.requested_enterprise_uuid