always unlink from all FC accounts (fixes #19947)

This commit is contained in:
Benjamin Dauvergne 2017-11-07 17:33:37 +01:00
parent 612877092c
commit 313824142a
6 changed files with 65 additions and 61 deletions

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: authentic2-auth-fc 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-30 22:51+0100\n"
"POT-Creation-Date: 2017-11-07 17:32+0100\n"
"PO-Revision-Date: 2016-09-14 09:35+0200\n"
"Last-Translator: Benjamin Dauvergne <bdauvergne@entrouvert.com>\n"
"Language-Team: french <fr@li.org>\n"
@ -21,15 +21,15 @@ msgstr ""
msgid "FranceConnect"
msgstr "FranceConnect"
#: authentic2_auth_fc/models.py:25
#: authentic2_auth_fc/models.py:69
msgid "user"
msgstr "utilisateur"
#: authentic2_auth_fc/models.py:28
#: authentic2_auth_fc/models.py:72
msgid "sub"
msgstr "sub"
#: authentic2_auth_fc/models.py:30 authentic2_auth_fc/models.py:31
#: authentic2_auth_fc/models.py:74 authentic2_auth_fc/models.py:75
msgid "access token"
msgstr "jeton d'accès"
@ -43,7 +43,7 @@ msgid "Create your account with FranceConnect"
msgstr "Créez votre compte avec FranceConnect"
#: authentic2_auth_fc/templates/authentic2_auth_fc/connecting.html:18
#: authentic2_auth_fc/templates/authentic2_auth_fc/linking.html:29
#: authentic2_auth_fc/templates/authentic2_auth_fc/linking.html:27
msgid "What is FranceConnect?"
msgstr "Qu'est-ce que FranceConnect ?"
@ -64,32 +64,30 @@ msgstr ""
msgid "Linked FranceConnect accounts"
msgstr "Comptes FranceConnect associés"
#: authentic2_auth_fc/templates/authentic2_auth_fc/linking.html:15
#: authentic2_auth_fc/templates/authentic2_auth_fc/linking.html:14
msgid "Delete link"
msgstr "Supprimer la liaison"
#: authentic2_auth_fc/templates/authentic2_auth_fc/linking.html:22
#: authentic2_auth_fc/templates/authentic2_auth_fc/linking.html:20
msgid "Link with a FranceConnect account"
msgstr "Se lier avec un compte FranceConnect"
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:7
#, python-format
msgid ""
"\n"
" You're about to delete the link between your user account and your "
"FranceConnect account :\n"
" %(fc_account)s.\n"
"FranceConnect account.\n"
" "
msgstr ""
"\n"
"Vous êtes sur le point de supprimer la liaison entre votre compte usager et "
"votre compte FranceConnect : %(fc_account)s."
"votre compte FranceConnect."
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:13
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:12
msgid ""
"\n"
" Delete this link won't delete those accounts. However, once all the "
"links with FranceConnect\n"
" Deleting this link won't delete those accounts. However, once all "
"the links with FranceConnect\n"
" are deleted, it's no more possible to use the FranceConnect to "
"automatically login to your\n"
" user account. It is still possible to link those accounts once again "
@ -104,11 +102,11 @@ msgstr ""
"utilisant FranceConnect. Il sera toujours possible de lier à nouveau ces "
"comptes en utilisant le bouton FranceConnect sur la page de connexion."
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:22
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:21
msgid ""
"\n"
" Your user account has no password and remove this link may make this "
"account inaccessible.\n"
" Your user account has no password and removing this link may make "
"this account inaccessible.\n"
" To avoid this situation, please provide a password.\n"
" "
msgstr ""
@ -117,51 +115,51 @@ msgstr ""
"rendre votre compte usager inaccessible. Pour éviter cela, merci de fournir "
"un mot de passe."
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:31
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:30
msgid "Unlink"
msgstr "Délier"
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:32
#: authentic2_auth_fc/templates/authentic2_auth_fc/unlink.html:31
msgid "Cancel"
msgstr "Annuler"
#: authentic2_auth_fc/views.py:211
#: authentic2_auth_fc/views.py:231
msgid "You refused the connection."
msgstr "Vous avez refusé la connexion."
#: authentic2_auth_fc/views.py:223 authentic2_auth_fc/views.py:232
#: authentic2_auth_fc/views.py:245
#: authentic2_auth_fc/views.py:243 authentic2_auth_fc/views.py:252
#: authentic2_auth_fc/views.py:261 authentic2_auth_fc/views.py:268
#: authentic2_auth_fc/views.py:279
msgid "Unable to connect to FranceConnect."
msgstr "Impossible de se connecter à FranceConnect."
#: authentic2_auth_fc/views.py:300
#: authentic2_auth_fc/views.py:335
msgid "The FranceConnect account {} is already linked with another account."
msgstr "Le compte FranceConnect {} est déjà associé à un autre compte."
#: authentic2_auth_fc/views.py:317
#: authentic2_auth_fc/views.py:353
msgid "Your FranceConnect account {} with email {} has been linked."
msgstr "Votre compte FranceConnect {} avec le courriel {} a été associé."
#: authentic2_auth_fc/views.py:320
#: authentic2_auth_fc/views.py:357
msgid "Your FranceConnect account {} has been linked."
msgstr "Votre compte FranceConnect {} a été associé."
#: authentic2_auth_fc/views.py:326
#: authentic2_auth_fc/views.py:363
msgid "Your local account has been updated."
msgstr "Votre compte local a été mis à jour."
#: authentic2_auth_fc/views.py:341
#: authentic2_auth_fc/views.py:399
msgid ""
"If you already have an account, please log in, else create your account."
msgstr ""
"Si vous avez déjà un compte saisissez vos identifiants sinon créez votre "
"compte."
#: authentic2_auth_fc/views.py:359
#: authentic2_auth_fc/views.py:429
msgid "FranceConnect didn't provide your email address, please do."
msgstr "FranceConnect n'a pas fourni votre adresse email, merci de le faire."
#: authentic2_auth_fc/views.py:420
#, python-brace-format
msgid "The link with the FranceConnect account {fc_account} has been deleted."
msgstr "La liaison avec le compte FranceConnect {fc_account} a été supprimée"
#: authentic2_auth_fc/views.py:478
msgid "The link with the FranceConnect account has been deleted."
msgstr "La liaison avec le compte FranceConnect a été supprimée."

View File

@ -11,9 +11,7 @@
{% trans "Linked FranceConnect accounts" %}
</p>
<ul class="fond">
{% for fc_account in user.fc_accounts.all %}
<li class="picto utilisateur"><p class="lien">{{ fc_account }}{% if unlink %} <a href="{% url 'fc-unlink' pk=fc_account.pk %}">{% trans 'Delete link'%}</a>{% endif %}</p></li>
{% endfor %}
<li class="picto utilisateur"><p class="lien">{{ user.fc_accounts.all.0 }}{% if unlink %} <a href="{% url 'fc-unlink' %}">{% trans 'Delete link'%}</a>{% endif %}</p></li>
</ul>
{% else %}
<p>

View File

@ -5,13 +5,12 @@
{% block content %}
<p>
{% blocktrans %}
You're about to delete the link between your user account and your FranceConnect account :
{{ fc_account }}.
You're about to delete the link between your user account and your FranceConnect account.
{% endblocktrans %}
</p>
<p>
{% blocktrans %}
Delete this link won't delete those accounts. However, once all the links with FranceConnect
Deleting this link won't delete those accounts. However, once all the links with FranceConnect
are deleted, it's no more possible to use the FranceConnect to automatically login to your
user account. It is still possible to link those accounts once again by using the
button FranceConnect on the login page.
@ -20,7 +19,7 @@
{% if no_password %}
<p>
{% blocktrans %}
Your user account has no password and remove this link may make this account inaccessible.
Your user account has no password and removing this link may make this account inaccessible.
To avoid this situation, please provide a password.
{% endblocktrans %}
</p>

View File

@ -10,5 +10,5 @@ fcpatterns = patterns('',
urlpatterns = patterns('',
url(r'^fc/', include(fcpatterns)),
url(r'^accounts/fc/register/$', views.registration, name='fc-registration'),
url(r'^accounts/fc/unlink/(?P<pk>\d+)/$', views.unlink, name='fc-unlink'),
url(r'^accounts/fc/unlink/$', views.unlink, name='fc-unlink'),
)

View File

@ -437,8 +437,7 @@ class RegistrationView(LoggerMixin, View):
return HttpResponseRedirect(activation_url)
class UnlinkView(LoggerMixin, SingleObjectMixin, FormView):
model = models.FcAccount
class UnlinkView(LoggerMixin, FormView):
template_name = 'authentic2_auth_fc/unlink.html'
def get_success_url(self):
@ -449,14 +448,14 @@ class UnlinkView(LoggerMixin, SingleObjectMixin, FormView):
def get_form_class(self):
form_class = Form
if not self.fc_account.user.has_usable_password():
if not self.request.user.has_usable_password():
form_class = SET_PASSWORD_FORM_CLASS
return form_class
def get_form_kwargs(self, **kwargs):
kwargs = super(UnlinkView, self).get_form_kwargs(**kwargs)
if not self.fc_account.user.has_usable_password():
kwargs['user'] = self.fc_account.user
if not self.request.user.has_usable_password():
kwargs['user'] = self.request.user
return kwargs
def dispatch(self, request, *args, **kwargs):
@ -467,30 +466,22 @@ class UnlinkView(LoggerMixin, SingleObjectMixin, FormView):
a2_app_settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD:
# Prevent access to the view.
raise Http404
self.fc_account = self.object = self.get_object()
self.check_access(self.fc_account)
return super(UnlinkView, self).dispatch(request, *args, **kwargs)
def check_access(self, fc_account):
if self.request.user != fc_account.user:
raise PermissionDenied
def form_valid(self, form):
if not self.fc_account.user.has_usable_password():
if not self.request.user.has_usable_password():
form.save()
self.logger.info(u'user %s has set a password', self.fc_account.user)
self.fc_account.user.backend = 'authentic2.backends.models_backend.ModelBackend'
msg_tpl = _('The link with the FranceConnect account {fc_account} has been deleted.')
msg = msg_tpl.format(fc_account=self.fc_account)
self.logger.info(u'user %s unlinked from %s', self.fc_account.user, self.fc_account)
self.fc_account.delete()
messages.info(self.request, msg)
self.logger.info(u'user %s has set a password', self.request.user)
links = models.FcAccount.objects.filter(user=self.request.user)
for link in links:
self.logger.info(u'user %s unlinked from %s', self.request.user, link)
messages.info(self.request, _('The link with the FranceConnect account has been deleted.'))
links.delete()
return super(UnlinkView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(UnlinkView, self).get_context_data(**kwargs)
context['fc_account'] = self.fc_account
if not self.fc_account.user.has_usable_password():
if not self.request.user.has_usable_password():
context['no_password'] = True
return context

View File

@ -13,6 +13,8 @@ from django.utils.timezone import now
from authentic2.utils import timestamp_from_datetime
from authentic2_auth_fc import models
User = get_user_model()
@ -99,6 +101,22 @@ def test_login(app, fc_settings, caplog, exp):
assert User.objects.count() == 0
else:
assert User.objects.count() == 1
if User.objects.count():
# we must be connected
assert app.session['_auth_user_id']
assert models.FcAccount.objects.count() == 1
response = app.get('/accounts/')
response = response.click('Delete link')
response.form.set('new_password1', 'ikKL1234')
response.form.set('new_password2', 'ikKL1234')
response = response.form.submit(name='unlink')
assert 'The link with the FranceConnect account has been deleted' in response.content
assert models.FcAccount.objects.count() == 0
continue_url = response.pyquery('a#a2-continue').attr['href']
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
assert app.session['fc_states'][state]['next'] == '/accounts/'
response = app.get(reverse('fc-logout') + '?state=' + state)
assert response['Location'] == 'http://testserver/accounts/'
def test_login_email_is_unique(app, fc_settings, caplog):