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
86da9c1c
Commit
86da9c1c
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
257de20d
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
101 additions
and
17 deletions
+101
-17
common/djangoapps/third_party_auth/pipeline.py
+10
-4
common/djangoapps/third_party_auth/tests/specs/base.py
+2
-1
common/djangoapps/third_party_auth/tests/specs/test_azuread.py
+2
-2
common/djangoapps/third_party_auth/tests/specs/test_google.py
+3
-3
common/djangoapps/third_party_auth/tests/test_utils.py
+34
-0
common/djangoapps/third_party_auth/utils.py
+29
-0
lms/djangoapps/student_account/test/test_views.py
+1
-0
lms/djangoapps/student_account/views.py
+2
-0
lms/static/js/student_account/views/LoginView.js
+2
-0
lms/static/js/student_account/views/RegisterView.js
+2
-0
lms/templates/student_account/login.underscore
+1
-1
lms/templates/student_account/register.underscore
+8
-4
openedx/core/djangoapps/user_api/api.py
+5
-2
No files found.
common/djangoapps/third_party_auth/pipeline.py
View file @
86da9c1c
...
...
@@ -84,6 +84,7 @@ import student
from
edxmako.shortcuts
import
render_to_string
from
eventtracking
import
tracker
from
openedx.core.djangoapps.site_configuration
import
helpers
as
configuration_helpers
from
third_party_auth.utils
import
user_exists
from
.
import
provider
...
...
@@ -501,7 +502,7 @@ def set_pipeline_timeout(strategy, user, *args, **kwargs):
# choice of the user.
def
redirect_to_custom_form
(
request
,
auth_entry
,
kwargs
):
def
redirect_to_custom_form
(
request
,
auth_entry
,
details
,
kwargs
):
"""
If auth_entry is found in AUTH_ENTRY_CUSTOM, this is used to send provider
data to an external server's registration/login page.
...
...
@@ -520,7 +521,7 @@ def redirect_to_custom_form(request, auth_entry, kwargs):
"auth_entry"
:
auth_entry
,
"backend_name"
:
backend_name
,
"provider_id"
:
provider_id
,
"user_details"
:
kwargs
[
'details'
]
,
"user_details"
:
details
,
})
digest
=
hmac
.
new
(
secret_key
,
msg
=
data_str
,
digestmod
=
hashlib
.
sha256
)
.
digest
()
# Store the data in the session temporarily, then redirect to a page that will POST it to
...
...
@@ -535,7 +536,7 @@ def redirect_to_custom_form(request, auth_entry, kwargs):
@partial.partial
def
ensure_user_information
(
strategy
,
auth_entry
,
backend
=
None
,
user
=
None
,
social
=
None
,
current_partial
=
None
,
allow_inactive_user
=
False
,
*
args
,
**
kwargs
):
allow_inactive_user
=
False
,
details
=
None
,
*
args
,
**
kwargs
):
"""
Ensure that we have the necessary information about a user (either an
existing account or registration data) to proceed with the pipeline.
...
...
@@ -567,6 +568,11 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia
(
current_provider
.
skip_email_verification
or
current_provider
.
send_to_registration_first
))
if
not
user
:
if
user_exists
(
details
or
{}):
# User has not already authenticated and the details sent over from
# identity provider belong to an existing user.
return
dispatch_to_login
()
if
is_api
(
auth_entry
):
return
HttpResponseBadRequest
()
elif
auth_entry
==
AUTH_ENTRY_LOGIN
:
...
...
@@ -583,7 +589,7 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia
raise
AuthEntryError
(
backend
,
'auth_entry is wrong. Settings requires a user.'
)
elif
auth_entry
in
AUTH_ENTRY_CUSTOM
:
# Pass the username, email, etc. via query params to the custom entry page:
return
redirect_to_custom_form
(
strategy
.
request
,
auth_entry
,
kwargs
)
return
redirect_to_custom_form
(
strategy
.
request
,
auth_entry
,
details
or
{},
kwargs
)
else
:
raise
AuthEntryError
(
backend
,
'auth_entry invalid'
)
...
...
common/djangoapps/third_party_auth/tests/specs/base.py
View file @
86da9c1c
...
...
@@ -894,8 +894,9 @@ class IntegrationTest(testutil.TestCase, test.TestCase):
strategy
.
storage
.
user
.
create_user
(
username
=
self
.
get_username
(),
email
=
'user@email.com'
,
password
=
'password'
)
backend
=
strategy
.
request
.
backend
backend
.
auth_complete
=
mock
.
MagicMock
(
return_value
=
self
.
fake_auth_complete
(
strategy
))
# If learner already has an account then make sure login page is served instead of registration.
# pylint: disable=protected-access
self
.
assert_redirect_to_
register
_looks_correct
(
actions
.
do_complete
(
backend
,
social_views
.
_do_login
))
self
.
assert_redirect_to_
login
_looks_correct
(
actions
.
do_complete
(
backend
,
social_views
.
_do_login
))
distinct_username
=
pipeline
.
get
(
request
)[
'kwargs'
][
'username'
]
self
.
assertNotEqual
(
original_username
,
distinct_username
)
...
...
common/djangoapps/third_party_auth/tests/specs/test_azuread.py
View file @
86da9c1c
...
...
@@ -35,8 +35,8 @@ class AzureADOauth2IntegrationTest(base.Oauth2IntegrationTest):
'aud'
:
'abcdefgh-1234-5678-900a-0aa0a00aa0aa'
,
'tid'
:
'abcdefgh-1234-5678-900a-0aa0a00aa0aa'
,
'amr'
:
[
'pwd'
],
'unique_name'
:
'
email_value@example
.com'
,
'upn'
:
'
email_value@example
.com'
,
'unique_name'
:
'
user@email
.com'
,
'upn'
:
'
user@email
.com'
,
'family_name'
:
'family_name_value'
,
'name'
:
'name_value'
,
'given_name'
:
'given_name_value'
,
...
...
common/djangoapps/third_party_auth/tests/specs/test_google.py
View file @
86da9c1c
...
...
@@ -31,7 +31,7 @@ class GoogleOauth2IntegrationTest(base.Oauth2IntegrationTest):
'token_type'
:
'token_type_value'
,
}
USER_RESPONSE_DATA
=
{
'email'
:
'
email_value@example
.com'
,
'email'
:
'
user@email
.com'
,
'family_name'
:
'family_name_value'
,
'given_name'
:
'given_name_value'
,
'id'
:
'id_value'
,
...
...
@@ -85,8 +85,8 @@ class GoogleOauth2IntegrationTest(base.Oauth2IntegrationTest):
'backend_name'
:
'google-oauth2'
,
'provider_id'
:
'oa2-google-oauth2'
,
'user_details'
:
{
'username'
:
'
email_value
'
,
'email'
:
'
email_value@example
.com'
,
'username'
:
'
user
'
,
'email'
:
'
user@email
.com'
,
'fullname'
:
'name_value'
,
'first_name'
:
'given_name_value'
,
'last_name'
:
'family_name_value'
,
...
...
common/djangoapps/third_party_auth/tests/test_utils.py
0 → 100644
View file @
86da9c1c
"""
Tests for third_party_auth utility functions.
"""
import
unittest
from
django.conf
import
settings
from
third_party_auth.tests.testutil
import
TestCase
from
third_party_auth.utils
import
user_exists
from
student.tests.factories
import
UserFactory
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
class
TestUtils
(
TestCase
):
"""
Test the utility functions.
"""
def
test_user_exists
(
self
):
"""
Verify that user_exists function returns correct response.
"""
# Create users from factory
UserFactory
(
username
=
'test_user'
,
email
=
'test_user@example.com'
)
self
.
assertTrue
(
user_exists
({
'username'
:
'test_user'
,
'email'
:
'test_user@example.com'
}),
)
self
.
assertTrue
(
user_exists
({
'username'
:
'test_user'
}),
)
self
.
assertTrue
(
user_exists
({
'email'
:
'test_user@example.com'
}),
)
self
.
assertFalse
(
user_exists
({
'username'
:
'invalid_user'
}),
)
common/djangoapps/third_party_auth/utils.py
0 → 100644
View file @
86da9c1c
"""
Utility functions for third_party_auth
"""
from
django.contrib.auth.models
import
User
def
user_exists
(
details
):
"""
Return True if user with given details exist in the system.
Arguments:
details (dict): dictionary containing user infor like email, username etc.
Returns:
(bool): True if user with given details exists, `False` otherwise.
"""
user_queryset_filter
=
{}
email
=
details
.
get
(
'email'
)
username
=
details
.
get
(
'username'
)
if
email
:
user_queryset_filter
[
'email'
]
=
email
elif
username
:
user_queryset_filter
[
'username'
]
=
username
if
user_queryset_filter
:
return
User
.
objects
.
filter
(
**
user_queryset_filter
)
.
exists
()
return
False
lms/djangoapps/student_account/test/test_views.py
View file @
86da9c1c
...
...
@@ -640,6 +640,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
"finishAuthUrl"
:
finish_auth_url
,
"errorMessage"
:
None
,
"registerFormSubmitButtonText"
:
"Create Account"
,
"syncLearnerProfileData"
:
False
,
}
if
expected_ec
is
not
None
:
# If we set an EnterpriseCustomer, third-party auth providers ought to be hidden.
...
...
lms/djangoapps/student_account/views.py
View file @
86da9c1c
...
...
@@ -326,6 +326,7 @@ def _third_party_auth_context(request, redirect_to, tpa_hint=None):
"finishAuthUrl"
:
None
,
"errorMessage"
:
None
,
"registerFormSubmitButtonText"
:
_
(
"Create Account"
),
"syncLearnerProfileData"
:
False
,
}
if
third_party_auth
.
is_enabled
():
...
...
@@ -357,6 +358,7 @@ def _third_party_auth_context(request, redirect_to, tpa_hint=None):
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
:
# For enterprise (and later for everyone), we need to get explicit consent to the
...
...
lms/static/js/student_account/views/LoginView.js
View file @
86da9c1c
...
...
@@ -41,6 +41,7 @@
data
.
thirdPartyAuth
.
secondaryProviders
&&
data
.
thirdPartyAuth
.
secondaryProviders
.
length
);
this
.
currentProvider
=
data
.
thirdPartyAuth
.
currentProvider
||
''
;
this
.
syncLearnerProfileData
=
data
.
thirdPartyAuth
.
syncLearnerProfileData
||
false
;
this
.
errorMessage
=
data
.
thirdPartyAuth
.
errorMessage
||
''
;
this
.
platformName
=
data
.
platformName
;
this
.
resetModel
=
data
.
resetModel
;
...
...
@@ -63,6 +64,7 @@
context
:
{
fields
:
fields
,
currentProvider
:
this
.
currentProvider
,
syncLearnerProfileData
:
this
.
syncLearnerProfileData
,
providers
:
this
.
providers
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
platformName
:
this
.
platformName
,
...
...
lms/static/js/student_account/views/RegisterView.js
View file @
86da9c1c
...
...
@@ -55,6 +55,7 @@
data
.
thirdPartyAuth
.
secondaryProviders
&&
data
.
thirdPartyAuth
.
secondaryProviders
.
length
);
this
.
currentProvider
=
data
.
thirdPartyAuth
.
currentProvider
||
''
;
this
.
syncLearnerProfileData
=
data
.
thirdPartyAuth
.
syncLearnerProfileData
||
false
;
this
.
errorMessage
=
data
.
thirdPartyAuth
.
errorMessage
||
''
;
this
.
platformName
=
data
.
platformName
;
this
.
autoSubmit
=
data
.
thirdPartyAuth
.
autoSubmitRegForm
;
...
...
@@ -141,6 +142,7 @@
context
:
{
fields
:
fields
,
currentProvider
:
this
.
currentProvider
,
syncLearnerProfileData
:
this
.
syncLearnerProfileData
,
providers
:
this
.
providers
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
platformName
:
this
.
platformName
,
...
...
lms/templates/student_account/login.underscore
View file @
86da9c1c
<div class="js-form-feedback" aria-live="assertive" tabindex="-1">
</div>
<% if ( context.createAccountOption !== false ) { %>
<% if ( context.createAccountOption !== false
&& !context.syncLearnerProfileData
) { %>
<div class="toggle-form">
<span class="text"><%- gettext("First time here?") %></span>
<a href="#login" class="form-toggle" data-type="register"><%- gettext("Create an Account.") %></a>
...
...
lms/templates/student_account/register.underscore
View file @
86da9c1c
<div class="js-form-feedback" aria-live="assertive" tabindex="-1">
</div>
<div class="toggle-form">
<span class="text"><%- edx.StringUtils.interpolate(gettext('Already have an {platformName} account?'), {platformName: context.platformName }) %></span>
<a href="#login" class="form-toggle" data-type="login"><%- gettext("Sign in.") %></a>
</div>
<% if (!context.syncLearnerProfileData) { %>
<div class="toggle-form">
<span class="text"><%- edx.StringUtils.interpolate(gettext('Already have an {platformName} account?'), {platformName: context.platformName }) %></span>
<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">
...
...
openedx/core/djangoapps/user_api/api.py
View file @
86da9c1c
...
...
@@ -843,8 +843,11 @@ class RegistrationFormFactory(object):
# 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
))
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
:
...
...
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