def _third_party_auth_context(request, redirect_to):
"""Context for third party auth providers and the currently running pipeline.
Arguments:
request (HttpRequest): The request, used to determine if a pipeline
is currently running.
redirect_to: The URL to send the user to following successful
authentication.
Returns:
dict
"""
context = {
"currentProvider": None,
"providers": [],
"secondaryProviders": [],
"finishAuthUrl": None,
"errorMessage": None,
}
if third_party_auth.is_enabled():
for enabled in third_party_auth.provider.Registry.accepting_logins():
info = {
"id": enabled.provider_id,
"name": enabled.name,
"iconClass": enabled.icon_class,
"loginUrl": pipeline.get_login_url(
enabled.provider_id,
pipeline.AUTH_ENTRY_LOGIN,
redirect_url=redirect_to,
),
"registerUrl": pipeline.get_login_url(
enabled.provider_id,
pipeline.AUTH_ENTRY_REGISTER,
redirect_url=redirect_to,
),
}
context["providers" if not enabled.secondary else "secondaryProviders"].append(info)
running_pipeline = pipeline.get(request)
if running_pipeline is not None:
current_provider = third_party_auth.provider.Registry.get_from_pipeline(running_pipeline)
if current_provider is not None:
context["currentProvider"] = current_provider.name
context["finishAuthUrl"] = pipeline.get_complete_url(current_provider.backend_name)
if current_provider.skip_registration_form:
# As a reliable way of "skipping" the registration form, we just submit it automatically
context["autoSubmitRegForm"] = True
# Check for any error messages we may want to display:
for msg in messages.get_messages(request):
if msg.extra_tags.split()[0] == "social-auth":
# msg may or may not be translated. Try translating [again] in case we are able to:
context['errorMessage'] = _(unicode(msg)) # pylint: disable=translation-of-non-string
break
return context
def _apply_third_party_auth_overrides(request, form_desc):
"""Modify the login form if the user has authenticated with a third-party provider.
If a user has successfully authenticated with a third-party provider,
and an email is associated with it then we fill in the email field with readonly property.
Arguments:
request (HttpRequest): The request for the registration form, used
to determine if the user has successfully authenticated
with a third-party provider.
form_desc (FormDescription): The registration form description
"""
if third_party_auth.is_enabled():
running_pipeline = third_party_auth.pipeline.get(request)
if running_pipeline:
current_provider = third_party_auth.provider.Registry.get_from_pipeline(running_pipeline)
if current_provider and enterprise_customer_for_request(request):
pipeline_kwargs = running_pipeline.get('kwargs')
# Details about the user sent back from the provider.
details = pipeline_kwargs.get('details')
email = details.get('email', '')
# override the email field.
form_desc.override_field_properties(
"email",
default=email,
restrictions={"readonly": "readonly"} if email else {
"min_length": accounts.EMAIL_MIN_LENGTH,
"max_length": accounts.EMAIL_MAX_LENGTH,
}
)
def auth_pipeline_urls(auth_entry, redirect_url=None):
"""Retrieve URLs for each enabled third-party auth provider.
These URLs are used on the "sign up" and "sign in" buttons
on the login/registration forms to allow users to begin
authentication with a third-party provider.
Optionally, we can redirect the user to an arbitrary
url after auth completes successfully. We use this
to redirect the user to a page that required login,
or to send users to the payment flow when enrolling
in a course.
Args:
auth_entry (string): Either `pipeline.AUTH_ENTRY_LOGIN` or `pipeline.AUTH_ENTRY_REGISTER`
Keyword Args:
redirect_url (unicode): If provided, send users to this URL
after they successfully authenticate.
Returns:
dict mapping provider IDs to URLs
"""
if not third_party_auth.is_enabled():
return {}
return {
provider.provider_id: third_party_auth.pipeline.get_login_url(
provider.provider_id, auth_entry, redirect_url=redirect_url
) for provider in third_party_auth.provider.Registry.displayed_for_login()
}
def inactive_user_view(request):
"""
A newly or recently registered user has completed the social auth pipeline.
Their account is not yet activated, but we let them login since the third party auth
provider is trusted to vouch for them. See details in pipeline.py.
The reason this view exists is that if we don't define this as the
SOCIAL_AUTH_INACTIVE_USER_URL, inactive users will get sent to LOGIN_ERROR_URL, which we
don't want.
If the third_party_provider.skip_email_verification is set then the user is activated
and verification email is not sent
"""
# 'next' may be set to '/account/finish_auth/.../' if this user needs to be auto-enrolled
# in a course. Otherwise, just redirect them to the dashboard, which displays a message
# about activating their account.
user = request.user
profile = UserProfile.objects.get(user=user)
activated = user.is_active
# If the user is registering via 3rd party auth, track which provider they use
if third_party_auth.is_enabled() and pipeline.running(request):
running_pipeline = pipeline.get(request)
third_party_provider = provider.Registry.get_from_pipeline(running_pipeline)
if third_party_provider.skip_email_verification and not activated:
user.is_active = True
user.save()
activated = True
if not activated:
compose_and_send_activation_email(user, profile)
return redirect(request.GET.get('next', 'dashboard'))
def login_user(request):
"""
AJAX request to log in the user.
"""
third_party_auth_requested = third_party_auth.is_enabled() and pipeline.running(request)
trumped_by_first_party_auth = bool(request.POST.get('email')) or bool(request.POST.get('password'))
was_authenticated_third_party = False
try:
if third_party_auth_requested and not trumped_by_first_party_auth:
# The user has already authenticated via third-party auth and has not
# asked to do first party auth by supplying a username or password. We
# now want to put them through the same logging and cookie calculation
# logic as with first-party auth.
# This nested try is due to us only returning an HttpResponse in this
# one case vs. JsonResponse everywhere else.
try:
email_user = _do_third_party_auth(request)
was_authenticated_third_party = True
except AuthFailedError as e:
return HttpResponse(e.value, content_type="text/plain", status=403)
else:
email_user = _get_user_by_email(request)
_check_shib_redirect(email_user)
_check_excessive_login_attempts(email_user)
_check_forced_password_reset(email_user)
possibly_authenticated_user = email_user
if not was_authenticated_third_party:
possibly_authenticated_user = _authenticate_first_party(request, email_user)
if possibly_authenticated_user and password_policy_compliance.should_enforce_compliance_on_login():
# Important: This call must be made AFTER the user was successfully authenticated.
_enforce_password_policy_compliance(request, possibly_authenticated_user)
if possibly_authenticated_user is None or not possibly_authenticated_user.is_active:
_handle_failed_authentication(email_user)
_handle_successful_authentication_and_login(possibly_authenticated_user, request)
redirect_url = None # The AJAX method calling should know the default destination upon success
if was_authenticated_third_party:
running_pipeline = pipeline.get(request)
redirect_url = pipeline.get_complete_url(backend_name=running_pipeline['backend'])
response = JsonResponse({
'success': True,
'redirect_url': redirect_url,
})
# Ensure that the external marketing site can
# detect that the user is logged in.
return set_logged_in_cookies(request, response, possibly_authenticated_user)
except AuthFailedError as error:
log.exception(error.get_response())
return JsonResponse(error.get_response())
def _apply_third_party_auth_overrides(self, request, form_desc):
"""Modify the registration form if the user has authenticated with a third-party provider.
If a user has successfully authenticated with a third-party provider,
but does not yet have an account with EdX, we want to fill in
the registration form with any info that we get from the
provider.
This will also hide the password field, since we assign users a default
(random) password on the assumption that they will be using
third-party auth to log in.
Arguments:
request (HttpRequest): The request for the registration form, used
to determine if the user has successfully authenticated
with a third-party provider.
form_desc (FormDescription): The registration form description
"""
if third_party_auth.is_enabled():
running_pipeline = third_party_auth.pipeline.get(request)
if running_pipeline:
current_provider = third_party_auth.provider.Registry.get_from_pipeline(running_pipeline)
if current_provider:
# Override username / email / full name
field_overrides = current_provider.get_register_form_data(
running_pipeline.get('kwargs')
)
for field_name in self.DEFAULT_FIELDS:
if field_name in field_overrides:
form_desc.override_field_properties(
field_name, default=field_overrides[field_name]
)
# Hide the password field
form_desc.override_field_properties(
"password",
default="",
field_type="hidden",
required=False,
label="",
instructions="",
restrictions={}
)
form_desc.override_field_properties(
"show_password",
default=False,
field_type="hidden",
required=False,
label="",
instructions="",
restrictions={}
)
def _third_party_auth_context(request, redirect_to):
"""Context for third party auth providers and the currently running pipeline.
Arguments:
request (HttpRequest): The request, used to determine if a pipeline
is currently running.
redirect_to: The URL to send the user to following successful
authentication.
Returns:
dict
"""
context = {
"currentProvider": None,
"providers": [],
"finishAuthUrl": None,
"errorMessage": None,
}
if third_party_auth.is_enabled():
context["providers"] = [
{
"name": enabled.NAME,
"iconClass": enabled.ICON_CLASS,
"loginUrl": pipeline.get_login_url(
enabled.NAME,
pipeline.AUTH_ENTRY_LOGIN,
redirect_url=redirect_to,
),
"registerUrl": pipeline.get_login_url(
enabled.NAME,
pipeline.AUTH_ENTRY_REGISTER,
redirect_url=redirect_to,
),
}
for enabled in third_party_auth.provider.Registry.enabled()
]
running_pipeline = pipeline.get(request)
if running_pipeline is not None:
current_provider = third_party_auth.provider.Registry.get_by_backend_name(
running_pipeline.get('backend')
)
context["currentProvider"] = current_provider.NAME
context["finishAuthUrl"] = pipeline.get_complete_url(current_provider.BACKEND_CLASS.name)
# Check for any error messages we may want to display:
for msg in messages.get_messages(request):
if msg.extra_tags.split()[0] == "social-auth":
context['errorMessage'] = unicode(msg)
break
return context
开发者ID:JudyFox,项目名称:edXMOOC,代码行数:54,代码来源:views.py
示例8: _third_party_auth_context
def _third_party_auth_context(request):
"""Context for third party auth providers and the currently running pipeline.
Arguments:
request (HttpRequest): The request, used to determine if a pipeline
is currently running.
Returns:
dict
"""
context = {
"currentProvider": None,
"providers": []
}
course_id = request.GET.get("course_id")
email_opt_in = request.GET.get('email_opt_in')
login_urls = auth_pipeline_urls(
third_party_auth.pipeline.AUTH_ENTRY_LOGIN_2,
course_id=course_id,
email_opt_in=email_opt_in
)
register_urls = auth_pipeline_urls(
third_party_auth.pipeline.AUTH_ENTRY_REGISTER_2,
course_id=course_id,
email_opt_in=email_opt_in
)
if third_party_auth.is_enabled():
context["providers"] = [
{
"name": enabled.NAME,
"iconClass": enabled.ICON_CLASS,
"loginUrl": login_urls[enabled.NAME],
"registerUrl": register_urls[enabled.NAME]
}
for enabled in third_party_auth.provider.Registry.enabled()
]
running_pipeline = third_party_auth.pipeline.get(request)
if running_pipeline is not None:
current_provider = third_party_auth.provider.Registry.get_by_backend_name(
running_pipeline.get('backend')
)
context["currentProvider"] = current_provider.NAME
return context
def create_account(request, post_override=None):
"""
Deprecated. Use RegistrationView instead.
JSON call to create new edX account.
Used by form in signup_modal.html, which is included into header.html
"""
# Check if ALLOW_PUBLIC_ACCOUNT_CREATION flag turned off to restrict user account creation
if not configuration_helpers.get_value(
'ALLOW_PUBLIC_ACCOUNT_CREATION',
settings.FEATURES.get('ALLOW_PUBLIC_ACCOUNT_CREATION', True)
):
return HttpResponseForbidden(_("Account creation not allowed."))
if waffle().is_enabled(PREVENT_AUTH_USER_WRITES):
return HttpResponseForbidden(SYSTEM_MAINTENANCE_MSG)
warnings.warn("Please use RegistrationView instead.", DeprecationWarning)
try:
user = create_account_with_params(request, post_override or request.POST)
except AccountValidationError as exc:
return JsonResponse({'success': False, 'value': text_type(exc), 'field': exc.field}, status=400)
except ValidationError as exc:
field, error_list = next(iteritems(exc.message_dict))
return JsonResponse(
{
"success": False,
"field": field,
"value": ' '.join(error_list),
},
status=400
)
redirect_url = None # The AJAX method calling should know the default destination upon success
# Resume the third-party-auth pipeline if necessary.
if third_party_auth.is_enabled() and pipeline.running(request):
running_pipeline = pipeline.get(request)
redirect_url = pipeline.get_complete_url(running_pipeline['backend'])
response = JsonResponse({
'success': True,
'redirect_url': redirect_url,
})
set_logged_in_cookies(request, response, user)
return response
def register_user(request, extra_context=None):
"""
Deprecated. To be replaced by :class:`user_authn.views.login_form.login_and_registration_form`.
"""
# Determine the URL to redirect to following login:
redirect_to = get_next_url_for_login_page(request)
if request.user.is_authenticated:
return redirect(redirect_to)
external_auth_response = external_auth_register(request)
if external_auth_response is not None:
return external_auth_response
context = {
'login_redirect_url': redirect_to, # This gets added to the query string of the "Sign In" button in the header
'email': '',
'name': '',
'running_pipeline': None,
'pipeline_urls': auth_pipeline_urls(pipeline.AUTH_ENTRY_REGISTER, redirect_url=redirect_to),
'platform_name': configuration_helpers.get_value(
'platform_name',
settings.PLATFORM_NAME
),
'selected_provider': '',
'username': '',
}
if extra_context is not None:
context.update(extra_context)
if context.get("extauth_domain", '').startswith(settings.SHIBBOLETH_DOMAIN_PREFIX):
return render_to_response('register-shib.html', context)
# If third-party auth is enabled, prepopulate the form with data from the
# selected provider.
if third_party_auth.is_enabled() and pipeline.running(request):
running_pipeline = pipeline.get(request)
current_provider = provider.Registry.get_from_pipeline(running_pipeline)
if current_provider is not None:
overrides = current_provider.get_register_form_data(running_pipeline.get('kwargs'))
overrides['running_pipeline'] = running_pipeline
overrides['selected_provider'] = current_provider.name
context.update(overrides)
return render_to_response('register.html', context)
def _get_profile(request):
"""Retrieve the user's profile information, including an HTML form
that students can use to update the information.
Args:
request (HttpRequest)
Returns:
HttpResponse
"""
user = request.user
context = {
'disable_courseware_js': True
}
if third_party_auth.is_enabled():
context['provider_user_states'] = third_party_auth.pipeline.get_provider_user_states(user)
return render_to_response('student_profile/index.html', context)
def login(request):
"""Allow external auth to intercept and handle a login request.
Arguments:
request (Request): A request for the login page.
Returns:
Response or None
"""
# Default to a `None` response, indicating that external auth
# is not handling the request.
response = None
if settings.IONISX_AUTH and third_party_auth.is_enabled():
# IONISx Authentication is enabled so we directly redirect
# to IONISx portal
redirect_to = request.GET.get('next')
redirect_uri = get_login_url('oa2-portal-oauth2', AUTH_ENTRY_LOGIN, redirect_to)
response = redirect(redirect_uri)
elif settings.FEATURES['AUTH_USE_CERTIFICATES'] and external_auth.views.ssl_get_cert_from_request(request):
# SSL login doesn't require a view, so redirect
# branding and allow that to process the login if it
# is enabled and the header is in the request.
response = external_auth.views.redirect_with_get('root', request.GET)
elif settings.FEATURES.get('AUTH_USE_CAS'):
# If CAS is enabled, redirect auth handling to there
response = redirect(reverse('cas-login'))
elif settings.FEATURES.get('AUTH_USE_SHIB'):
redirect_to = request.GET.get('next')
if redirect_to:
course_id = _parse_course_id_from_string(redirect_to)
if course_id and _get_course_enrollment_domain(course_id):
response = external_auth.views.course_specific_login(request, course_id.to_deprecated_string())
return response
def register(request):
"""Allow external auth to intercept and handle a registration request.
Arguments:
request (Request): A request for the registration page.
Returns:
Response or None
"""
response = None
if settings.IONISX_AUTH and third_party_auth.is_enabled():
# IONISx Authentication is enabled so we directly redirect
# to IONISx portal
redirect_to = request.GET.get('next')
redirect_uri = get_login_url('oa2-portal-oauth2', AUTH_ENTRY_REGISTER, redirect_to)
response = redirect(redirect_uri)
elif settings.FEATURES.get('AUTH_USE_CERTIFICATES_IMMEDIATE_SIGNUP'):
# Redirect to branding to process their certificate if SSL is enabled
# and registration is disabled.
response = external_auth.views.redirect_with_get('root', request.GET)
return response
def create_account_with_params(request, params):
"""
Given a request and a dict of parameters (which may or may not have come
from the request), create an account for the requesting user, including
creating a comments service user object and sending an activation email.
This also takes external/third-party auth into account, updates that as
necessary, and authenticates the user for the request's session.
Does not return anything.
Raises AccountValidationError if an account with the username or email
specified by params already exists, or ValidationError if any of the given
parameters is invalid for any other reason.
Issues with this code:
* It is non-transactional except where explicitly wrapped in atomic to
alleviate deadlocks and improve performance. This means failures at
different places in registration can leave users in inconsistent
states.
* Third-party auth passwords are not verified. There is a comment that
they are unused, but it would be helpful to have a sanity check that
they are sane.
* The user-facing text is rather unfriendly (e.g. "Username must be a
minimum of two characters long" rather than "Please use a username of
at least two characters").
* Duplicate email raises a ValidationError (rather than the expected
AccountValidationError). Duplicate username returns an inconsistent
user message (i.e. "An account with the Public Username '{username}'
already exists." rather than "It looks like {username} belongs to an
existing account. Try again with a different username.") The two checks
occur at different places in the code; as a result, registering with
both a duplicate username and email raises only a ValidationError for
email only.
"""
# Copy params so we can modify it; we can't just do dict(params) because if
# params is request.POST, that results in a dict containing lists of values
params = dict(params.items())
# allow to define custom set of required/optional/hidden fields via configuration
extra_fields = configuration_helpers.get_value(
'REGISTRATION_EXTRA_FIELDS',
getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
)
# registration via third party (Google, Facebook) using mobile application
# doesn't use social auth pipeline (no redirect uri(s) etc involved).
# In this case all related info (required for account linking)
# is sent in params.
# `third_party_auth_credentials_in_api` essentially means 'request
# is made from mobile application'
third_party_auth_credentials_in_api = 'provider' in params
is_third_party_auth_enabled = third_party_auth.is_enabled()
if is_third_party_auth_enabled and (pipeline.running(request) or third_party_auth_credentials_in_api):
params["password"] = generate_password()
# in case user is registering via third party (Google, Facebook) and pipeline has expired, show appropriate
# error message
if is_third_party_auth_enabled and ('social_auth_provider' in params and not pipeline.running(request)):
raise ValidationError(
{'session_expired': [
_(u"Registration using {provider} has timed out.").format(
provider=params.get('social_auth_provider'))
]}
)
do_external_auth, eamap = pre_account_creation_external_auth(request, params)
extended_profile_fields = configuration_helpers.get_value('extended_profile_fields', [])
# Can't have terms of service for certain SHIB users, like at Stanford
registration_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
tos_required = (
registration_fields.get('terms_of_service') != 'hidden' or
registration_fields.get('honor_code') != 'hidden'
) and (
not settings.FEATURES.get("AUTH_USE_SHIB") or
not settings.FEATURES.get("SHIB_DISABLE_TOS") or
not do_external_auth or
not eamap.external_domain.startswith(settings.SHIBBOLETH_DOMAIN_PREFIX)
)
form = AccountCreationForm(
data=params,
extra_fields=extra_fields,
extended_profile_fields=extended_profile_fields,
do_third_party_auth=do_external_auth,
tos_required=tos_required,
)
custom_form = get_registration_extension_form(data=params)
# Perform operations within a transaction that are critical to account creation
with outer_atomic(read_committed=True):
# first, create the account
(user, profile, registration) = do_create_account(form, custom_form)
third_party_provider, running_pipeline = _link_user_to_third_party_provider(
is_third_party_auth_enabled, third_party_auth_credentials_in_api, user, request, params,
)
new_user = authenticate_new_user(request, user.username, params['password'])
django_login(request, new_user)
#.........这里部分代码省略.........
def account_settings_context(request):
""" Context for the account settings page.
Args:
request: The request object.
Returns:
dict
"""
user = request.user
year_of_birth_options = [(unicode(year), unicode(year)) for year in UserProfile.VALID_YEARS]
context = {
"auth": {},
"duplicate_provider": None,
"fields": {
"country": {"options": list(countries)},
"gender": {
"options": [
(choice[0], _(choice[1])) for choice in UserProfile.GENDER_CHOICES
] # pylint: disable=translation-of-non-string
},
"language": {"options": released_languages()},
"level_of_education": {
"options": [
(choice[0], _(choice[1])) for choice in UserProfile.LEVEL_OF_EDUCATION_CHOICES
] # pylint: disable=translation-of-non-string
},
"password": {"url": reverse("password_reset")},
"year_of_birth": {"options": year_of_birth_options},
"preferred_language": {"options": settings.ALL_LANGUAGES},
},
"platform_name": settings.PLATFORM_NAME,
"user_accounts_api_url": reverse("accounts_api", kwargs={"username": user.username}),
"user_preferences_api_url": reverse("preferences_api", kwargs={"username": user.username}),
"disable_courseware_js": True,
}
if third_party_auth.is_enabled():
# If the account on the third party provider is already connected with another edX account,
# we display a message to the user.
context["duplicate_provider"] = pipeline.get_duplicate_provider(messages.get_messages(request))
auth_states = pipeline.get_provider_user_states(user)
context["auth"]["providers"] = [
{
"id": state.provider.provider_id,
"name": state.provider.name, # The name of the provider e.g. Facebook
"connected": state.has_account, # Whether the user's edX account is connected with the provider.
# If the user is not connected, they should be directed to this page to authenticate
# with the particular provider, as long as the provider supports initiating a login.
"connect_url": pipeline.get_login_url(
state.provider.provider_id,
pipeline.AUTH_ENTRY_ACCOUNT_SETTINGS,
# The url the user should be directed to after the auth process has completed.
redirect_url=reverse("account_settings"),
),
"accepts_logins": state.provider.accepts_logins,
# If the user is connected, sending a POST request to this url removes the connection
# information for this provider from their edX account.
"disconnect_url": pipeline.get_disconnect_url(state.provider.provider_id, state.association_id),
}
for state in auth_states
]
return context
def account_settings_context(request):
""" Context for the account settings page.
Args:
request: The request object.
Returns:
dict
"""
user = request.user
year_of_birth_options = [(unicode(year), unicode(year)) for year in UserProfile.VALID_YEARS]
try:
user_orders = get_user_orders(user)
except: # pylint: disable=bare-except
log.exception('Error fetching order history from Otto.')
# Return empty order list as account settings page expect a list and
# it will be broken if exception raised
user_orders = []
beta_language = {}
dark_lang_config = DarkLangConfig.current()
if dark_lang_config.enable_beta_languages:
user_preferences = get_user_preferences(user)
pref_language = user_preferences.get('pref-lang')
if pref_language in dark_lang_config.beta_languages_list:
beta_language['code'] = pref_language
beta_language['name'] = settings.LANGUAGE_DICT.get(pref_language)
context = {
'auth': {},
'duplicate_provider': None,
'nav_hidden': True,
'fields': {
'country': {
'options': list(countries),
}, 'gender': {
'options': [(choice[0], _(choice[1])) for choice in UserProfile.GENDER_CHOICES],
}, 'language': {
'options': released_languages(),
}, 'level_of_education': {
'options': [(choice[0], _(choice[1])) for choice in UserProfile.LEVEL_OF_EDUCATION_CHOICES],
}, 'password': {
'url': reverse('password_reset'),
}, 'year_of_birth': {
'options': year_of_birth_options,
}, 'preferred_language': {
'options': all_languages(),
}, 'time_zone': {
'options': TIME_ZONE_CHOICES,
}
},
'platform_name': configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME),
'password_reset_support_link': configuration_helpers.get_value(
'PASSWORD_RESET_SUPPORT_LINK', settings.PASSWORD_RESET_SUPPORT_LINK
) or settings.SUPPORT_SITE_LINK,
'user_accounts_api_url': reverse("accounts_api", kwargs={'username': user.username}),
'user_preferences_api_url': reverse('preferences_api', kwargs={'username': user.username}),
'disable_courseware_js': True,
'show_program_listing': ProgramsApiConfig.is_enabled(),
'show_dashboard_tabs': True,
'order_history': user_orders,
'disable_order_history_tab': should_redirect_to_order_history_microfrontend(),
'enable_account_deletion': configuration_helpers.get_value(
'ENABLE_ACCOUNT_DELETION', settings.FEATURES.get('ENABLE_ACCOUNT_DELETION', False)
),
'extended_profile_fields': _get_extended_profile_fields(),
'beta_language': beta_language,
}
enterprise_customer = get_enterprise_customer_for_learner(user=request.user)
update_account_settings_context_for_enterprise(context, enterprise_customer)
if third_party_auth.is_enabled():
# If the account on the third party provider is already connected with another edX account,
# we display a message to the user.
context['duplicate_provider'] = pipeline.get_duplicate_provider(messages.get_messages(request))
auth_states = pipeline.get_provider_user_states(user)
context['auth']['providers'] = [{
'id': state.provider.provider_id,
'name': state.provider.name, # The name of the provider e.g. Facebook
'connected': state.has_account, # Whether the user's edX account is connected with the provider.
# If the user is not connected, they should be directed to this page to authenticate
# with the particular provider, as long as the provider supports initiating a login.
'connect_url': pipeline.get_login_url(
state.provider.provider_id,
pipeline.AUTH_ENTRY_ACCOUNT_SETTINGS,
# The url the user should be directed to after the auth process has completed.
redirect_url=reverse('account_settings'),
),
'accepts_logins': state.provider.accepts_logins,
# If the user is connected, sending a POST request to this url removes the connection
# information for this provider from their edX account.
'disconnect_url': pipeline.get_disconnect_url(state.provider.provider_id, state.association_id),
# We only want to include providers if they are either currently available to be logged
# in with, or if the user is already authenticated with them.
} for state in auth_states if state.provider.display_for_login or state.has_account]
#.........这里部分代码省略.........
def _third_party_auth_context(request, redirect_to, tpa_hint=None):
"""Context for third party auth providers and the currently running pipeline.
Arguments:
request (HttpRequest): The request, used to determine if a pipeline
is currently running.
redirect_to: The URL to send the user to following successful
authentication.
tpa_hint (string): An override flag that will return a matching provider
as long as its configuration has been enabled
Returns:
dict
"""
context = {
"currentProvider": None,
"providers": [],
"secondaryProviders": [],
"finishAuthUrl": None,
"errorMessage": None,
"registerFormSubmitButtonText": _("Create Account"),
"syncLearnerProfileData": False,
"pipeline_user_details": {}
}
if third_party_auth.is_enabled():
for enabled in third_party_auth.provider.Registry.displayed_for_login(tpa_hint=tpa_hint):
info = {
"id": enabled.provider_id,
"name": enabled.name,
"iconClass": enabled.icon_class or None,
"iconImage": enabled.icon_image.url if enabled.icon_image else None,
"loginUrl": pipeline.get_login_url(
enabled.provider_id,
pipeline.AUTH_ENTRY_LOGIN,
redirect_url=redirect_to,
),
"registerUrl": pipeline.get_login_url(
enabled.provider_id,
pipeline.AUTH_ENTRY_REGISTER,
redirect_url=redirect_to,
),
}
context["providers" if not enabled.secondary else "secondaryProviders"].append(info)
running_pipeline = pipeline.get(request)
if running_pipeline is not None:
current_provider = third_party_auth.provider.Registry.get_from_pipeline(running_pipeline)
user_details = running_pipeline['kwargs']['details']
if user_details:
context['pipeline_user_details'] = user_details
if current_provider is not None:
context["currentProvider"] = current_provider.name
context["finishAuthUrl"] = pipeline.get_complete_url(current_provider.backend_name)
context["syncLearnerProfileData"] = current_provider.sync_learner_profile_data
if current_provider.skip_registration_form:
# As a reliable way of "skipping" the registration form, we just submit it automatically
context["autoSubmitRegForm"] = True
# Check for any error messages we may want to display:
for msg in messages.get_messages(request):
if msg.extra_tags.split()[0] == "social-auth":
# msg may or may not be translated. Try translating [again] in case we are able to:
context['errorMessage'] = _(unicode(msg))
break
return context
请发表评论