documentation

This commit is contained in:
lpm0073 2022-10-04 09:58:18 -05:00
parent d5cd19d490
commit 28bc231643

View File

@ -4,11 +4,11 @@ written by: Lawrence McDaniel
date: oct-2022 date: oct-2022
usage: Abstract class implementation of BaseOAuth2 to handle the field usage: subclass of BaseOAuth2 Third Party Authtencation client to
mapping and data converstions between the dict that WP Oauth handle the field mapping and data conversions between
returns versus the dict that Open edX actually needs. the dict that WP Oauth returns versus the dict that Open edX
actually needs.
""" """
from abc import abstractmethod
import json import json
from urllib.parse import urlencode from urllib.parse import urlencode
from urllib.request import urlopen from urllib.request import urlopen
@ -20,85 +20,90 @@ logger = getLogger(__name__)
VERBOSE_LOGGING = True VERBOSE_LOGGING = True
class StepwiseMathWPOAuth2(BaseOAuth2): class StepwiseMathWPOAuth2(BaseOAuth2):
""" """
WP OAuth authentication backend customized for Open edX WP OAuth authentication backend customized for Open edX.
see https://python-social-auth.readthedocs.io/en/latest/backends/implementation.html
""" """
# private utility function. not part of psa.
def _urlopen(self, url):
return urlopen(url).read().decode("utf-8")
# https://python-social-auth.readthedocs.io/en/latest/configuration/settings.html def __init__(self, strategy, redirect_uri=None):
super().__init__(strategy, redirect_uri)
@property if VERBOSE_LOGGING:
def ACCESS_TOKEN_METHOD(self): logger.info('StepwiseMathWPOAuth2() - ready.')
return 'POST'
# require redirect domain to match the original initiating domain.
@property
def SOCIAL_AUTH_SANITIZE_REDIRECTS(self):
return True
# This defines the backend name and identifies it during the auth process.
# The name is used in the URLs /login/<backend name> and /complete/<backend name>.
#
# This is the string value that will appear in the LMS Django Admin # This is the string value that will appear in the LMS Django Admin
# Third Party Authentication / Provider Configuration (OAuth) # Third Party Authentication / Provider Configuration (OAuth)
# setup page drop-down box titled, "Backend name:", just above # setup page drop-down box titled, "Backend name:", just above
# the "Client ID:" and "Client Secret:" fields. # the "Client ID:" and "Client Secret:" fields.
@property name = 'stepwisemath-oauth'
def name(self):
return 'stepwisemath-oauth'
# note: no slash at the end of the base url. Python Social Auth # note: no slash at the end of the base url. Python Social Auth
# might clean this up for you, but i'm not 100% certain of that. # might clean this up for you, but i'm not 100% certain of that.
@property BASE_URL = "https://stepwisemath.ai"
def BASE_URL(self):
return "https://stepwisemath.ai" # The default key name where the user identification field is defined, its
# used in the auth process when some basic user data is returned. This Id
# is stored in the UserSocialAuth.uid field and this, together with the
# UserSocialAuth.provider field, is used to uniquely identify a user association.
ID_KEY = 'id'
# Flags the backend to enforce email validation during the pipeline
# (if the corresponding pipeline social_core.pipeline.mail.mail_validation was enabled).
REQUIRES_EMAIL_VALIDATION = False
# Some providers give nothing about the user but some basic data like the
# user Id or an email address. The default scope attribute is used to
# specify a default value for the scope argument to request those extra bits.
DEFAULT_SCOPE = 'basic'
# Specifying the method type required to retrieve your access token if its
# not the default GET request.
ACCESS_TOKEN_METHOD = 'POST'
# require redirect domain to match the original initiating domain.
SOCIAL_AUTH_SANITIZE_REDIRECTS = True
# During the auth process some basic user data is returned by the provider
# or retrieved by the user_data() method which usually is used to call
# some API on the provider to retrieve it. This data will be stored in the
# UserSocialAuth.extra_data attribute, but to make it accessible under some
# common names on different providers, this attribute defines a list of
# tuples in the form (name, alias) where name is the key in the user data
# (which should be a dict instance) and alias is the name to store it on extra_data.
EXTRA_DATA = [
('id', 'id'),
('is_superuser', 'is_superuser'),
('is_staff', 'is_staff'),
('date_joined', 'date_joined'),
]
# the value of the scope separator is user-defined. Check the # the value of the scope separator is user-defined. Check the
# scopes field value for your oauth client in your wordpress host. # scopes field value for your oauth client in your wordpress host.
# the wp-oauth default value for scopes is 'basic' but can be # the wp-oauth default value for scopes is 'basic' but can be
# changed to a list. example 'basic, email, profile'. This # changed to a list. example 'basic, email, profile'. This
# list can be delimited with commas, spaces, whatever. # list can be delimited with commas, spaces, whatever.
@property SCOPE_SEPARATOR = " "
def SCOPE_SEPARATOR(self):
return ","
@property # private utility function. not part of psa.
def base_url(self) -> str: def _urlopen(self, url):
return self.BASE_URL return urlopen(url).read().decode("utf-8")
# override AUTHORIZATION_URL in parent class # override Python Social Auth default end points
# see https://wp-oauth.com/docs/general/endpoints/ # see https://wp-oauth.com/docs/general/endpoints/
@property @property
def AUTHORIZATION_URL(self) -> str: def AUTHORIZATION_URL(self) -> str:
return f"{self.base_url}/oauth/authorize" return f"{self.BASE_URL}/oauth/authorize"
# overrides ACCESS_TOKEN_URL from parent class
@property @property
# see https://wp-oauth.com/docs/general/endpoints/
def ACCESS_TOKEN_URL(self) -> str: def ACCESS_TOKEN_URL(self) -> str:
return f"{self.base_url}/oauth/token" return f"{self.BASE_URL}/oauth/token"
# overrides USER_QUERY from parent class
# see https://wp-oauth.com/docs/general/endpoints/
@property @property
def USER_QUERY(self) -> str: def USER_QUERY(self) -> str:
return f"{self.base_url}/oauth/me" return f"{self.BASE_URL}/oauth/me"
# overrides EXTRA_DATA from parent class
# see https://python-social-auth.readthedocs.io/en/latest/backends/implementation.html
@property
def EXTRA_DATA(self) -> list:
return [
('id', 'id'),
('username', 'username'),
('email', 'email'),
('first_name', 'first_name'),
('last_name', 'last_name'),
('fullname', 'fullname'),
('is_superuser', 'is_superuser'),
('is_staff', 'is_staff'),
('date_joined', 'date_joined'),
]
# implementation of get_user_details()
# see https://python-social-auth.readthedocs.io/en/latest/backends/implementation.html # see https://python-social-auth.readthedocs.io/en/latest/backends/implementation.html
def get_user_details(self, response) -> dict: def get_user_details(self, response) -> dict:
"""Return user details from the WP account""" """Return user details from the WP account"""
@ -169,6 +174,5 @@ class StepwiseMathWPOAuth2(BaseOAuth2):
user_details = self.get_user_details(response) user_details = self.get_user_details(response)
return user_details return user_details
except ValueError as e: except ValueError as e:
logger.error('user_data() did not work: {err}'.format(err=e)) logger.error('user_data() {err}'.format(err=e))
return None return None