forked from openedx/edx-platform
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add observability for default auth classes (openedx#33003)
Added new authentication classes to be used in DEFAULT_AUTHENTICATION_CLASSES that include observability. This will enable us to see more about the endpoints using the defaults, to help us make choices about changes in the defaults. We make the DRF default of Session and Basic Authentication explicit by setting DEFAULT_AUTHENTICATION_CLASSES explicitly.
- Loading branch information
Showing
2 changed files
with
95 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
""" | ||
Default Authentication classes that are ONLY meant to be used by | ||
DEFAULT_AUTHENTICATION_CLASSES for observability purposes. | ||
""" | ||
from edx_django_utils.monitoring import set_custom_attribute | ||
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication | ||
from rest_framework.authentication import BasicAuthentication, SessionAuthentication | ||
|
||
|
||
class DefaultSessionAuthentication(SessionAuthentication): | ||
""" Default SessionAuthentication with observability """ | ||
|
||
def authenticate(self, request): | ||
# .. custom_attribute_name: using_default_auth_classes | ||
# .. custom_attribute_description: This custom attribute will always be | ||
# True (if not NULL), and signifies that a default authentication | ||
# class was used. This can be used to find endpoints using the | ||
# default authentication classes. | ||
set_custom_attribute('using_default_auth_classes', True) | ||
|
||
try: | ||
user_and_auth = super().authenticate(request) | ||
if user_and_auth: | ||
# .. custom_attribute_name: session_auth_result | ||
# .. custom_attribute_description: The result of session auth, represented | ||
# by: 'success', 'failure', or 'skipped'. | ||
set_custom_attribute('session_auth_result', 'success') | ||
else: | ||
set_custom_attribute('session_auth_result', 'skipped') | ||
return user_and_auth | ||
except Exception as exception: | ||
set_custom_attribute('session_auth_result', 'failure') | ||
raise | ||
|
||
|
||
class DefaultBasicAuthentication(BasicAuthentication): | ||
""" | ||
Default BasicAuthentication with observability | ||
Note that BasicAuthentication was a default because it was a DRF default. | ||
Observability will be used to determine if BasicAuthentication could | ||
instead be dropped as a default. | ||
""" | ||
|
||
def authenticate(self, request): | ||
# .. custom_attribute_name: using_default_auth_classes | ||
# .. custom_attribute_description: This custom attribute will always be | ||
# True (if not NULL), and signifies that a default authentication | ||
# class was used. This can be used to find endpoints using the | ||
# default authentication classes. | ||
set_custom_attribute('using_default_auth_classes', True) | ||
|
||
try: | ||
user_and_auth = super().authenticate(request) | ||
if user_and_auth: | ||
# .. custom_attribute_name: basic_auth_result | ||
# .. custom_attribute_description: The result of basic auth, represented | ||
# by: 'success', 'failure', or 'skipped'. | ||
set_custom_attribute('basic_auth_result', 'success') | ||
else: | ||
set_custom_attribute('basic_auth_result', 'skipped') | ||
return user_and_auth | ||
except Exception as exception: | ||
set_custom_attribute('basic_auth_result', 'failure') | ||
raise | ||
|
||
|
||
class DefaultJwtAuthentication(JwtAuthentication): | ||
""" | ||
Default JwtAuthentication with observability | ||
Note that the plan is to add JwtAuthentication as a default, but it | ||
is not yet used. This class will be used during the transition. | ||
""" | ||
|
||
def authenticate(self, request): | ||
# .. custom_attribute_name: using_default_auth_classes | ||
# .. custom_attribute_description: This custom attribute will always be | ||
# True (if not NULL), and signifies that a default authentication | ||
# class was used. This can be used to find endpoints using the | ||
# default authentication classes. | ||
set_custom_attribute('using_default_auth_classes', True) | ||
|
||
# Unlike the other DRF authentication classes, JwtAuthentication already | ||
# includes a jwt_auth_result custom attribute, so we do not need to | ||
# reimplement that observability in this class. | ||
return super().authenticate(request) |