Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
3b9550bd
Commit
3b9550bd
authored
Nov 22, 2017
by
Saleem Latif
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Disable linking of personal accounts to enterprise customers via SSO
parent
773b622e
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
116 additions
and
41 deletions
+116
-41
common/djangoapps/third_party_auth/pipeline.py
+8
-0
lms/djangoapps/student_account/test/test_views.py
+2
-0
lms/djangoapps/student_account/views.py
+27
-2
lms/static/js/student_account/views/AccessView.js
+5
-1
lms/static/js/student_account/views/LoginView.js
+3
-1
lms/static/js/student_account/views/RegisterView.js
+4
-0
lms/static/sass/views/_login-register.scss
+18
-2
lms/templates/student_account/form_field.underscore
+2
-1
lms/templates/student_account/register.underscore
+8
-4
openedx/core/djangoapps/user_api/api.py
+36
-27
openedx/core/djangoapps/user_api/helpers.py
+3
-3
No files found.
common/djangoapps/third_party_auth/pipeline.py
View file @
3b9550bd
...
@@ -567,6 +567,14 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia
...
@@ -567,6 +567,14 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia
(
current_provider
.
skip_email_verification
or
current_provider
.
send_to_registration_first
))
(
current_provider
.
skip_email_verification
or
current_provider
.
send_to_registration_first
))
if
not
user
:
if
not
user
:
details
=
kwargs
.
get
(
'details'
,
{})
if
'email'
in
details
or
'username'
in
details
:
# pylint: disable=invalid-name
qs
=
{
'email'
:
details
[
'email'
]}
if
details
.
get
(
'email'
)
else
\
{
'username'
:
details
.
get
(
'username'
)}
if
User
.
objects
.
filter
(
**
qs
)
.
exists
():
return
dispatch_to_login
()
if
is_api
(
auth_entry
):
if
is_api
(
auth_entry
):
return
HttpResponseBadRequest
()
return
HttpResponseBadRequest
()
elif
auth_entry
==
AUTH_ENTRY_LOGIN
:
elif
auth_entry
==
AUTH_ENTRY_LOGIN
:
...
...
lms/djangoapps/student_account/test/test_views.py
View file @
3b9550bd
...
@@ -640,6 +640,8 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
...
@@ -640,6 +640,8 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
"finishAuthUrl"
:
finish_auth_url
,
"finishAuthUrl"
:
finish_auth_url
,
"errorMessage"
:
None
,
"errorMessage"
:
None
,
"registerFormSubmitButtonText"
:
"Create Account"
,
"registerFormSubmitButtonText"
:
"Create Account"
,
"hideSignInLink"
:
False
,
"syncLearnerProfileData"
:
False
,
}
}
if
expected_ec
is
not
None
:
if
expected_ec
is
not
None
:
# If we set an EnterpriseCustomer, third-party auth providers ought to be hidden.
# If we set an EnterpriseCustomer, third-party auth providers ought to be hidden.
...
...
lms/djangoapps/student_account/views.py
View file @
3b9550bd
...
@@ -124,6 +124,22 @@ def login_and_registration_form(request, initial_mode="login"):
...
@@ -124,6 +124,22 @@ def login_and_registration_form(request, initial_mode="login"):
}
for
message
in
messages
.
get_messages
(
request
)
if
'account-activation'
in
message
.
tags
}
for
message
in
messages
.
get_messages
(
request
)
if
'account-activation'
in
message
.
tags
]
]
account_creation_allowed
=
configuration_helpers
.
get_value
(
'ALLOW_PUBLIC_ACCOUNT_CREATION'
,
settings
.
FEATURES
.
get
(
'ALLOW_PUBLIC_ACCOUNT_CREATION'
,
True
)
)
# add user details from running pipeline
pipeline_user_details
=
{}
running_pipeline
=
pipeline
.
get
(
request
)
if
running_pipeline
:
pipeline_user_details
=
running_pipeline
[
'kwargs'
][
'details'
]
if
'email'
in
pipeline_user_details
or
'username'
in
pipeline_user_details
:
# pylint: disable=invalid-name
qs
=
{
'email'
:
pipeline_user_details
[
'email'
]}
if
pipeline_user_details
.
get
(
'email'
)
else
\
{
'username'
:
pipeline_user_details
.
get
(
'username'
)}
if
User
.
objects
.
filter
(
**
qs
)
.
exists
():
account_creation_allowed
=
False
# Otherwise, render the combined login/registration page
# Otherwise, render the combined login/registration page
context
=
{
context
=
{
'data'
:
{
'data'
:
{
...
@@ -145,8 +161,8 @@ def login_and_registration_form(request, initial_mode="login"):
...
@@ -145,8 +161,8 @@ def login_and_registration_form(request, initial_mode="login"):
'login_form_desc'
:
json
.
loads
(
form_descriptions
[
'login'
]),
'login_form_desc'
:
json
.
loads
(
form_descriptions
[
'login'
]),
'registration_form_desc'
:
json
.
loads
(
form_descriptions
[
'registration'
]),
'registration_form_desc'
:
json
.
loads
(
form_descriptions
[
'registration'
]),
'password_reset_form_desc'
:
json
.
loads
(
form_descriptions
[
'password_reset'
]),
'password_reset_form_desc'
:
json
.
loads
(
form_descriptions
[
'password_reset'
]),
'account_creation_allowed'
:
configuration_helpers
.
get_value
(
'account_creation_allowed'
:
account_creation_allowed
,
'ALLOW_PUBLIC_ACCOUNT_CREATION'
,
settings
.
FEATURES
.
get
(
'ALLOW_PUBLIC_ACCOUNT_CREATION'
,
True
))
'pipeline_user_details'
:
pipeline_user_details
},
},
'login_redirect_url'
:
redirect_to
,
# This gets added to the query string of the "Sign In" button in header
'login_redirect_url'
:
redirect_to
,
# This gets added to the query string of the "Sign In" button in header
'responsive'
:
True
,
'responsive'
:
True
,
...
@@ -236,6 +252,7 @@ def update_context_for_enterprise(request, context):
...
@@ -236,6 +252,7 @@ def update_context_for_enterprise(request, context):
context
=
context
.
copy
()
context
=
context
.
copy
()
sidebar_context
=
enterprise_sidebar_context
(
request
)
sidebar_context
=
enterprise_sidebar_context
(
request
)
sync_learner_profile_data
=
context
[
'data'
][
'third_party_auth'
][
'syncLearnerProfileData'
]
if
sidebar_context
:
if
sidebar_context
:
context
[
'data'
][
'registration_form_desc'
][
'fields'
]
=
enterprise_fields_only
(
context
[
'data'
][
'registration_form_desc'
][
'fields'
]
=
enterprise_fields_only
(
...
@@ -247,6 +264,11 @@ def update_context_for_enterprise(request, context):
...
@@ -247,6 +264,11 @@ def update_context_for_enterprise(request, context):
else
:
else
:
context
[
'enable_enterprise_sidebar'
]
=
False
context
[
'enable_enterprise_sidebar'
]
=
False
if
sync_learner_profile_data
:
context
[
'data'
][
'hide_auth_warnings'
]
=
True
enterprise_customer
=
enterprise_customer_for_request
(
request
)
context
[
'data'
][
'enterprise_name'
]
=
enterprise_customer
and
enterprise_customer
[
'name'
]
return
context
return
context
...
@@ -327,6 +349,7 @@ def _third_party_auth_context(request, redirect_to, tpa_hint=None):
...
@@ -327,6 +349,7 @@ def _third_party_auth_context(request, redirect_to, tpa_hint=None):
"finishAuthUrl"
:
None
,
"finishAuthUrl"
:
None
,
"errorMessage"
:
None
,
"errorMessage"
:
None
,
"registerFormSubmitButtonText"
:
_
(
"Create Account"
),
"registerFormSubmitButtonText"
:
_
(
"Create Account"
),
"syncLearnerProfileData"
:
False
,
}
}
if
third_party_auth
.
is_enabled
():
if
third_party_auth
.
is_enabled
():
...
@@ -358,6 +381,8 @@ def _third_party_auth_context(request, redirect_to, tpa_hint=None):
...
@@ -358,6 +381,8 @@ def _third_party_auth_context(request, redirect_to, tpa_hint=None):
if
current_provider
is
not
None
:
if
current_provider
is
not
None
:
context
[
"currentProvider"
]
=
current_provider
.
name
context
[
"currentProvider"
]
=
current_provider
.
name
context
[
"finishAuthUrl"
]
=
pipeline
.
get_complete_url
(
current_provider
.
backend_name
)
context
[
"finishAuthUrl"
]
=
pipeline
.
get_complete_url
(
current_provider
.
backend_name
)
context
[
"hideSignInLink"
]
=
bool
(
current_provider
.
sync_learner_profile_data
)
context
[
"syncLearnerProfileData"
]
=
current_provider
.
sync_learner_profile_data
if
current_provider
.
skip_registration_form
:
if
current_provider
.
skip_registration_form
:
# For enterprise (and later for everyone), we need to get explicit consent to the
# For enterprise (and later for everyone), we need to get explicit consent to the
...
...
lms/static/js/student_account/views/AccessView.js
View file @
3b9550bd
...
@@ -71,10 +71,12 @@
...
@@ -71,10 +71,12 @@
};
};
this
.
platformName
=
options
.
platform_name
;
this
.
platformName
=
options
.
platform_name
;
this
.
enterpriseName
=
options
.
enterprise_name
;
this
.
supportURL
=
options
.
support_link
;
this
.
supportURL
=
options
.
support_link
;
this
.
passwordResetSupportUrl
=
options
.
password_reset_support_link
;
this
.
passwordResetSupportUrl
=
options
.
password_reset_support_link
;
this
.
createAccountOption
=
options
.
account_creation_allowed
;
this
.
createAccountOption
=
options
.
account_creation_allowed
;
this
.
hideAuthWarnings
=
options
.
hide_auth_warnings
||
false
;
this
.
hideAuthWarnings
=
options
.
hide_auth_warnings
||
false
;
this
.
pipelineUserDetails
=
options
.
pipeline_user_details
;
// The login view listens for 'sync' events from the reset model
// The login view listens for 'sync' events from the reset model
this
.
resetModel
=
new
PasswordResetModel
({},
{
this
.
resetModel
=
new
PasswordResetModel
({},
{
...
@@ -133,7 +135,8 @@
...
@@ -133,7 +135,8 @@
supportURL
:
this
.
supportURL
,
supportURL
:
this
.
supportURL
,
passwordResetSupportUrl
:
this
.
passwordResetSupportUrl
,
passwordResetSupportUrl
:
this
.
passwordResetSupportUrl
,
createAccountOption
:
this
.
createAccountOption
,
createAccountOption
:
this
.
createAccountOption
,
hideAuthWarnings
:
this
.
hideAuthWarnings
hideAuthWarnings
:
this
.
hideAuthWarnings
,
pipelineUserDetails
:
this
.
pipelineUserDetails
});
});
// Listen for 'password-help' event to toggle sub-views
// Listen for 'password-help' event to toggle sub-views
...
@@ -170,6 +173,7 @@
...
@@ -170,6 +173,7 @@
model
:
model
,
model
:
model
,
thirdPartyAuth
:
this
.
thirdPartyAuth
,
thirdPartyAuth
:
this
.
thirdPartyAuth
,
platformName
:
this
.
platformName
,
platformName
:
this
.
platformName
,
enterpriseName
:
this
.
enterpriseName
,
hideAuthWarnings
:
this
.
hideAuthWarnings
hideAuthWarnings
:
this
.
hideAuthWarnings
});
});
...
...
lms/static/js/student_account/views/LoginView.js
View file @
3b9550bd
...
@@ -49,6 +49,7 @@
...
@@ -49,6 +49,7 @@
this
.
createAccountOption
=
data
.
createAccountOption
;
this
.
createAccountOption
=
data
.
createAccountOption
;
this
.
accountActivationMessages
=
data
.
accountActivationMessages
;
this
.
accountActivationMessages
=
data
.
accountActivationMessages
;
this
.
hideAuthWarnings
=
data
.
hideAuthWarnings
;
this
.
hideAuthWarnings
=
data
.
hideAuthWarnings
;
this
.
pipelineUserDetails
=
data
.
pipelineUserDetails
;
this
.
listenTo
(
this
.
model
,
'sync'
,
this
.
saveSuccess
);
this
.
listenTo
(
this
.
model
,
'sync'
,
this
.
saveSuccess
);
this
.
listenTo
(
this
.
resetModel
,
'sync'
,
this
.
resetEmail
);
this
.
listenTo
(
this
.
resetModel
,
'sync'
,
this
.
resetEmail
);
...
@@ -66,7 +67,8 @@
...
@@ -66,7 +67,8 @@
providers
:
this
.
providers
,
providers
:
this
.
providers
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
platformName
:
this
.
platformName
,
platformName
:
this
.
platformName
,
createAccountOption
:
this
.
createAccountOption
createAccountOption
:
this
.
createAccountOption
,
pipelineUserDetails
:
this
.
pipelineUserDetails
}
}
}));
}));
...
...
lms/static/js/student_account/views/RegisterView.js
View file @
3b9550bd
...
@@ -55,6 +55,8 @@
...
@@ -55,6 +55,8 @@
data
.
thirdPartyAuth
.
secondaryProviders
&&
data
.
thirdPartyAuth
.
secondaryProviders
.
length
data
.
thirdPartyAuth
.
secondaryProviders
&&
data
.
thirdPartyAuth
.
secondaryProviders
.
length
);
);
this
.
currentProvider
=
data
.
thirdPartyAuth
.
currentProvider
||
''
;
this
.
currentProvider
=
data
.
thirdPartyAuth
.
currentProvider
||
''
;
this
.
hideSignInLink
=
data
.
thirdPartyAuth
.
hideSignInLink
||
false
;
this
.
enterpriseName
=
data
.
enterpriseName
||
''
;
this
.
errorMessage
=
data
.
thirdPartyAuth
.
errorMessage
||
''
;
this
.
errorMessage
=
data
.
thirdPartyAuth
.
errorMessage
||
''
;
this
.
platformName
=
data
.
platformName
;
this
.
platformName
=
data
.
platformName
;
this
.
autoSubmit
=
data
.
thirdPartyAuth
.
autoSubmitRegForm
;
this
.
autoSubmit
=
data
.
thirdPartyAuth
.
autoSubmitRegForm
;
...
@@ -141,6 +143,8 @@
...
@@ -141,6 +143,8 @@
context
:
{
context
:
{
fields
:
fields
,
fields
:
fields
,
currentProvider
:
this
.
currentProvider
,
currentProvider
:
this
.
currentProvider
,
hideSignInLink
:
this
.
hideSignInLink
,
enterpriseName
:
this
.
enterpriseName
,
providers
:
this
.
providers
,
providers
:
this
.
providers
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
platformName
:
this
.
platformName
,
platformName
:
this
.
platformName
,
...
...
lms/static/sass/views/_login-register.scss
View file @
3b9550bd
...
@@ -259,6 +259,20 @@
...
@@ -259,6 +259,20 @@
display
:
none
;
display
:
none
;
}
}
input
[
readonly
]
{
font-family
:
OpenSans-Regular
;
background-color
:
#e6e4e4
;
color
:
#292b2c
;
font-size
:
22px
;
border
:
none
;
margin
:
5px
0
;
&
:focus
{
outline
:
none
;
}
}
.auto-register-message
{
.auto-register-message
{
font-size
:
1
.1em
;
font-size
:
1
.1em
;
line-height
:
1
.3em
;
line-height
:
1
.3em
;
...
@@ -446,7 +460,8 @@
...
@@ -446,7 +460,8 @@
outline
:
solid
1px
$gray-l3
;
outline
:
solid
1px
$gray-l3
;
cursor
:
pointer
;
cursor
:
pointer
;
&
:active
,
&
:focus
{
&
:active
,
&
:focus
{
outline
:
auto
;
outline
:
auto
;
}
}
}
}
...
@@ -462,7 +477,8 @@
...
@@ -462,7 +477,8 @@
}
}
}
}
.tip
,
.label-optional
{
.tip
,
.label-optional
{
@extend
%t-copy-sub1
;
@extend
%t-copy-sub1
;
color
:
$uxpl-gray-base
;
color
:
$uxpl-gray-base
;
...
...
lms/templates/student_account/form_field.underscore
View file @
3b9550bd
...
@@ -91,7 +91,8 @@
...
@@ -91,7 +91,8 @@
<% } %>
<% } %>
<% if ( restrictions.min_length ) { %> minlength="<%- restrictions.min_length %>"<% } %>
<% if ( restrictions.min_length ) { %> minlength="<%- restrictions.min_length %>"<% } %>
<% if ( restrictions.max_length ) { %> maxlength="<%- restrictions.max_length %>"<% } %>
<% if ( restrictions.max_length ) { %> maxlength="<%- restrictions.max_length %>"<% } %>
<% if ( required ) { %> required<% } %>
<% if ( restrictions.readonly ) { %> readonly <% } %>
<% if ( required ) { %> required <% } %>
<% if ( typeof errorMessages !== 'undefined' ) {
<% if ( typeof errorMessages !== 'undefined' ) {
_.each(errorMessages, function( msg, type ) {%>
_.each(errorMessages, function( msg, type ) {%>
data-errormsg-<%- type %>="<%- msg %>"
data-errormsg-<%- type %>="<%- msg %>"
...
...
lms/templates/student_account/register.underscore
View file @
3b9550bd
<div class="js-form-feedback" aria-live="assertive" tabindex="-1">
<div class="js-form-feedback" aria-live="assertive" tabindex="-1">
</div>
</div>
<div class="toggle-form">
<% if (!context.hideSignInLink) { %>
<span class="text"><%- edx.StringUtils.interpolate(gettext('Already have an {platformName} account?'), {platformName: context.platformName }) %></span>
<div class="toggle-form">
<a href="#login" class="form-toggle" data-type="login"><%- gettext("Sign in.") %></a>
<span class="text"><%- edx.StringUtils.interpolate(gettext('Already have an {platformName} account?'), {platformName: context.platformName }) %></span>
</div>
<a href="#login" class="form-toggle" data-type="login"><%- gettext("Sign in.") %></a>
</div>
<% } %>
<h2><%- gettext('Create an Account')%></h2>
<form id="register" class="register-form" autocomplete="off" tabindex="-1" method="POST">
<form id="register" class="register-form" autocomplete="off" tabindex="-1" method="POST">
...
...
openedx/core/djangoapps/user_api/api.py
View file @
3b9550bd
...
@@ -835,35 +835,10 @@ class RegistrationFormFactory(object):
...
@@ -835,35 +835,10 @@ class RegistrationFormFactory(object):
current_provider
=
third_party_auth
.
provider
.
Registry
.
get_from_pipeline
(
running_pipeline
)
current_provider
=
third_party_auth
.
provider
.
Registry
.
get_from_pipeline
(
running_pipeline
)
if
current_provider
:
if
current_provider
:
# Override username / email / full name
self
.
_override_registration_fields_using_identity_provider_configuration
(
field_overrides
=
current_provider
.
get_register_form_data
(
request
,
current_provider
,
running_pipeline
,
form_desc
running_pipeline
.
get
(
'kwargs'
)
)
)
# When the TPA Provider is configured to skip the registration form and we are in an
# enterprise context, we need to hide all fields except for terms of service and
# ensure that the user explicitly checks that field.
hide_registration_fields_except_tos
=
(
current_provider
.
skip_registration_form
and
enterprise_customer_for_request
(
request
))
for
field_name
in
self
.
DEFAULT_FIELDS
+
self
.
EXTRA_FIELDS
:
if
field_name
in
field_overrides
:
form_desc
.
override_field_properties
(
field_name
,
default
=
field_overrides
[
field_name
]
)
if
(
field_name
not
in
[
'terms_of_service'
,
'honor_code'
]
and
field_overrides
[
field_name
]
and
hide_registration_fields_except_tos
):
form_desc
.
override_field_properties
(
field_name
,
field_type
=
"hidden"
,
label
=
""
,
instructions
=
""
,
)
# Hide the password field
form_desc
.
override_field_properties
(
form_desc
.
override_field_properties
(
"password"
,
"password"
,
default
=
""
,
default
=
""
,
...
@@ -881,3 +856,37 @@ class RegistrationFormFactory(object):
...
@@ -881,3 +856,37 @@ class RegistrationFormFactory(object):
default
=
current_provider
.
name
if
current_provider
.
name
else
"Third Party"
,
default
=
current_provider
.
name
if
current_provider
.
name
else
"Third Party"
,
required
=
False
,
required
=
False
,
)
)
# pylint: disable=invalid-name
def
_override_registration_fields_using_identity_provider_configuration
(
self
,
request
,
current_provider
,
running_pipeline
,
form_desc
):
"""
Apply form field overrides based on configuration of third party auth provider.
"""
field_overrides
=
current_provider
.
get_register_form_data
(
running_pipeline
.
get
(
'kwargs'
)
)
# When the TPA Provider is configured to skip the registration form and we are in an
# enterprise context, we need to hide all fields except for terms of service and
# ensure that the user explicitly checks that field.
hide_registration_fields_except_tos
=
(
(
current_provider
.
skip_registration_form
and
enterprise_customer_for_request
(
request
)
)
or
current_provider
.
sync_learner_profile_data
)
for
field_name
in
self
.
DEFAULT_FIELDS
+
self
.
EXTRA_FIELDS
:
if
field_name
in
field_overrides
:
form_desc
.
override_field_properties
(
field_name
,
default
=
field_overrides
[
field_name
]
)
if
field_name
not
in
[
'terms_of_service'
,
'honor_code'
]
and
field_overrides
[
field_name
]
and
\
hide_registration_fields_except_tos
:
form_desc
.
override_field_properties
(
field_name
,
field_type
=
"hidden"
,
label
=
""
,
instructions
=
""
,
)
openedx/core/djangoapps/user_api/helpers.py
View file @
3b9550bd
...
@@ -124,9 +124,9 @@ class FormDescription(object):
...
@@ -124,9 +124,9 @@ class FormDescription(object):
ALLOWED_TYPES
=
[
"text"
,
"email"
,
"select"
,
"textarea"
,
"checkbox"
,
"password"
,
"hidden"
]
ALLOWED_TYPES
=
[
"text"
,
"email"
,
"select"
,
"textarea"
,
"checkbox"
,
"password"
,
"hidden"
]
ALLOWED_RESTRICTIONS
=
{
ALLOWED_RESTRICTIONS
=
{
"text"
:
[
"min_length"
,
"max_length"
],
"text"
:
[
"min_length"
,
"max_length"
,
"readonly"
],
"password"
:
[
"min_length"
,
"max_length"
],
"password"
:
[
"min_length"
,
"max_length"
,
"readonly"
],
"email"
:
[
"min_length"
,
"max_length"
],
"email"
:
[
"min_length"
,
"max_length"
,
"readonly"
],
}
}
FIELD_TYPE_MAP
=
{
FIELD_TYPE_MAP
=
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment