Skip to content

Commit

Permalink
Merge pull request #180 from CUCWD/feature.maple/ztraboo/feat-merge-p…
Browse files Browse the repository at this point in the history
…rior-release

fix(third-party-auth): Need to account for additional required demographic fields for BigCommerce provider for `maple` release.
  • Loading branch information
becdavid committed Jan 3, 2024
1 parent 48fd4cc commit efa113e
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.13 on 2022-08-23 22:37

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('bigcommerce_app', '0008_auto_20211021_2019'),
]

operations = [
migrations.AddField(
model_name='customer',
name='bc_country_code',
field=models.TextField(blank=True),
),
migrations.AddField(
model_name='customer',
name='bc_postal_code',
field=models.TextField(blank=True),
),
]
4 changes: 3 additions & 1 deletion lms/djangoapps/bigcommerce_app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ class Customer(models.Model):

def __str__(self):
return f"Id: {self.bc_id}\nEmail: {self.bc_email}\nGroup: {self.bc_group_id}\n" \
"Full Name: {self.bc_first_name} {self.bc_last_name}"
"Full Name: {self.bc_first_name} {self.bc_last_name}\n" \
"Postal Code: {self.bc_postal_code}\n" \
"Country Code: {self.bc.country_code}"

class Meta(object): # lint-amnesty, pylint: disable=missing-class-docstring
app_label = "bigcommerce_app"
Expand Down
29 changes: 29 additions & 0 deletions openedx/core/djangoapps/user_authn/views/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,35 @@ def create_account_with_params(request, params): # pylint: disable=too-many-sta
registration_fields.get('honor_code') != 'hidden'
)

# update this to reflect third-party authentication changes for `required`
# fields to `optional`.
if is_third_party_auth_enabled and pipeline.running(request):
running_pipeline = pipeline.get(request)
third_party_provider = provider.Registry.get_from_pipeline(running_pipeline)

# Check to see if BigCommerce backend is the current_provider.
is_bigcommerce_provider_backend = (
third_party_provider.backend_class.__base__.__name__ == 'BigCommerceCustomerBaseAuth'
)

# only do this for `BigCommerceCustomerBaseAuth` backends that have
# `Skip registration form` enabled.
if (is_bigcommerce_provider_backend and third_party_provider.skip_registration_form):

# make `year_of_birth` optional field.
for provider_field_name, provider_field_value in \
third_party_provider.get_setting("REGISTRATION_EXTRA_FIELDS").items():
# check to see if provider field exists in LMS environment. Only make updates if
# environment shows `required` field.
if (params[provider_field_name] == '' and provider_field_name in extra_fields):
# set this to `None` to avoid issue with
# AccountCreationForm.clean_year_of_birth() value error.
params.update({provider_field_name: None})

# Update field to be optional if required for third-party only.
if extra_fields[provider_field_name] == 'required':
extra_fields.update({provider_field_name: provider_field_value})

form = AccountCreationForm(
data=params,
extra_fields=extra_fields,
Expand Down
42 changes: 35 additions & 7 deletions openedx/core/djangoapps/user_authn/views/registration_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import copy
from importlib import import_module
import logging
import re

from django import forms
Expand Down Expand Up @@ -35,6 +36,8 @@
validate_password,
)

LOGGER = logging.getLogger(__name__)


class TrueCheckbox(widgets.CheckboxInput):
"""
Expand Down Expand Up @@ -279,7 +282,7 @@ def clean_year_of_birth(self):
"""
try:
year_str = self.cleaned_data["year_of_birth"]
return int(year_str) if year_str is not None else None
return int(year_str) if year_str is not None and len(year_str) > 0 else None
except ValueError:
return None

Expand Down Expand Up @@ -337,6 +340,8 @@ class RegistrationFormFactory:
"marketing_emails_opt_in",
]

CUSTOM_FORM_FIELDS = []

def _is_field_visible(self, field_name):
"""Check whether a field is visible based on Django settings. """
return self._extra_fields_setting.get(field_name) in ["required", "optional", "optional-exposed"]
Expand Down Expand Up @@ -410,14 +415,15 @@ def get_registration_form(self, request):
HttpResponse
"""
form_desc = FormDescription("post", self._get_registration_submit_url(request))
self._apply_third_party_auth_overrides(request, form_desc)

# Custom form fields can be added via the form set in settings.REGISTRATION_EXTENSION_FORM
custom_form = get_registration_extension_form()
if custom_form:
custom_form_field_names = [field_name for field_name, field in custom_form.fields.items()]
else:
custom_form_field_names = []
self.CUSTOM_FORM_FIELDS = [field_name for field_name, field in custom_form.fields.items()]

# apply third-party auth provider overrides.
# need to make sure this is done before adding third-party fields.
self._apply_third_party_auth_overrides(request, form_desc)

# Go through the fields in the fields order and add them if they are required or visible
for field_name in self.field_order:
Expand All @@ -428,7 +434,7 @@ def get_registration_form(self, request):
form_desc,
required=self._is_field_required(field_name)
)
elif field_name in custom_form_field_names:
elif field_name in self.CUSTOM_FORM_FIELDS:
for custom_field_name, field in custom_form.fields.items():
if field_name == custom_field_name:
restrictions = {}
Expand Down Expand Up @@ -1117,6 +1123,11 @@ def _apply_third_party_auth_overrides(self, request, form_desc):
current_provider = third_party_auth.provider.Registry.get_from_pipeline(running_pipeline)

if current_provider:
# Check to see if BigCommerce backend is the current_provider.
is_bigcommerce_provider_backend = (
current_provider.backend_class.__base__.__name__ == 'BigCommerceCustomerBaseAuth' # pylint: disable=line-too-long
)

# Override username / email / full name
field_overrides = current_provider.get_register_form_data(
running_pipeline.get('kwargs')
Expand All @@ -1132,12 +1143,29 @@ def _apply_third_party_auth_overrides(self, request, form_desc):
) or current_provider.sync_learner_profile_data
)

for field_name in self.DEFAULT_FIELDS + self.EXTRA_FIELDS:
for field_name in self.DEFAULT_FIELDS + self.EXTRA_FIELDS + self.CUSTOM_FORM_FIELDS:
if field_name in field_overrides:
form_desc.override_field_properties(
field_name, default=field_overrides[field_name]
)

LOGGER.warning("tpa fields %s - override (%s)", field_name, field_overrides[field_name])

# handle this field specifically since the third-party service
# may not pass it and this field is required.
# only do this for `BigCommerceCustomerBaseAuth` backends that have
# `Skip registration form` enabled.
if (is_bigcommerce_provider_backend and current_provider.skip_registration_form):
if (field_name in current_provider.get_setting("REGISTRATION_EXTRA_FIELDS") and
current_provider.skip_registration_form):

# override the field values from the provider.
form_desc.override_field_properties(
field_name,
default=field_overrides[field_name],
required=(True if current_provider.get_setting("REGISTRATION_EXTRA_FIELDS").get(field_name) == 'required' else False) # pylint: disable=line-too-long, simplifiable-if-expression
)

if (
field_name not in ['terms_of_service', 'honor_code'] and
field_overrides[field_name] and
Expand Down

0 comments on commit efa113e

Please sign in to comment.