0002-csv_import-allow-setting-user-password-and-sending-m.patch
src/authentic2/csv_import.py | ||
---|---|---|
18 | 18 | |
19 | 19 |
import csv |
20 | 20 |
import io |
21 |
import uuid |
|
21 | 22 | |
22 | 23 |
from chardet.universaldetector import UniversalDetector |
23 | 24 |
import attr |
... | ... | |
37 | 38 |
from authentic2.custom_user.models import User |
38 | 39 |
from authentic2.forms.profile import modelform_factory, BaseUserForm |
39 | 40 |
from authentic2.models import Attribute, AttributeValue, UserExternalId |
41 |
from authentic2.utils import send_password_reset_mail |
|
40 | 42 | |
41 | 43 |
Role = get_role_model() |
42 | 44 | |
... | ... | |
197 | 199 |
SOURCE_COLUMNS = set([SOURCE_NAME, SOURCE_ID]) |
198 | 200 |
ROLE_NAME = '_role_name' |
199 | 201 |
ROLE_SLUG = '_role_slug' |
200 |
SPECIAL_COLUMNS = SOURCE_COLUMNS | {ROLE_NAME, ROLE_SLUG} |
|
202 |
REGISTRATION = '@registration' |
|
203 |
REGISTRATION_EMAIL = 'send-email' |
|
204 |
REGISTRATION_RANDOM_PASSWORD = 'set-random-password' |
|
205 |
SPECIAL_COLUMNS = SOURCE_COLUMNS | {ROLE_NAME, ROLE_SLUG, REGISTRATION} |
|
201 | 206 | |
202 | 207 | |
203 | 208 |
class ImportUserForm(BaseUserForm): |
... | ... | |
207 | 212 |
locals()[ROLE_SLUG] = forms.CharField( |
208 | 213 |
label=_('Role slug'), |
209 | 214 |
required=False) |
215 |
choices = [ |
|
216 |
(REGISTRATION_EMAIL, _('Send registration email with password')), |
|
217 |
(REGISTRATION_RANDOM_PASSWORD, _('Set random password')), |
|
218 |
] |
|
219 |
locals()[REGISTRATION] = forms.ChoiceField( |
|
220 |
choices, |
|
221 |
label=_('Registration option'), |
|
222 |
required=False) |
|
210 | 223 | |
211 | 224 |
def clean(self): |
212 | 225 |
super(BaseUserForm, self).clean() |
... | ... | |
639 | 652 |
continue |
640 | 653 |
if cell.header.name in {ROLE_NAME, ROLE_SLUG}: |
641 | 654 |
success &= self.add_role(cell, user, do_clear=True) |
655 |
elif cell.header.name == REGISTRATION and row.action == 'create': |
|
656 |
success &= self.registration_option(cell, user) |
|
642 | 657 | |
643 | 658 |
setattr(self, row.action + 'd', getattr(self, row.action + 'd') + 1) |
644 | 659 |
return success |
... | ... | |
664 | 679 |
user.roles.add(role) |
665 | 680 |
cell.action = 'updated' |
666 | 681 |
return True |
682 | ||
683 |
def registration_option(self, cell, user): |
|
684 |
if cell.value == REGISTRATION_EMAIL: |
|
685 |
send_password_reset_mail( |
|
686 |
user, |
|
687 |
template_names=['authentic2/manager/user_create_registration_email', |
|
688 |
'authentic2/password_reset'], |
|
689 |
next_url='/accounts/', |
|
690 |
context={ |
|
691 |
'user': user, |
|
692 |
}) |
|
693 |
elif cell.value == REGISTRATION_RANDOM_PASSWORD: |
|
694 |
user.set_password(uuid.uuid4().hex) |
|
695 |
user.save() |
|
696 |
return True |
tests/test_csv_import.py | ||
---|---|---|
21 | 21 | |
22 | 22 |
import io |
23 | 23 | |
24 |
from django.core import mail |
|
25 | ||
24 | 26 |
from django_rbac.utils import get_role_model |
25 | 27 | |
26 | 28 |
from authentic2.custom_user.models import User |
... | ... | |
476 | 478 |
assert not importer.run() |
477 | 479 |
assert importer.has_errors |
478 | 480 |
assert importer.errors[0].code == 'invalid-role-column' |
481 | ||
482 | ||
483 |
def test_csv_registration_options(profile, user_csv_importer_factory): |
|
484 |
content = '''email key,first_name,last_name,@registration |
|
485 |
tnoel@entrouvert.com,Thomas,Noël,''' |
|
486 | ||
487 |
importer = user_csv_importer_factory(content + 'set-random-password') |
|
488 |
assert importer.run() |
|
489 |
thomas = User.objects.get(email='tnoel@entrouvert.com') |
|
490 |
assert thomas.password |
|
491 | ||
492 |
password = thomas.password |
|
493 |
importer = user_csv_importer_factory(content + 'set-random-password') |
|
494 |
assert importer.run() |
|
495 |
assert thomas.password == password |
|
496 | ||
497 |
thomas.delete() |
|
498 |
assert not mail.outbox |
|
499 |
importer = user_csv_importer_factory(content + 'send-email') |
|
500 |
assert importer.run() |
|
501 |
assert thomas.password |
|
502 |
assert len(mail.outbox) == 1 |
|
503 | ||
504 |
password = thomas.password |
|
505 |
del mail.outbox[0] |
|
506 |
importer = user_csv_importer_factory(content + 'send-email') |
|
507 |
assert importer.run() |
|
508 |
assert thomas.password == password |
|
509 |
assert not mail.outbox |
|
510 | ||
511 |
importer = user_csv_importer_factory(content + 'invalid-option') |
|
512 |
assert importer.run() |
|
513 |
assert importer.has_errors |
|
514 |
assert importer.rows[0].cells[-1].errors[0].code == 'data-error' |
|
479 |
- |