Remove set_password/check_password (supports #3049) (#3662)

This commit is contained in:
Mark Striemer 2016-10-13 12:37:43 -05:00 коммит произвёл GitHub
Родитель db7f226add
Коммит a207265995
30 изменённых файлов: 57 добавлений и 291 удалений

Просмотреть файл

@ -130,7 +130,6 @@ def mozilla_user(admin_group):
user = UserProfile.objects.create(pk=settings.TASK_USER_ID, user = UserProfile.objects.create(pk=settings.TASK_USER_ID,
email='admin@mozilla.com', email='admin@mozilla.com',
username='admin') username='admin')
user.set_password('password')
user.save() user.save()
GroupUser.objects.create(user=user, group=admin_group) GroupUser.objects.create(user=user, group=admin_group)
return user return user

Просмотреть файл

@ -93,11 +93,6 @@ LANGUAGES = lazy(lazy_langs, dict)(AMO_LANGUAGES)
LANGUAGE_URL_MAP = dict([(i.lower(), i) for i in AMO_LANGUAGES]) LANGUAGE_URL_MAP = dict([(i.lower(), i) for i in AMO_LANGUAGES])
TASK_USER_ID = 4043307 TASK_USER_ID = 4043307
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.MD5PasswordHasher',
'olympia.users.models.SHA512PasswordHasher',
)
ES_DEFAULT_NUM_REPLICAS = 0 ES_DEFAULT_NUM_REPLICAS = 0
ES_DEFAULT_NUM_SHARDS = 3 ES_DEFAULT_NUM_SHARDS = 3

Просмотреть файл

@ -190,7 +190,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "", "last_login_attempt_ip": "",
"last_login_attempt": null, "last_login_attempt": null,
"password": "nope", "password": "",
"created": "2010-09-12 07:19:31", "created": "2010-09-12 07:19:31",
"notes": "", "notes": "",
"modified": "2010-09-12 07:34:47", "modified": "2010-09-12 07:34:47",

Просмотреть файл

@ -214,7 +214,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "", "last_login_attempt_ip": "",
"last_login_attempt": null, "last_login_attempt": null,
"password": "nope", "password": "",
"created": "2010-09-12 07:19:31", "created": "2010-09-12 07:19:31",
"notes": "", "notes": "",
"modified": "2010-09-12 07:34:47", "modified": "2010-09-12 07:34:47",
@ -243,7 +243,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "", "last_login_attempt_ip": "",
"last_login_attempt": null, "last_login_attempt": null,
"password": "nope", "password": "",
"created": "2010-09-12 07:19:31", "created": "2010-09-12 07:19:31",
"notes": "", "notes": "",
"modified": "2010-09-12 07:34:47", "modified": "2010-09-12 07:34:47",

Просмотреть файл

@ -122,7 +122,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "", "last_login_attempt_ip": "",
"last_login_attempt": null, "last_login_attempt": null,
"password": "sha512$308d46cdaf22e72f733811461a8ec6f99b6f5ff61f000096f4183009923fecd8$0b7d13e659492aca20eaada963bd2f77152ab83da9bbee750dee1f5b8789059e97a0db57e7ec13840e275932614fad8f805e76cc8411d6c847bcdb6a9e142fb8", "password": "",
"created": "2007-03-05 13:09:37", "created": "2007-03-05 13:09:37",
"notes": null, "notes": null,
"modified": "2010-05-12 16:10:49", "modified": "2010-05-12 16:10:49",

Просмотреть файл

@ -243,7 +243,7 @@
"location": "", "location": "",
"bio": null, "bio": null,
"deleted": false, "deleted": false,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "55021", "username": "55021",
"display_name": "55021 \u0627\u0644\u062a\u0637\u0628", "display_name": "55021 \u0627\u0644\u062a\u0637\u0628",
"created": "2007-03-05 13:09:56", "created": "2007-03-05 13:09:56",

Просмотреть файл

@ -137,7 +137,7 @@
"email": "g@gmail.com", "email": "g@gmail.com",
"location": "", "location": "",
"deleted": false, "deleted": false,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "60582", "username": "60582",
"display_name": "60582 \u0627\u0644\u062a\u0637\u0628", "display_name": "60582 \u0627\u0644\u062a\u0637\u0628",
"notes": null, "notes": null,

Просмотреть файл

@ -38,7 +38,7 @@
"notifycompat": 1, "notifycompat": 1,
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "yermom", "password": "",
"username": "Wink-RU", "username": "Wink-RU",
"display_name": "Wink-RU \u0627\u0644\u062a\u0637\u0628", "display_name": "Wink-RU \u0627\u0644\u062a\u0637\u0628",
"created": "2008-08-29 06:53:46", "created": "2008-08-29 06:53:46",

Просмотреть файл

@ -14,7 +14,7 @@
"notifycompat": 1, "notifycompat": 1,
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "jbalogh", "username": "jbalogh",
"created": "2009-02-02 11:50:31", "created": "2009-02-02 11:50:31",
"notes": "", "notes": "",

Просмотреть файл

@ -12,7 +12,7 @@
"notifycompat": 1, "notifycompat": 1,
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "regularuser", "username": "regularuser",
"display_name": "regularuser \u0627\u0644\u062a\u0637\u0628", "display_name": "regularuser \u0627\u0644\u062a\u0637\u0628",
"created": "2009-02-02 11:50:31", "created": "2009-02-02 11:50:31",

Просмотреть файл

@ -12,7 +12,7 @@
"notifycompat": 1, "notifycompat": 1,
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "regularuser", "username": "regularuser",
"display_name": "regularuser \u0627\u0644\u062a\u0637\u0628", "display_name": "regularuser \u0627\u0644\u062a\u0637\u0628",
"created": "2009-02-02 11:50:31", "created": "2009-02-02 11:50:31",
@ -52,7 +52,7 @@
"location": "Portland, OR", "location": "Portland, OR",
"bio": 379598, "bio": 379598,
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "clouserw", "username": "clouserw",
"display_name": "clouserw \u0627\u0644\u062a\u0637\u0628", "display_name": "clouserw \u0627\u0644\u062a\u0637\u0628",
"created": "2007-03-05 13:09:38", "created": "2007-03-05 13:09:38",
@ -76,7 +76,7 @@
"notifycompat": 1, "notifycompat": 1,
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "admin", "username": "admin",
"display_name": "admin \u0627\u0644\u062a\u0637\u0628", "display_name": "admin \u0627\u0644\u062a\u0637\u0628",
"created": "2009-02-02 11:50:31", "created": "2009-02-02 11:50:31",
@ -102,7 +102,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "127.0.0.1", "last_login_attempt_ip": "127.0.0.1",
"last_login_attempt": "2010-11-16 10:51:34", "last_login_attempt": "2010-11-16 10:51:34",
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"created": "2010-10-19 13:02:25", "created": "2010-10-19 13:02:25",
"modified": "2010-11-16 10:51:34", "modified": "2010-11-16 10:51:34",
"last_login_ip": "127.0.0.1", "last_login_ip": "127.0.0.1",
@ -124,7 +124,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "127.0.0.1", "last_login_attempt_ip": "127.0.0.1",
"last_login_attempt": "2010-11-16 10:51:34", "last_login_attempt": "2010-11-16 10:51:34",
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"created": "2010-10-19 13:02:25", "created": "2010-10-19 13:02:25",
"modified": "2010-11-16 10:51:34", "modified": "2010-11-16 10:51:34",
"last_login_ip": "127.0.0.1", "last_login_ip": "127.0.0.1",
@ -255,7 +255,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "127.0.0.1", "last_login_attempt_ip": "127.0.0.1",
"last_login_attempt": "2012-05-22 14:59:28", "last_login_attempt": "2012-05-22 14:59:28",
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"read_dev_agreement": "2012-08-20 00:00:00", "read_dev_agreement": "2012-08-20 00:00:00",
"created": "2012-01-06 12:31:13", "created": "2012-01-06 12:31:13",
"notes": null, "notes": null,

Просмотреть файл

@ -11,7 +11,6 @@ def test_admin_group(admin_group):
def test_mozilla_user(mozilla_user): def test_mozilla_user(mozilla_user):
assert mozilla_user.check_password('password')
admin_group = mozilla_user.groups.get() admin_group = mozilla_user.groups.get()
assert admin_group.name == 'Admins' assert admin_group.name == 'Admins'
assert admin_group.rules == '*:*' assert admin_group.rules == '*:*'

Просмотреть файл

@ -129,7 +129,7 @@
"location": "", "location": "",
"bio": null, "bio": null,
"deleted": false, "deleted": false,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "55021", "username": "55021",
"display_name": "55021 \u0627\u0644\u062a\u0637\u0628", "display_name": "55021 \u0627\u0644\u062a\u0637\u0628",
"created": "2007-03-05 13:09:56", "created": "2007-03-05 13:09:56",

Просмотреть файл

@ -129,7 +129,7 @@
"location": "", "location": "",
"bio": null, "bio": null,
"deleted": false, "deleted": false,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "55021", "username": "55021",
"display_name": "55021 \u0627\u0644\u062a\u0637\u0628", "display_name": "55021 \u0627\u0644\u062a\u0637\u0628",
"created": "2007-03-05 13:09:56", "created": "2007-03-05 13:09:56",

Просмотреть файл

@ -19,7 +19,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "127.0.0.1", "last_login_attempt_ip": "127.0.0.1",
"last_login_attempt": "2012-05-22 14:59:28", "last_login_attempt": "2012-05-22 14:59:28",
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"read_dev_agreement": "2012-08-20 00:00:00", "read_dev_agreement": "2012-08-20 00:00:00",
"created": "2012-01-06 12:31:13", "created": "2012-01-06 12:31:13",
"notes": null, "notes": null,

Просмотреть файл

@ -19,7 +19,7 @@
"deleted": false, "deleted": false,
"last_login_attempt_ip": "127.0.0.1", "last_login_attempt_ip": "127.0.0.1",
"last_login_attempt": "2012-05-22 14:59:28", "last_login_attempt": "2012-05-22 14:59:28",
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"read_dev_agreement": "2012-08-20 00:00:00", "read_dev_agreement": "2012-08-20 00:00:00",
"created": "2012-01-06 12:31:13", "created": "2012-01-06 12:31:13",
"notes": null, "notes": null,

Просмотреть файл

@ -902,7 +902,6 @@ class TestQueueBasics(QueueTest):
users = [] users = []
for x in range(2): for x in range(2):
user = amo.tests.user_factory() user = amo.tests.user_factory()
user.set_password('password')
user.save() user.save()
users.append(user) users.append(user)
@ -2964,7 +2963,6 @@ class LimitedReviewerBase:
def create_limited_user(self): def create_limited_user(self):
limited_user = UserProfile.objects.create(username='limited', limited_user = UserProfile.objects.create(username='limited',
email="limited@mozilla.com") email="limited@mozilla.com")
limited_user.set_password('password')
limited_user.save() limited_user.save()
permissions = [ permissions = [

Просмотреть файл

@ -38,7 +38,6 @@ class ThemeReviewTestMixin(object):
email = username + '@mozilla.com' email = username + '@mozilla.com'
user = UserProfile.objects.create(email=email, user = UserProfile.objects.create(email=email,
username=username) username=username)
user.set_password('password')
user.save() user.save()
GroupUser.objects.create(group_id=50060, user=user) GroupUser.objects.create(group_id=50060, user=user)

Просмотреть файл

@ -129,10 +129,6 @@ DATABASE_ROUTERS = ('multidb.PinningMasterSlaveRouter',)
# Put the aliases for your slave databases in this list. # Put the aliases for your slave databases in this list.
SLAVE_DATABASES = [] SLAVE_DATABASES = []
PASSWORD_HASHERS = (
'olympia.users.models.SHA512PasswordHasher',
)
# Local time zone for this installation. Choices can be found here: # Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems. # although not all choices may be available on all operating systems.

Просмотреть файл

@ -38,7 +38,7 @@
"notifycompat": true, "notifycompat": true,
"bio": null, "bio": null,
"deleted": false, "deleted": false,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "root_x", "username": "root_x",
"created": "2010-04-21 12:29:12", "created": "2010-04-21 12:29:12",
"notes": null, "notes": null,
@ -94,7 +94,7 @@
"notifycompat": true, "notifycompat": true,
"bio": null, "bio": null,
"deleted": false, "deleted": false,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "Wladimir Palant", "username": "Wladimir Palant",
"created": "2007-03-05 13:09:33", "created": "2007-03-05 13:09:33",
"notes": null, "notes": null,

Просмотреть файл

@ -106,7 +106,7 @@
"deleted": 0, "deleted": 0,
"user": null, "user": null,
"bio": null, "bio": null,
"password": "sha512$280a921ec6e735ec6a1a76dc8802f3f6aee254f3fd71589010fe85ebce185f7a$c797ddde00731d7660b9e0c887d77b373e782eaa949e6101f17ada9a7236c426db53ac4344c133cdf32e73381bb7c7280efe5fdc5dd6134bbd2f706d994f94ff", "password": "",
"username": "Join2", "username": "Join2",
"created": "2009-05-16 05:29:58", "created": "2009-05-16 05:29:58",
"notes": "", "notes": "",

Просмотреть файл

@ -5,7 +5,7 @@
"fields": { "fields": {
"username": "jbalogh", "username": "jbalogh",
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"email": "jbalogh@mozilla.com", "email": "jbalogh@mozilla.com",
"created": "2009-06-02 17:55:23", "created": "2009-06-02 17:55:23",
"modified": "2009-06-02 17:55:23", "modified": "2009-06-02 17:55:23",
@ -18,7 +18,7 @@
"fields": { "fields": {
"username": "nobodyspecial", "username": "nobodyspecial",
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"email": "nobodyspecial@mozilla.com", "email": "nobodyspecial@mozilla.com",
"created": "2009-06-02 17:55:23", "created": "2009-06-02 17:55:23",
"modified": "2009-06-02 17:55:23", "modified": "2009-06-02 17:55:23",

Просмотреть файл

@ -14,7 +14,7 @@
"notifycompat": 1, "notifycompat": 1,
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "jbalogh", "username": "jbalogh",
"display_name": "Jeff Balogh \u0627\u0644\u062a\u0637\u0628", "display_name": "Jeff Balogh \u0627\u0644\u062a\u0637\u0628",
"created": "2009-02-02 11:50:31", "created": "2009-02-02 11:50:31",
@ -42,7 +42,7 @@
"notifycompat": 1, "notifycompat": 1,
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "sha512$32e15df727a054aa56cf69accc142d1573372641a176aab9b0f1458e27dc6f3b$5bd3bd7811569776a07fbbb5e50156aa6ebdd0bec9267249b57da065340f0324190f1ad0d5f609dca19179a86c64807e22f789d118e6f7109c95b9c64ae8f619", "password": "",
"username": "fligtar", "username": "fligtar",
"display_name": "Justin Scott \u0627\u0644\u062a\u0637\u0628", "display_name": "Justin Scott \u0627\u0644\u062a\u0637\u0628",
"created": "2007-03-05 13:09:37", "created": "2007-03-05 13:09:37",
@ -67,7 +67,7 @@
"notifycompat": true, "notifycompat": true,
"bio": null, "bio": null,
"deleted": false, "deleted": false,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "barry", "username": "barry",
"display_name": "barry \u0627\u0644\u062a\u0637\u0628", "display_name": "barry \u0627\u0644\u062a\u0637\u0628",
"created": "2010-07-03 23:03:11", "created": "2010-07-03 23:03:11",
@ -118,7 +118,7 @@
"notifycompat": 1, "notifycompat": 1,
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "sha512$32e15df727a054aa56cf69accc142d1573372641a176aab9b0f1458e27dc6f3b$5bd3bd7811569776a07fbbb5e50156aa6ebdd0bec9267249b57da065340f0324190f1ad0d5f609dca19179a86c64807e22f789d118e6f7109c95b9c64ae8f619", "password": "",
"username": "alice", "username": "alice",
"display_name": "Alice Smith \u0627\u0644\u062a\u0637\u0628", "display_name": "Alice Smith \u0627\u0644\u062a\u0637\u0628",
"created": "2007-03-05 13:09:37", "created": "2007-03-05 13:09:37",

Просмотреть файл

@ -26,8 +26,7 @@ and email address and that's it.
field_name: self.get_value(field_name) field_name: self.get_value(field_name)
for field_name in self.required_fields for field_name in self.required_fields
} }
get_user_model()._default_manager.create_superuser( get_user_model()._default_manager.create_superuser(**user_data)
password=None, **user_data)
def get_value(self, field_name): def get_value(self, field_name):
field = get_user_model()._meta.get_field(field_name) field = get_user_model()._meta.get_field(field_name)

Просмотреть файл

@ -1,25 +1,18 @@
import hashlib
import os import os
import random
import re import re
import string
import time import time
from base64 import decodestring
from contextlib import contextmanager from contextlib import contextmanager
from datetime import datetime from datetime import datetime
from django import dispatch, forms from django import dispatch, forms
from django.conf import settings from django.conf import settings
from django.contrib.auth.hashers import BasePasswordHasher, mask_hash
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.core import validators from django.core import validators
from django.db import models, transaction from django.db import models, transaction
from django.template import Context, loader from django.template import Context, loader
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext as _, get_language, activate from django.utils.translation import ugettext as _, get_language, activate
from django.utils.crypto import constant_time_compare from django.utils.encoding import force_text
from django.utils.datastructures import SortedDict
from django.utils.encoding import force_bytes, force_text
from django.utils.functional import lazy from django.utils.functional import lazy
import caching.base as caching import caching.base as caching
@ -36,61 +29,6 @@ from olympia.translations.query import order_by_translation
log = commonware.log.getLogger('z.users') log = commonware.log.getLogger('z.users')
class SHA512PasswordHasher(BasePasswordHasher):
"""
The SHA2 password hashing algorithm, 512 bits.
"""
algorithm = 'sha512'
def encode(self, password, salt):
assert password is not None
assert salt and '$' not in salt
hash = hashlib.new(self.algorithm,
force_bytes(salt + password)).hexdigest()
return "%s$%s$%s" % (self.algorithm, salt, hash)
def verify(self, password, encoded):
algorithm, salt, hash = encoded.split('$', 2)
assert algorithm == self.algorithm
encoded_2 = self.encode(password, salt)
return constant_time_compare(encoded, encoded_2)
def safe_summary(self, encoded):
algorithm, salt, hash = encoded.split('$', 2)
assert algorithm == self.algorithm
return SortedDict([
(_('algorithm'), algorithm),
(_('salt'), mask_hash(salt, show=2)),
(_('hash'), mask_hash(hash)),
])
def get_hexdigest(algorithm, salt, raw_password):
if 'base64' in algorithm:
# These are getpersonas passwords with base64 encoded salts.
salt = decodestring(salt)
algorithm = algorithm.replace('+base64', '')
if algorithm.startswith('sha512+MD5'):
# These are persona specific passwords when we imported
# users from getpersonas.com. The password is md5 hashed
# and then sha512'd.
md5 = hashlib.new('md5', raw_password).hexdigest()
return hashlib.new('sha512', force_bytes(salt + md5)).hexdigest()
return hashlib.new(algorithm, force_bytes(salt + raw_password)).hexdigest()
def rand_string(length):
return ''.join(random.choice(string.letters) for i in xrange(length))
def create_password(algorithm, raw_password):
salt = get_hexdigest(algorithm, rand_string(12), rand_string(12))[:64]
hsh = get_hexdigest(algorithm, salt, raw_password)
return '$'.join([algorithm, salt, hsh])
class UserForeignKey(models.ForeignKey): class UserForeignKey(models.ForeignKey):
""" """
A replacement for models.ForeignKey('users.UserProfile'). A replacement for models.ForeignKey('users.UserProfile').
@ -138,38 +76,31 @@ class UserEmailField(forms.EmailField):
class UserManager(BaseUserManager, ManagerBase): class UserManager(BaseUserManager, ManagerBase):
def create_user(self, username, email, password=None, fxa_id=None): def create_user(self, username, email, fxa_id=None):
# We'll send username=None when registering through FxA to try and # We'll send username=None when registering through FxA to generate
# generate a username from the email. # an anonymous username.
now = timezone.now() now = timezone.now()
user = self.model( user = self.model(
username=username, email=email, fxa_id=fxa_id, username=username, email=email, fxa_id=fxa_id,
last_login=now) last_login=now)
if username is None: if username is None:
user.anonymize_username() user.anonymize_username()
# FxA won't set a password so don't let a user log in with one. user.set_unusable_password()
if password is None:
user.set_unusable_password()
else:
user.set_password(password)
log.debug('Creating user with email {} and username {}'.format( log.debug('Creating user with email {} and username {}'.format(
email, username)) email, username))
user.save(using=self._db) user.save(using=self._db)
return user return user
def create_superuser(self, username, email, password): def create_superuser(self, username, email):
""" """
Creates and saves a superuser. Creates and saves a superuser.
""" """
user = self.create_user(username, email, password) user = self.create_user(username, email)
admins = Group.objects.get(name='Admins') admins = Group.objects.get(name='Admins')
GroupUser.objects.create(user=user, group=admins) GroupUser.objects.create(user=user, group=admins)
return user return user
AbstractBaseUser._meta.get_field('password').max_length = 255
class UserProfile(OnChangeMixin, ModelBase, AbstractBaseUser): class UserProfile(OnChangeMixin, ModelBase, AbstractBaseUser):
objects = UserManager() objects = UserManager()
USERNAME_FIELD = 'username' USERNAME_FIELD = 'username'
@ -329,16 +260,6 @@ class UserProfile(OnChangeMixin, ModelBase, AbstractBaseUser):
return self.addonuser_set.filter( return self.addonuser_set.filter(
addon__type=amo.ADDON_PERSONA).exists() addon__type=amo.ADDON_PERSONA).exists()
@amo.cached_property
def needs_tougher_password(user):
from olympia.access import acl
return (acl.action_allowed_user(user, 'Admin', '%') or
acl.action_allowed_user(user, 'Addons', 'Edit') or
acl.action_allowed_user(user, 'Addons', 'Review') or
acl.action_allowed_user(user, 'Apps', 'Review') or
acl.action_allowed_user(user, 'Personas', 'Review') or
acl.action_allowed_user(user, 'Users', 'Edit'))
@property @property
def source(self): def source(self):
if not self.pk: if not self.pk:
@ -400,7 +321,7 @@ class UserProfile(OnChangeMixin, ModelBase, AbstractBaseUser):
def anonymize(self): def anonymize(self):
log.info(u"User (%s: <%s>) is being anonymized." % (self, self.email)) log.info(u"User (%s: <%s>) is being anonymized." % (self, self.email))
self.email = None self.email = None
self.password = "sha512$Anonymous$Password" self.set_unusable_password()
self.fxa_id = None self.fxa_id = None
self.username = "Anonymous-%s" % self.id # Can't be null self.username = "Anonymous-%s" % self.id # Can't be null
self.display_name = None self.display_name = None
@ -433,45 +354,11 @@ class UserProfile(OnChangeMixin, ModelBase, AbstractBaseUser):
def set_unusable_password(self): def set_unusable_password(self):
self.password = '' self.password = ''
def has_usable_password(self): def set_password(self, password):
"""Override AbstractBaseUser.has_usable_password.""" raise NotImplementedError('cannot set password')
# We also override the check_password method, and don't rely on
# settings.PASSWORD_HASHERS, and don't use "set_unusable_password", so
# we want to bypass most of AbstractBaseUser.has_usable_password
# checks.
return bool(self.password) # Not None and not empty.
def check_password(self, raw_password): def check_password(self, password):
if not self.has_usable_password(): raise NotImplementedError('cannot check password')
return False
if '$' not in self.password:
valid = (get_hexdigest('md5', '', raw_password) == self.password)
if valid:
# Upgrade an old password.
self.set_password(raw_password)
self.save()
return valid
algo, salt, hsh = self.password.split('$')
# Complication due to getpersonas account migration; we don't
# know if passwords were utf-8 or latin-1 when hashed. If you
# can prove that they are one or the other, you can delete one
# of these branches.
if '+base64' in algo and isinstance(raw_password, unicode):
if hsh == get_hexdigest(algo, salt, raw_password.encode('utf-8')):
return True
else:
try:
return hsh == get_hexdigest(algo, salt,
raw_password.encode('latin1'))
except UnicodeEncodeError:
return False
else:
return hsh == get_hexdigest(algo, salt, raw_password)
def set_password(self, raw_password, algorithm='sha512'):
self.password = create_password(algorithm, raw_password)
def log_login_attempt(self, successful): def log_login_attempt(self, successful):
"""Log a user's login attempt""" """Log a user's login attempt"""

Просмотреть файл

@ -117,12 +117,11 @@ class TestUserEditForm(UserFormBase):
'password': 'longer123', 'password': 'longer123',
'password2': 'longer123', 'password2': 'longer123',
'lang': 'en-US'} 'lang': 'en-US'}
assert self.user.check_password('password') original_password = self.user.password
r = self.client.post(self.url, data, follow=True) r = self.client.post(self.url, data, follow=True)
self.assertContains(r, 'Profile Updated') self.assertContains(r, 'Profile Updated')
self.user.reload() self.user.reload()
assert self.user.check_password('password') assert self.user.password == original_password
assert not self.user.check_password('longer123')
def test_long_data(self): def test_long_data(self):
data = {'username': 'jbalogh', data = {'username': 'jbalogh',

Просмотреть файл

@ -1,17 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import datetime import datetime
import hashlib
from base64 import encodestring
import django # noqa import django # noqa
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.contrib.auth.hashers import (is_password_usable, check_password,
make_password, identify_hasher)
from django.db import models, migrations from django.db import models, migrations
from django.db.migrations.writer import MigrationWriter from django.db.migrations.writer import MigrationWriter
from django.utils import translation from django.utils import translation
from django.utils.encoding import force_bytes
import pytest import pytest
from mock import patch from mock import patch
@ -25,7 +20,7 @@ from olympia.bandwagon.models import Collection, CollectionWatcher
from olympia.reviews.models import Review from olympia.reviews.models import Review
from olympia.translations.models import Translation from olympia.translations.models import Translation
from olympia.users.models import ( from olympia.users.models import (
BlacklistedName, get_hexdigest, UserEmailField, UserProfile, BlacklistedName, UserEmailField, UserProfile,
UserForeignKey) UserForeignKey)
from olympia.users.utils import find_users from olympia.users.utils import find_users
@ -311,111 +306,15 @@ class TestUserProfile(TestCase):
user = UserProfile(fxa_id='db27f8') user = UserProfile(fxa_id='db27f8')
assert user.fxa_migrated() is True assert user.fxa_migrated() is True
def test_cannot_set_password(self):
user = UserProfile.objects.get(id='4043307')
with self.assertRaises(NotImplementedError):
user.set_password('password')
class TestPasswords(TestCase): def test_cannot_check_password(self):
utf = u'\u0627\u0644\u062a\u0637\u0628' user = UserProfile.objects.get(id='4043307')
bytes_ = '\xb1\x98og\x88\x87\x08q' with self.assertRaises(NotImplementedError):
user.check_password('password')
def test_invalid_old_password(self):
u = UserProfile(password=self.utf)
assert u.check_password(self.utf) is False
assert u.has_usable_password() is True
def test_invalid_new_password(self):
u = UserProfile()
u.set_password(self.utf)
assert u.check_password('wrong') is False
assert u.has_usable_password() is True
def test_valid_old_password(self):
hsh = hashlib.md5(force_bytes(self.utf)).hexdigest()
u = UserProfile(password=hsh)
assert u.check_password(self.utf) is True
# Make sure we updated the old password.
algo, salt, hsh = u.password.split('$')
assert algo == 'sha512'
assert hsh == get_hexdigest(algo, salt, self.utf)
assert u.has_usable_password() is True
def test_valid_new_password(self):
u = UserProfile()
u.set_password(self.utf)
assert u.check_password(self.utf) is True
assert u.has_usable_password() is True
def test_persona_sha512_md5(self):
md5 = hashlib.md5('password').hexdigest()
hsh = hashlib.sha512(self.bytes_ + md5).hexdigest()
u = UserProfile(password='sha512+MD5$%s$%s' %
(self.bytes_, hsh))
assert u.check_password('password') is True
assert u.has_usable_password() is True
def test_persona_sha512_base64(self):
hsh = hashlib.sha512(self.bytes_ + 'password').hexdigest()
u = UserProfile(password='sha512+base64$%s$%s' %
(encodestring(self.bytes_), hsh))
assert u.check_password('password') is True
assert u.has_usable_password() is True
def test_persona_sha512_base64_maybe_utf8(self):
hsh = hashlib.sha512(self.bytes_ + self.utf.encode('utf8')).hexdigest()
u = UserProfile(password='sha512+base64$%s$%s' %
(encodestring(self.bytes_), hsh))
assert u.check_password(self.utf) is True
assert u.has_usable_password() is True
def test_persona_sha512_base64_maybe_latin1(self):
passwd = u'fo\xf3'
hsh = hashlib.sha512(self.bytes_ + passwd.encode('latin1')).hexdigest()
u = UserProfile(password='sha512+base64$%s$%s' %
(encodestring(self.bytes_), hsh))
assert u.check_password(passwd) is True
assert u.has_usable_password() is True
def test_persona_sha512_base64_maybe_not_latin1(self):
passwd = u'fo\xf3'
hsh = hashlib.sha512(self.bytes_ + passwd.encode('latin1')).hexdigest()
u = UserProfile(password='sha512+base64$%s$%s' %
(encodestring(self.bytes_), hsh))
assert u.check_password(self.utf) is False
assert u.has_usable_password() is True
def test_persona_sha512_md5_base64(self):
md5 = hashlib.md5('password').hexdigest()
hsh = hashlib.sha512(self.bytes_ + md5).hexdigest()
u = UserProfile(password='sha512+MD5+base64$%s$%s' %
(encodestring(self.bytes_), hsh))
assert u.check_password('password') is True
assert u.has_usable_password() is True
def test_sha512(self):
encoded = make_password('lètmein', 'seasalt', 'sha512')
assert encoded == (
'sha512$seasalt$16bf4502ffdfce9551b90319d06674e6faa3e174144123d'
'392d94470ebf0aa77096b871f9e84f60ed2bac2f10f755368b068e52547e04'
'35fef8b4f6ca237d7d8')
assert is_password_usable(encoded)
assert check_password('lètmein', encoded)
assert not check_password('lètmeinz', encoded)
assert identify_hasher(encoded).algorithm == "sha512"
# Blank passwords
blank_encoded = make_password('', 'seasalt', 'sha512')
assert blank_encoded.startswith('sha512$')
assert is_password_usable(blank_encoded)
assert check_password('', blank_encoded)
assert not check_password(' ', blank_encoded)
def test_empty_password(self):
profile = UserProfile(password=None)
assert profile.has_usable_password() is False
assert not check_password(None, profile.password)
assert not profile.check_password(None)
profile = UserProfile(password='')
assert profile.has_usable_password() is False
assert not check_password('', profile.password)
assert not profile.check_password('')
class TestBlacklistedName(TestCase): class TestBlacklistedName(TestCase):
@ -487,7 +386,6 @@ class TestUserManager(TestCase):
user = UserProfile.objects.create_superuser( user = UserProfile.objects.create_superuser(
"test", "test",
"test@test.com", "test@test.com",
'xxx'
) )
assert user.pk is not None assert user.pk is not None
Group.objects.get(name="Admins") in user.groups.all() Group.objects.get(name="Admins") in user.groups.all()

Просмотреть файл

@ -136,12 +136,11 @@ class TestEdit(UserViewBase):
data['oldpassword'] = 'password' data['oldpassword'] = 'password'
data['password'] = 'longenough' data['password'] = 'longenough'
data['password2'] = 'longenough' data['password2'] = 'longenough'
assert self.user.check_password('password') original_password = self.user.password
res = self.client.post(self.url, data) res = self.client.post(self.url, data)
assert res.status_code == 302 assert res.status_code == 302
self.user.reload() self.user.reload()
assert not self.user.check_password('longenough') assert self.user.password == original_password
assert self.user.check_password('password')
def test_edit_bio(self): def test_edit_bio(self):
assert self.get_profile().bio is None assert self.get_profile().bio is None
@ -290,7 +289,7 @@ class TestEditAdmin(UserViewBase):
data['anonymize'] = True data['anonymize'] = True
res = self.client.post(self.url, data) res = self.client.post(self.url, data)
assert res.status_code == 302 assert res.status_code == 302
assert self.get_user().password == "sha512$Anonymous$Password" assert self.get_user().password == ""
def test_anonymize_fails(self): def test_anonymize_fails(self):
data = self.get_data() data = self.get_data()

Просмотреть файл

@ -14,7 +14,7 @@
"location": "Portland, OR", "location": "Portland, OR",
"bio": null, "bio": null,
"deleted": 0, "deleted": 0,
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600", "password": "",
"username": "Mozilla", "username": "Mozilla",
"display_name": "Mozilla", "display_name": "Mozilla",
"created": "2007-03-05 13:09:38", "created": "2007-03-05 13:09:38",

Просмотреть файл

@ -38,7 +38,6 @@ class Command(BaseCommand):
user_id = '{}-{}'.format(group_id, index) user_id = '{}-{}'.format(group_id, index)
username = 'loadtest-{}'.format(user_id) username = 'loadtest-{}'.format(user_id)
email = '{}@addons.mozilla.org'.format(username) email = '{}@addons.mozilla.org'.format(username)
password = os.urandom(16).encode('hex')
user = UserProfile.objects.create( user = UserProfile.objects.create(
username=username, username=username,
@ -47,10 +46,9 @@ class Command(BaseCommand):
is_verified=True, is_verified=True,
notes='auto-generated for load testing', notes='auto-generated for load testing',
read_dev_agreement=datetime.now()) read_dev_agreement=datetime.now())
user.set_password(password)
user.save() user.save()
user_file.write('{}:{}\n'.format(email, password)) user_file.write('{}:{}\n'.format(email))
print ('Wrote user credentials to {}' print ('Wrote user credentials to {}'
.format(user_file.name.replace(os.getcwd(), '.'))) .format(user_file.name.replace(os.getcwd(), '.')))