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
99e85556
Commit
99e85556
authored
Feb 27, 2015
by
Christina Roberts
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7140 from edx/christina/delete-enable-new-dashboard
Delete ENABLE_NEW_DASHBOARD code.
parents
820b0118
61a108d3
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
0 additions
and
798 deletions
+0
-798
common/djangoapps/student/models.py
+0
-26
common/djangoapps/third_party_auth/pipeline.py
+0
-8
common/djangoapps/third_party_auth/settings.py
+0
-7
lms/djangoapps/student_account/test/test_views.py
+0
-173
lms/djangoapps/student_account/urls.py
+0
-8
lms/djangoapps/student_account/views.py
+0
-164
lms/envs/common.py
+0
-3
lms/templates/student_account/email_change_failed.html
+0
-30
lms/templates/student_account/email_change_successful.html
+0
-18
lms/templates/student_account/emails/email_change_confirmation/message_body.txt
+0
-21
lms/templates/student_account/emails/email_change_confirmation/subject_line.txt
+0
-3
lms/templates/student_account/emails/email_change_request/message_body.txt
+0
-34
lms/templates/student_account/emails/email_change_request/subject_line.txt
+0
-3
lms/templates/student_account/index.html
+0
-26
openedx/core/djangoapps/user_api/api/account.py
+0
-121
openedx/core/djangoapps/user_api/tests/test_account_api.py
+0
-153
No files found.
common/djangoapps/student/models.py
View file @
99e85556
...
...
@@ -309,32 +309,6 @@ class UserProfile(models.Model):
self
.
name
=
new_name
self
.
save
()
@transaction.commit_on_success
def
update_email
(
self
,
new_email
):
"""Update the user's email and save the change in the history.
Implicitly saves the model.
If the new email is the same as the old email, do not update the history.
Arguments:
new_email (unicode): The new email for the user.
Returns:
None
"""
if
self
.
user
.
email
==
new_email
:
return
meta
=
self
.
get_meta
()
if
'old_emails'
not
in
meta
:
meta
[
'old_emails'
]
=
[]
meta
[
'old_emails'
]
.
append
([
self
.
user
.
email
,
datetime
.
now
(
UTC
)
.
isoformat
()])
self
.
set_meta
(
meta
)
self
.
save
()
self
.
user
.
email
=
new_email
self
.
user
.
save
()
class
UserSignupSource
(
models
.
Model
):
"""
...
...
common/djangoapps/third_party_auth/pipeline.py
View file @
99e85556
...
...
@@ -112,7 +112,6 @@ AUTH_EMAIL_OPT_IN_KEY = 'email_opt_in'
AUTH_ENTRY_DASHBOARD
=
'dashboard'
AUTH_ENTRY_LOGIN
=
'login'
AUTH_ENTRY_PROFILE
=
'profile'
AUTH_ENTRY_REGISTER
=
'register'
# This is left-over from an A/B test
...
...
@@ -143,16 +142,11 @@ AUTH_DISPATCH_URLS = {
AUTH_ENTRY_LOGIN_2
:
'/account/login/'
,
AUTH_ENTRY_REGISTER_2
:
'/account/register/'
,
# If linking/unlinking an account from the new student profile
# page, redirect to the profile page. Only used if
# `FEATURES['ENABLE_NEW_DASHBOARD']` is true.
AUTH_ENTRY_PROFILE
:
'/profile/'
,
}
_AUTH_ENTRY_CHOICES
=
frozenset
([
AUTH_ENTRY_DASHBOARD
,
AUTH_ENTRY_LOGIN
,
AUTH_ENTRY_PROFILE
,
AUTH_ENTRY_REGISTER
,
# This is left-over from an A/B test
...
...
@@ -452,8 +446,6 @@ def parse_query_params(strategy, response, *args, **kwargs):
'is_login'
:
auth_entry
in
[
AUTH_ENTRY_LOGIN
,
AUTH_ENTRY_LOGIN_2
],
# Whether the auth pipeline entered from /register.
'is_register'
:
auth_entry
in
[
AUTH_ENTRY_REGISTER
,
AUTH_ENTRY_REGISTER_2
],
# Whether the auth pipeline entered from /profile.
'is_profile'
:
auth_entry
==
AUTH_ENTRY_PROFILE
,
# Whether the auth pipeline entered from an API
'is_api'
:
auth_entry
==
AUTH_ENTRY_API
,
}
...
...
common/djangoapps/third_party_auth/settings.py
View file @
99e85556
...
...
@@ -51,8 +51,6 @@ _MIDDLEWARE_CLASSES = (
'third_party_auth.middleware.ExceptionMiddleware'
,
)
_SOCIAL_AUTH_LOGIN_REDIRECT_URL
=
'/dashboard'
_SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL
=
'/profile'
_SOCIAL_AUTH_DISCONNECT_REDIRECT_URL
=
'/profile'
def
_merge_auth_info
(
django_settings
,
auth_info
):
...
...
@@ -97,11 +95,6 @@ def _set_global_settings(django_settings):
# Where to send the user once social authentication is successful.
django_settings
.
SOCIAL_AUTH_LOGIN_REDIRECT_URL
=
_SOCIAL_AUTH_LOGIN_REDIRECT_URL
# Change redirects to the profile page if we enable the new dashboard.
if
django_settings
.
FEATURES
.
get
(
'ENABLE_NEW_DASHBOARD'
,
''
):
django_settings
.
SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL
=
_SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL
django_settings
.
SOCIAL_AUTH_DISCONNECT_REDIRECT_URL
=
_SOCIAL_AUTH_DISCONNECT_REDIRECT_URL
# Inject our customized auth pipeline. All auth backends must work with
# this pipeline.
django_settings
.
SOCIAL_AUTH_PIPELINE
=
(
...
...
lms/djangoapps/student_account/test/test_views.py
View file @
99e85556
...
...
@@ -59,7 +59,6 @@ class StudentAccountUpdateTest(UrlResetMixin, TestCase):
INVALID_KEY
=
u"123abc"
@mock.patch.dict
(
settings
.
FEATURES
,
{
'ENABLE_NEW_DASHBOARD'
:
True
})
def
setUp
(
self
):
super
(
StudentAccountUpdateTest
,
self
)
.
setUp
(
"student_account.urls"
)
...
...
@@ -71,141 +70,6 @@ class StudentAccountUpdateTest(UrlResetMixin, TestCase):
result
=
self
.
client
.
login
(
username
=
self
.
USERNAME
,
password
=
self
.
OLD_PASSWORD
)
self
.
assertTrue
(
result
)
def
test_index
(
self
):
response
=
self
.
client
.
get
(
reverse
(
'account_index'
))
self
.
assertContains
(
response
,
"Student Account"
)
def
test_change_email
(
self
):
response
=
self
.
_change_email
(
self
.
NEW_EMAIL
,
self
.
OLD_PASSWORD
)
self
.
assertEquals
(
response
.
status_code
,
200
)
# Verify that the email associated with the account remains unchanged
profile_info
=
profile_api
.
profile_info
(
self
.
USERNAME
)
self
.
assertEquals
(
profile_info
[
'email'
],
self
.
OLD_EMAIL
)
# Check that an email was sent with the activation key
self
.
assertEqual
(
len
(
mail
.
outbox
),
1
)
self
.
_assert_email
(
mail
.
outbox
[
0
],
[
self
.
NEW_EMAIL
],
u"Email Change Request"
,
u"There was recently a request to change the email address"
)
# Retrieve the activation key from the email
email_body
=
mail
.
outbox
[
0
]
.
body
result
=
re
.
search
(
'/email/confirmation/([^
\n
]+)'
,
email_body
)
self
.
assertIsNot
(
result
,
None
)
activation_key
=
result
.
group
(
1
)
# Attempt to activate the email
response
=
self
.
client
.
get
(
reverse
(
'email_change_confirm'
,
kwargs
=
{
'key'
:
activation_key
}))
self
.
assertEqual
(
response
.
status_code
,
200
)
# Verify that the email was changed
profile_info
=
profile_api
.
profile_info
(
self
.
USERNAME
)
self
.
assertEquals
(
profile_info
[
'email'
],
self
.
NEW_EMAIL
)
# Verify that notification emails were sent
self
.
assertEqual
(
len
(
mail
.
outbox
),
2
)
self
.
_assert_email
(
mail
.
outbox
[
1
],
[
self
.
OLD_EMAIL
,
self
.
NEW_EMAIL
],
u"Email Change Successful"
,
u"You successfully changed the email address"
)
def
test_email_change_wrong_password
(
self
):
response
=
self
.
_change_email
(
self
.
NEW_EMAIL
,
"wrong password"
)
self
.
assertEqual
(
response
.
status_code
,
401
)
def
test_email_change_request_no_user
(
self
):
# Patch account API to raise an internal error when an email change is requested
with
mock
.
patch
(
'student_account.views.account_api.request_email_change'
)
as
mock_call
:
mock_call
.
side_effect
=
account_api
.
AccountUserNotFound
response
=
self
.
_change_email
(
self
.
NEW_EMAIL
,
self
.
OLD_PASSWORD
)
self
.
assertEquals
(
response
.
status_code
,
400
)
def
test_email_change_request_email_taken_by_active_account
(
self
):
# Create/activate a second user with the new email
activation_key
=
account_api
.
create_account
(
self
.
ALTERNATE_USERNAME
,
self
.
OLD_PASSWORD
,
self
.
NEW_EMAIL
)
account_api
.
activate_account
(
activation_key
)
# Request to change the original user's email to the email now used by the second user
response
=
self
.
_change_email
(
self
.
NEW_EMAIL
,
self
.
OLD_PASSWORD
)
self
.
assertEquals
(
response
.
status_code
,
409
)
def
test_email_change_request_email_taken_by_inactive_account
(
self
):
# Create a second user with the new email, but don't active them
account_api
.
create_account
(
self
.
ALTERNATE_USERNAME
,
self
.
OLD_PASSWORD
,
self
.
NEW_EMAIL
)
# Request to change the original user's email to the email used by the inactive user
response
=
self
.
_change_email
(
self
.
NEW_EMAIL
,
self
.
OLD_PASSWORD
)
self
.
assertEquals
(
response
.
status_code
,
200
)
@ddt.data
(
*
INVALID_EMAILS
)
def
test_email_change_request_email_invalid
(
self
,
invalid_email
):
# Request to change the user's email to an invalid address
response
=
self
.
_change_email
(
invalid_email
,
self
.
OLD_PASSWORD
)
self
.
assertEquals
(
response
.
status_code
,
400
)
def
test_email_change_confirmation
(
self
):
# Get an email change activation key
activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
self
.
NEW_EMAIL
,
self
.
OLD_PASSWORD
)
# Follow the link sent in the confirmation email
response
=
self
.
client
.
get
(
reverse
(
'email_change_confirm'
,
kwargs
=
{
'key'
:
activation_key
}))
self
.
assertContains
(
response
,
"Email change successful"
)
# Verify that the email associated with the account has changed
profile_info
=
profile_api
.
profile_info
(
self
.
USERNAME
)
self
.
assertEquals
(
profile_info
[
'email'
],
self
.
NEW_EMAIL
)
def
test_email_change_confirmation_invalid_key
(
self
):
# Visit the confirmation page with an invalid key
response
=
self
.
client
.
get
(
reverse
(
'email_change_confirm'
,
kwargs
=
{
'key'
:
self
.
INVALID_KEY
}))
self
.
assertContains
(
response
,
"Something went wrong"
)
# Verify that the email associated with the account has not changed
profile_info
=
profile_api
.
profile_info
(
self
.
USERNAME
)
self
.
assertEquals
(
profile_info
[
'email'
],
self
.
OLD_EMAIL
)
def
test_email_change_confirmation_email_already_exists
(
self
):
# Get an email change activation key
email_activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
self
.
NEW_EMAIL
,
self
.
OLD_PASSWORD
)
# Create/activate a second user with the new email
account_activation_key
=
account_api
.
create_account
(
self
.
ALTERNATE_USERNAME
,
self
.
OLD_PASSWORD
,
self
.
NEW_EMAIL
)
account_api
.
activate_account
(
account_activation_key
)
# Follow the link sent to the original user
response
=
self
.
client
.
get
(
reverse
(
'email_change_confirm'
,
kwargs
=
{
'key'
:
email_activation_key
}))
self
.
assertContains
(
response
,
"address you wanted to use is already used"
)
# Verify that the email associated with the original account has not changed
profile_info
=
profile_api
.
profile_info
(
self
.
USERNAME
)
self
.
assertEquals
(
profile_info
[
'email'
],
self
.
OLD_EMAIL
)
def
test_email_change_confirmation_internal_error
(
self
):
# Get an email change activation key
activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
self
.
NEW_EMAIL
,
self
.
OLD_PASSWORD
)
# Patch account API to return an internal error
with
mock
.
patch
(
'student_account.views.account_api.confirm_email_change'
)
as
mock_call
:
mock_call
.
side_effect
=
account_api
.
AccountInternalError
response
=
self
.
client
.
get
(
reverse
(
'email_change_confirm'
,
kwargs
=
{
'key'
:
activation_key
}))
self
.
assertContains
(
response
,
"Something went wrong"
)
def
test_email_change_request_missing_email_param
(
self
):
response
=
self
.
_change_email
(
None
,
self
.
OLD_PASSWORD
)
self
.
assertEqual
(
response
.
status_code
,
400
)
def
test_email_change_request_missing_password_param
(
self
):
response
=
self
.
_change_email
(
self
.
OLD_EMAIL
,
None
)
self
.
assertEqual
(
response
.
status_code
,
400
)
@skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in LMS'
)
def
test_password_change
(
self
):
# Request a password change while logged in, simulating
...
...
@@ -316,25 +180,6 @@ class StudentAccountUpdateTest(UrlResetMixin, TestCase):
self
.
assertEqual
(
response
.
status_code
,
403
)
@ddt.data
(
(
'get'
,
'account_index'
,
[]),
(
'post'
,
'email_change_request'
,
[]),
(
'get'
,
'email_change_confirm'
,
[
123
])
)
@ddt.unpack
def
test_require_login
(
self
,
method
,
url_name
,
args
):
# Access the page while logged out
self
.
client
.
logout
()
url
=
reverse
(
url_name
,
args
=
args
)
response
=
getattr
(
self
.
client
,
method
)(
url
,
follow
=
True
)
# Should have been redirected to the login page
self
.
assertEqual
(
len
(
response
.
redirect_chain
),
1
)
self
.
assertIn
(
'accounts/login?next='
,
response
.
redirect_chain
[
0
][
0
])
@ddt.data
(
(
'get'
,
'account_index'
,
[]),
(
'post'
,
'email_change_request'
,
[]),
(
'get'
,
'email_change_confirm'
,
[
123
]),
(
'post'
,
'password_change_request'
,
[]),
)
@ddt.unpack
...
...
@@ -346,24 +191,6 @@ class StudentAccountUpdateTest(UrlResetMixin, TestCase):
response
=
getattr
(
self
.
client
,
method
)(
url
)
self
.
assertEqual
(
response
.
status_code
,
405
)
def
_assert_email
(
self
,
email
,
expected_to
,
expected_subject
,
expected_body
):
"""Check whether an email has the correct properties. """
self
.
assertEqual
(
email
.
to
,
expected_to
)
self
.
assertIn
(
expected_subject
,
email
.
subject
)
self
.
assertIn
(
expected_body
,
email
.
body
)
def
_change_email
(
self
,
new_email
,
password
):
"""Request to change the user's email. """
data
=
{}
if
new_email
is
not
None
:
data
[
'email'
]
=
new_email
if
password
is
not
None
:
# We can't pass a Unicode object to urlencode, so we encode the Unicode object
data
[
'password'
]
=
password
.
encode
(
'utf-8'
)
return
self
.
client
.
post
(
path
=
reverse
(
'email_change_request'
),
data
=
data
)
def
_change_password
(
self
,
email
=
None
):
"""Request to change the user's password. """
data
=
{}
...
...
lms/djangoapps/student_account/urls.py
View file @
99e85556
...
...
@@ -11,11 +11,3 @@ if settings.FEATURES.get('ENABLE_COMBINED_LOGIN_REGISTRATION'):
url
(
r'^register/$'
,
'login_and_registration_form'
,
{
'initial_mode'
:
'register'
},
name
=
'account_register'
),
url
(
r'^password$'
,
'password_change_request_handler'
,
name
=
'password_change_request'
),
)
if
settings
.
FEATURES
.
get
(
'ENABLE_NEW_DASHBOARD'
):
urlpatterns
+=
patterns
(
'student_account.views'
,
url
(
r'^$'
,
'index'
,
name
=
'account_index'
),
url
(
r'^email$'
,
'email_change_request_handler'
,
name
=
'email_change_request'
),
url
(
r'^email/confirmation/(?P<key>[^/]*)$'
,
'email_change_confirmation_handler'
,
name
=
'email_change_confirm'
),
)
lms/djangoapps/student_account/views.py
View file @
99e85556
...
...
@@ -42,31 +42,6 @@ from student_account.helpers import auth_pipeline_urls
AUDIT_LOG
=
logging
.
getLogger
(
"audit"
)
@login_required
@require_http_methods
([
'GET'
])
def
index
(
request
):
"""Render the account info page.
Args:
request (HttpRequest)
Returns:
HttpResponse: 200 if the index page was sent successfully
HttpResponse: 302 if not logged in (redirect to login page)
HttpResponse: 405 if using an unsupported HTTP method
Example usage:
GET /account
"""
return
render_to_response
(
'student_account/index.html'
,
{
'disable_courseware_js'
:
True
,
}
)
@require_http_methods
([
'GET'
])
@ensure_csrf_cookie
def
login_and_registration_form
(
request
,
initial_mode
=
"login"
):
...
...
@@ -124,145 +99,6 @@ def login_and_registration_form(request, initial_mode="login"):
return
render_to_response
(
'student_account/login_and_register.html'
,
context
)
@login_required
@require_http_methods
([
'POST'
])
@ensure_csrf_cookie
def
email_change_request_handler
(
request
):
"""Handle a request to change the user's email address.
Sends an email to the newly specified address containing a link
to a confirmation page.
Args:
request (HttpRequest)
Returns:
HttpResponse: 200 if the confirmation email was sent successfully
HttpResponse: 302 if not logged in (redirect to login page)
HttpResponse: 400 if the format of the new email is incorrect, or if
an email change is requested for a user which does not exist
HttpResponse: 401 if the provided password (in the form) is incorrect
HttpResponse: 405 if using an unsupported HTTP method
HttpResponse: 409 if the provided email is already in use
Example usage:
POST /account/email
"""
username
=
request
.
user
.
username
password
=
request
.
POST
.
get
(
'password'
)
new_email
=
request
.
POST
.
get
(
'email'
)
if
new_email
is
None
:
return
HttpResponseBadRequest
(
"Missing param 'email'"
)
if
password
is
None
:
return
HttpResponseBadRequest
(
"Missing param 'password'"
)
old_email
=
profile_api
.
profile_info
(
username
)[
'email'
]
try
:
key
=
account_api
.
request_email_change
(
username
,
new_email
,
password
)
except
(
account_api
.
AccountEmailInvalid
,
account_api
.
AccountUserNotFound
):
return
HttpResponseBadRequest
()
except
account_api
.
AccountEmailAlreadyExists
:
return
HttpResponse
(
status
=
409
)
except
account_api
.
AccountNotAuthorized
:
return
HttpResponse
(
status
=
401
)
context
=
{
'key'
:
key
,
'old_email'
:
old_email
,
'new_email'
:
new_email
,
}
subject
=
render_to_string
(
'student_account/emails/email_change_request/subject_line.txt'
,
context
)
subject
=
''
.
join
(
subject
.
splitlines
())
message
=
render_to_string
(
'student_account/emails/email_change_request/message_body.txt'
,
context
)
from_address
=
microsite
.
get_value
(
'email_from_address'
,
settings
.
DEFAULT_FROM_EMAIL
)
# Send a confirmation email to the new address containing the activation key
send_mail
(
subject
,
message
,
from_address
,
[
new_email
])
return
HttpResponse
(
status
=
200
)
@login_required
@require_http_methods
([
'GET'
])
def
email_change_confirmation_handler
(
request
,
key
):
"""Complete a change of the user's email address.
This is called when the activation link included in the confirmation
email is clicked.
Args:
request (HttpRequest)
Returns:
HttpResponse: 200 if the email change is successful, the activation key
is invalid, the new email is already in use, or the
user to which the email change will be applied does
not exist
HttpResponse: 302 if not logged in (redirect to login page)
HttpResponse: 405 if using an unsupported HTTP method
Example usage:
GET /account/email/confirmation/{key}
"""
try
:
old_email
,
new_email
=
account_api
.
confirm_email_change
(
key
)
except
account_api
.
AccountNotAuthorized
:
return
render_to_response
(
'student_account/email_change_failed.html'
,
{
'disable_courseware_js'
:
True
,
'error'
:
'key_invalid'
,
}
)
except
account_api
.
AccountEmailAlreadyExists
:
return
render_to_response
(
'student_account/email_change_failed.html'
,
{
'disable_courseware_js'
:
True
,
'error'
:
'email_used'
,
}
)
except
account_api
.
AccountInternalError
:
return
render_to_response
(
'student_account/email_change_failed.html'
,
{
'disable_courseware_js'
:
True
,
'error'
:
'internal'
,
}
)
context
=
{
'old_email'
:
old_email
,
'new_email'
:
new_email
,
}
subject
=
render_to_string
(
'student_account/emails/email_change_confirmation/subject_line.txt'
,
context
)
subject
=
''
.
join
(
subject
.
splitlines
())
message
=
render_to_string
(
'student_account/emails/email_change_confirmation/message_body.txt'
,
context
)
from_address
=
microsite
.
get_value
(
'email_from_address'
,
settings
.
DEFAULT_FROM_EMAIL
)
# Notify both old and new emails of the change
send_mail
(
subject
,
message
,
from_address
,
[
old_email
,
new_email
])
return
render_to_response
(
'student_account/email_change_successful.html'
,
{
'disable_courseware_js'
:
True
,
}
)
@require_http_methods
([
'POST'
])
def
password_change_request_handler
(
request
):
"""Handle password change requests originating from the account page.
...
...
lms/envs/common.py
View file @
99e85556
...
...
@@ -313,9 +313,6 @@ FEATURES = {
# ENABLE_OAUTH2_PROVIDER to True
'ENABLE_MOBILE_REST_API'
:
False
,
# Enable the new dashboard, account, and profile pages
'ENABLE_NEW_DASHBOARD'
:
False
,
# Enable the combined login/registration form
'ENABLE_COMBINED_LOGIN_REGISTRATION'
:
False
,
...
...
lms/templates/student_account/email_change_failed.html
deleted
100644 → 0
View file @
820b0118
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%
inherit
file=
"../main.html"
/>
<section
class=
"container activation"
>
<section
class=
"message"
>
<h1
class=
"invalid"
>
${_("Email change failed.")}
</h1>
<hr
class=
"horizontal-divider"
>
<p>
% if error is 'key_invalid' or error is 'internal':
${_("Something went wrong. Please contact {support} for help.").format(
support="
<a
href=
'mailto:{support_email}'
>
{support_email}
</a>
".format(
support_email=settings.TECH_SUPPORT_EMAIL
)
)}
% elif error is 'email_used':
${_("The email address you wanted to use is already used by another "
"{platform_name} account.").format(platform_name=settings.PLATFORM_NAME)}
% endif
</p>
<p>
${_("You can try again from the {link_start}account settings{link_end} page.").format(
link_start="
<a
href=
'{url}'
>
".format(url=reverse('account_index')),
link_end="
</a>
"
)}
</p>
</section>
</section>
lms/templates/student_account/email_change_successful.html
deleted
100644 → 0
View file @
820b0118
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%
inherit
file=
"../main.html"
/>
<section
class=
"container activation"
>
<section
class=
"message"
>
<h1
class=
"valid"
>
${_("Email change successful!")}
</h1>
<hr
class=
"horizontal-divider"
>
<p>
${_("You should see your new email address listed on the "
"{link_start}account settings{link_end} page.").format(
link_start="
<a
href=
'{url}'
>
".format(url=reverse('account_index')),
link_end="
</a>
",
)}
</p>
</section>
</section>
lms/templates/student_account/emails/email_change_confirmation/message_body.txt
deleted
100644 → 0
View file @
820b0118
<%! from django.utils.translation import ugettext as _ %>
## TODO: Get sign-off from Product on new copy, and think about
## turning this into a large, multi-line message for i18n purposes.
## Greeting
${_("Hi there,")}
## Preamble
${_("You successfully changed the email address associated with your "
"{platform_name} account from {old_email} to {new_email}.").format(
platform_name=settings.PLATFORM_NAME,
old_email=old_email,
new_email=new_email
)
}
## Translators: This is the signature of an email. "\n" is a newline character,
## and should be placed between the closing word and the signing team's name.
${_("Thanks,\n - The {platform_name} Team").format(
platform_name=settings.PLATFORM_NAME,
)}
lms/templates/student_account/emails/email_change_confirmation/subject_line.txt
deleted
100644 → 0
View file @
820b0118
<%! from django.utils.translation import ugettext as _ %>
${_("{platform_name} Email Change Successful").format(platform_name=settings.PLATFORM_NAME)}
lms/templates/student_account/emails/email_change_request/message_body.txt
deleted
100644 → 0
View file @
820b0118
<%! from django.utils.translation import ugettext as _ %>
## TODO: Get sign-off from Product on new copy, and think about
## turning this into a large, multi-line message for i18n purposes.
## Greeting
${_("Hi there,")}
## Preamble
${_("There was recently a request to change the email address associated "
"with your {platform_name} account from {old_email} to {new_email}. "
"If you requested this change, please confirm your new email address "
"by following the link below:").format(
platform_name=settings.PLATFORM_NAME,
old_email=old_email,
new_email=new_email
)
}
## Confirmation link
% if is_secure:
https://${site}/account/email/confirmation/${key}
% else:
http://${site}/account/email/confirmation/${key}
% endif
## Closing
${_("If you don't want to change the email address associated with your "
"account, ignore this message.")}
## Translators: This is the signature of an email. "\n" is a newline character,
## and should be placed between the closing word and the signing team's name.
${_("Thanks,\n - The {platform_name} Team").format(
platform_name=settings.PLATFORM_NAME,
)}
lms/templates/student_account/emails/email_change_request/subject_line.txt
deleted
100644 → 0
View file @
820b0118
<%! from django.utils.translation import ugettext as _ %>
${_("{platform_name} Email Change Request").format(platform_name=settings.PLATFORM_NAME)}
lms/templates/student_account/index.html
deleted
100644 → 0
View file @
820b0118
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
<
%
namespace
name=
'static'
file=
'/static_content.html'
/>
<
%
inherit
file=
"../main.html"
/>
<
%
block
name=
"pagetitle"
>
${_("Student Account")}
</
%
block>
<
%
block
name=
"js_extra"
>
<script
type=
"text/javascript"
src=
"${static.url('js/vendor/underscore-min.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/vendor/backbone-min.js')}"
></script>
<
%
static:js
group=
'student_account'
/>
</
%
block>
<
%
block
name=
"header_extras"
>
% for template_name in ["account"]:
<script
type=
"text/template"
id=
"${template_name}-tpl"
>
<%
static
:
include
path
=
"student_account/${template_name}.underscore"
/>
</script>
% endfor
</
%
block>
<h1>
Student Account
</h1>
<p>
This is a placeholder for the student's account page.
</p>
<div
id=
"account-container"
></div>
openedx/core/djangoapps/user_api/api/account.py
View file @
99e85556
...
...
@@ -45,11 +45,6 @@ class AccountUsernameAlreadyExists(AccountUserAlreadyExists):
pass
class
AccountEmailAlreadyExists
(
AccountUserAlreadyExists
):
"""An account already exists with the requested email. """
pass
class
AccountUsernameInvalid
(
AccountRequestError
):
"""The requested username is not in a valid format. """
pass
...
...
@@ -216,122 +211,6 @@ def activate_account(activation_key):
# This implicitly saves the registration
registration
.
activate
()
@intercept_errors
(
AccountInternalError
,
ignore_errors
=
[
AccountRequestError
])
def
request_email_change
(
username
,
new_email
,
password
):
"""Request an email change.
Users must confirm the change before we update their information.
Args:
username (unicode): The username associated with the account.
new_email (unicode): The user's new email address.
password (unicode): The password the user entered to authorize the change.
Returns:
unicode: an activation key for the account.
Raises:
AccountUserNotFound
AccountEmailAlreadyExists
AccountEmailInvalid
AccountNotAuthorized
"""
try
:
user
=
User
.
objects
.
get
(
username
=
username
)
except
User
.
DoesNotExist
:
raise
AccountUserNotFound
# Check the user's credentials
if
not
user
.
check_password
(
password
):
raise
AccountNotAuthorized
# Validate the email, raising an exception if it is not in the correct format
_validate_email
(
new_email
)
# Verify that no active account has taken the email in between
# the request and the activation.
# We'll check again before confirming and persisting the change,
# but if the email is already taken by an active account, we should
# let the user know as soon as possible.
if
User
.
objects
.
filter
(
email
=
new_email
,
is_active
=
True
)
.
exists
():
raise
AccountEmailAlreadyExists
try
:
pending_change
=
PendingEmailChange
.
objects
.
get
(
user
=
user
)
except
PendingEmailChange
.
DoesNotExist
:
pending_change
=
PendingEmailChange
(
user
=
user
)
# Update the change (re-using the same record if it already exists)
# This will generate a new activation key and save the record.
return
pending_change
.
request_change
(
new_email
)
@intercept_errors
(
AccountInternalError
,
ignore_errors
=
[
AccountRequestError
])
@transaction.commit_on_success
def
confirm_email_change
(
activation_key
):
"""Confirm an email change.
Users can confirm the change by providing an activation key
they received via email.
Args:
activation_key (unicode): The activation key the user received
when he/she requested the email change.
Returns:
Tuple: (old_email, new_email)
Raises:
AccountNotAuthorized: The activation code is invalid.
AccountEmailAlreadyExists: Someone else has already taken the email address.
AccountInternalError
"""
try
:
# Activation key has a uniqueness constraint, so we're guaranteed to get
# at most one pending change.
pending_change
=
PendingEmailChange
.
objects
.
select_related
(
'user'
)
.
get
(
activation_key
=
activation_key
)
except
PendingEmailChange
.
DoesNotExist
:
# If there are no changes, then the activation key is invalid
raise
AccountNotAuthorized
else
:
old_email
=
pending_change
.
user
.
email
new_email
=
pending_change
.
new_email
# Verify that no one else has taken the email in between
# the request and the activation.
# In our production database, email has a uniqueness constraint,
# so there is no danger of a race condition here.
if
User
.
objects
.
filter
(
email
=
new_email
)
.
exists
():
raise
AccountEmailAlreadyExists
# Update the email history (in the user profile)
try
:
profile
=
UserProfile
.
objects
.
get
(
user
=
pending_change
.
user
)
except
UserProfile
.
DoesNotExist
:
raise
AccountInternalError
(
"No profile exists for the user '{username}'"
.
format
(
username
=
pending_change
.
user
.
username
)
)
else
:
profile
.
update_email
(
new_email
)
# Delete the pending change, so that the activation code
# will be single-use
pending_change
.
delete
()
# Return the old and new email
# This allows the caller of the function to notify users at both
# the new and old email, which is necessary for security reasons.
return
(
old_email
,
new_email
)
@intercept_errors
(
AccountInternalError
,
ignore_errors
=
[
AccountRequestError
])
def
request_password_change
(
email
,
orig_host
,
is_secure
):
"""Email a single-use link for performing a password reset.
...
...
openedx/core/djangoapps/user_api/tests/test_account_api.py
View file @
99e85556
...
...
@@ -76,40 +76,6 @@ class AccountApiTest(TestCase):
account
=
account_api
.
account_info
(
self
.
USERNAME
)
self
.
assertTrue
(
account
[
'is_active'
])
def
test_change_email
(
self
):
# Request an email change
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
u'new+email@example.com'
,
self
.
PASSWORD
)
# Verify that the email has not yet changed
account
=
account_api
.
account_info
(
self
.
USERNAME
)
self
.
assertEqual
(
account
[
'email'
],
self
.
EMAIL
)
# Confirm the change, using the activation code
old_email
,
new_email
=
account_api
.
confirm_email_change
(
activation_key
)
self
.
assertEqual
(
old_email
,
self
.
EMAIL
)
self
.
assertEqual
(
new_email
,
u'new+email@example.com'
)
# Verify that the email is changed
account
=
account_api
.
account_info
(
self
.
USERNAME
)
self
.
assertEqual
(
account
[
'email'
],
u'new+email@example.com'
)
def
test_confirm_email_change_repeat
(
self
):
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
u'new+email@example.com'
,
self
.
PASSWORD
)
# Confirm the change once
account_api
.
confirm_email_change
(
activation_key
)
# Confirm the change again. The activation code should be
# single-use, so this should raise an error.
with
self
.
assertRaises
(
account_api
.
AccountNotAuthorized
):
account_api
.
confirm_email_change
(
activation_key
)
def
test_create_account_duplicate_username
(
self
):
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
with
self
.
assertRaises
(
account_api
.
AccountUserAlreadyExists
):
...
...
@@ -155,125 +121,6 @@ class AccountApiTest(TestCase):
def
test_activate_account_invalid_key
(
self
):
account_api
.
activate_account
(
u'invalid'
)
@raises
(
account_api
.
AccountUserNotFound
)
def
test_request_email_change_no_user
(
self
):
account_api
.
request_email_change
(
u'no_such_user'
,
self
.
EMAIL
,
self
.
PASSWORD
)
@ddt.data
(
*
INVALID_EMAILS
)
def
test_request_email_change_invalid_email
(
self
,
invalid_email
):
# Create an account with a valid email address
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
# Attempt to change the account to an invalid email
with
self
.
assertRaises
(
account_api
.
AccountEmailInvalid
):
account_api
.
request_email_change
(
self
.
USERNAME
,
invalid_email
,
self
.
PASSWORD
)
def
test_request_email_change_already_exists
(
self
):
# Create two accounts, both activated
activation_key
=
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
account_api
.
activate_account
(
activation_key
)
activation_key
=
account_api
.
create_account
(
u'another_user'
,
u'password'
,
u'another+user@example.com'
)
account_api
.
activate_account
(
activation_key
)
# Try to change the first user's email to the same as the second user's
with
self
.
assertRaises
(
account_api
.
AccountEmailAlreadyExists
):
account_api
.
request_email_change
(
self
.
USERNAME
,
u'another+user@example.com'
,
self
.
PASSWORD
)
def
test_request_email_change_duplicates_unactivated_account
(
self
):
# Create two accounts, but the second account is inactive
activation_key
=
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
account_api
.
activate_account
(
activation_key
)
account_api
.
create_account
(
u'another_user'
,
u'password'
,
u'another+user@example.com'
)
# Try to change the first user's email to the same as the second user's
# Since the second user has not yet activated, this should succeed.
account_api
.
request_email_change
(
self
.
USERNAME
,
u'another+user@example.com'
,
self
.
PASSWORD
)
def
test_request_email_change_same_address
(
self
):
# Create and activate the account
activation_key
=
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
account_api
.
activate_account
(
activation_key
)
# Try to change the email address to the current address
with
self
.
assertRaises
(
account_api
.
AccountEmailAlreadyExists
):
account_api
.
request_email_change
(
self
.
USERNAME
,
self
.
EMAIL
,
self
.
PASSWORD
)
def
test_request_email_change_wrong_password
(
self
):
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
# Use the wrong password
with
self
.
assertRaises
(
account_api
.
AccountNotAuthorized
):
account_api
.
request_email_change
(
self
.
USERNAME
,
u'new+email@example.com'
,
u'wrong password'
)
def
test_confirm_email_change_invalid_activation_key
(
self
):
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
account_api
.
request_email_change
(
self
.
USERNAME
,
u'new+email@example.com'
,
self
.
PASSWORD
)
with
self
.
assertRaises
(
account_api
.
AccountNotAuthorized
):
account_api
.
confirm_email_change
(
u'invalid'
)
def
test_confirm_email_change_no_request_pending
(
self
):
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
def
test_confirm_email_already_exists
(
self
):
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
# Request a change
activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
u'new+email@example.com'
,
self
.
PASSWORD
)
# Another use takes the email before we confirm the change
account_api
.
create_account
(
u'other_user'
,
u'password'
,
u'new+email@example.com'
)
# When we try to confirm our change, we get an error because the email is taken
with
self
.
assertRaises
(
account_api
.
AccountEmailAlreadyExists
):
account_api
.
confirm_email_change
(
activation_key
)
# Verify that the email was NOT changed
self
.
assertEqual
(
account_api
.
account_info
(
self
.
USERNAME
)[
'email'
],
self
.
EMAIL
)
def
test_confirm_email_no_user_profile
(
self
):
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
u'new+email@example.com'
,
self
.
PASSWORD
)
# This should never happen, but just in case...
UserProfile
.
objects
.
get
(
user__username
=
self
.
USERNAME
)
.
delete
()
with
self
.
assertRaises
(
account_api
.
AccountInternalError
):
account_api
.
confirm_email_change
(
activation_key
)
def
test_record_email_change_history
(
self
):
account_api
.
create_account
(
self
.
USERNAME
,
self
.
PASSWORD
,
self
.
EMAIL
)
# Change the email once
activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
u'new+email@example.com'
,
self
.
PASSWORD
)
account_api
.
confirm_email_change
(
activation_key
)
# Verify that the old email appears in the history
meta
=
UserProfile
.
objects
.
get
(
user__username
=
self
.
USERNAME
)
.
get_meta
()
self
.
assertEqual
(
len
(
meta
[
'old_emails'
]),
1
)
email
,
timestamp
=
meta
[
'old_emails'
][
0
]
self
.
assertEqual
(
email
,
self
.
EMAIL
)
self
.
_assert_is_datetime
(
timestamp
)
# Change the email again
activation_key
=
account_api
.
request_email_change
(
self
.
USERNAME
,
u'another_new+email@example.com'
,
self
.
PASSWORD
)
account_api
.
confirm_email_change
(
activation_key
)
# Verify that both emails appear in the history
meta
=
UserProfile
.
objects
.
get
(
user__username
=
self
.
USERNAME
)
.
get_meta
()
self
.
assertEqual
(
len
(
meta
[
'old_emails'
]),
2
)
email
,
timestamp
=
meta
[
'old_emails'
][
1
]
self
.
assertEqual
(
email
,
'new+email@example.com'
)
self
.
_assert_is_datetime
(
timestamp
)
@skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in LMS'
)
def
test_request_password_change
(
self
):
# Create and activate an account
...
...
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