{"action":"opened","issue":{"url":"https://api.github.com/repos/4teamwork/opengever.core/issues/1187","labels_url":"https://api.github.com/repos/4teamwork/opengever.core/issues/1187/labels{/name}","comments_url":"https://api.github.com/repos/4teamwork/opengever.core/issues/1187/comments","events_url":"https://api.github.com/repos/4teamwork/opengever.core/issues/1187/events","html_url":"https://github.com/4teamwork/opengever.core/issues/1187","id":102385223,"number":1187,"title":"Zwei-Faktor-Authentifizierung einbinden","user":{"login":"lukasgraf","id":405124,"avatar_url":"https://avatars.githubusercontent.com/u/405124?v=3","gravatar_id":"","url":"https://api.github.com/users/lukasgraf","html_url":"https://github.com/lukasgraf","followers_url":"https://api.github.com/users/lukasgraf/followers","following_url":"https://api.github.com/users/lukasgraf/following{/other_user}","gists_url":"https://api.github.com/users/lukasgraf/gists{/gist_id}","starred_url":"https://api.github.com/users/lukasgraf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lukasgraf/subscriptions","organizations_url":"https://api.github.com/users/lukasgraf/orgs","repos_url":"https://api.github.com/users/lukasgraf/repos","events_url":"https://api.github.com/users/lukasgraf/events{/privacy}","received_events_url":"https://api.github.com/users/lukasgraf/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-08-21T13:59:03Z","updated_at":"2015-08-21T13:59:03Z","closed_at":null,"body":"Es soll in GEVER Zwei-Faktor-Authentifizierung implementiert werden (vorerst für EDK, siehe [EDK Tracker #3](https://extranet.4teamwork.ch/extern/0338-projekt-installation-onegov-gever-edk/0338-tracker-installation-onegov-gever-edk/3)).\r\n\r\nDazu habe ich [collective.googleauthenticator](https://github.com/collective/collective.googleauthenticator) getestet. Ich denke mit diesem Add-On kann das Grundsätzlich funktionieren, es gibt aber noch vieles zu tun und einige ungelöste Probleme:\r\n\r\n- Nach dem Eingeben von Benutzername und Passwort, aber *vor* dem eingeben des Google-Tokens, ist der Benutzer in Plone bereits authentisiert. `portal_membership.getAuthenticatedMember()` gibt den Benutzer zurück, Permission-Checks sind erfolgreich, etc...\r\n\r\n![verification](https://cloud.githubusercontent.com/assets/405124/9403995/ee971554-47eb-11e5-9b91-3fbf7b9f84cb.png)\r\n\r\nDies ist der Fall weil die `authenticateCredentials()` Methode des PAS Plugin von `collective.googleauthenticator` [`None` zurückgibt](https://github.com/collective/collective.googleauthenticator/blob/master/src/collective/googleauthenticator/pas_plugin.py#L116) für den Fall dass es die Authentisierung übernehmen will und den Redirect auf das Token-Verification Form auslöst.\r\n\r\nPAS interpretiert das dann so, dass dieses Plugin die Credentials nicht authentisieren konnte, und [fragt das nächste in der Liste](https://github.com/zopefoundation/Products.PluggableAuthService/blob/master/Products/PluggableAuthService/PluggableAuthService.py#L654-L655). Dieses wird dann irgendwann das Plugin sein das die Credentials üblicherweise authentisiert, und aus Sicht von PAS ist die Authentisierung damit bereits erfolgreich, und der User ist angemeldet. \r\n\r\nUm dies zu verhindern, denke ich dass `authenticateCredentials()` zu diesem Punkt auf jeden Fall einen Wert zurückgeben muss, der nicht `None` ist. Für diese konkrete Condition würde `(None, None)` reichen, aber dann ist eine [spätere condition](https://github.com/zopefoundation/Products.PluggableAuthService/blob/master/Products/PluggableAuthService/PluggableAuthService.py#L666) nicht erfüllt. `('Anonymous', None)` *scheint* für den Moment den gewünschten Effekt zu haben, ist aber ein Hack der schlicht ein Implementierungsdetail von PAS ausnutzt.\r\n\r\n- Das globale Aktivieren von 2FA funktioniert nicht richtig.\r\nDie Checkbox im Controlpanel-Formular löst beim Speichern aus, dass entweder für alle User die 2FA aktiviert oder deaktiviert wird. Weil aber `plone.api.user.get_users()` keine User eines `LDAPUserFolder`s zurückliefern kann, wird dies in unserem Setup für keinen User aktiviert.\r\n\r\n- Die [Condition `if 'user' in plugid`](https://github.com/collective/collective.googleauthenticator/blob/master/src/collective/googleauthenticator/pas_plugin.py#L87) ist falsch - dies führt dazu dass z.B. der LDAPUserFolder nicht berücksichtigt wird. Stattdessen sollten alle `IAuthenticator` plugins befragt werden, ausser natürlich dass Google Authenticator plugin selbst.\r\n\r\n- Nach dem (manuellen) aktivieren von 2FA durch einen User sollte nicht auf die `@@personal-information` view redirected werden, diese wird bei uns nicht verwendet.\r\n\r\n#### Kleinigkeiten\r\n\r\n- Formular-Buttons im Google Authenticator Control-Panel führen zu `Unsaved changes - leave this page?` Abfrage im Browser und sind nicht richtig übersetzt.\r\n\r\n- Nach erfolgreichem Anmelden wird eine custom status message verwendet statt die Standard-Message von Plone - deshalb ist diese auch nicht übersetzt.\r\n \r\n- Enable 2FA Aktion sollte *oberhalb* von \"Logout\" sein. \"Logout\" sollte m.M.n. immer die unterste Aktion im Menü sein."}}