Add multi-factor authentication modules#15489
Conversation
tests/scripts/test_auth.py
Outdated
There was a problem hiding this comment.
'tests.common.MockUser' imported but unused
tests/scripts/test_auth.py
Outdated
There was a problem hiding this comment.
'homeassistant.auth.models.Credentials' imported but unused
|
For architecture, if we need to resolve the flow result to credentials, we should just do that. We can't be making things up. Maybe we need a config flow that wraps the provider config flow instead of using inheritance. That way we can forward calls and then intercept the call to async_create_entry. But that too is a complicated solution. We should focus on the rest of the auth system before picking this up again. |
|
Sure, I am going to finish change user.mfa_modules design tomorrow, then I will put this PR on the shelf for a while.
|
|
I was thinking about that comment, and with credentials we do the exact opposite. We store the data that connects a user to an auth provider in the user. We should probably do that for MFA too. That way we can ask an MFA module: given this config and this value, is this ok? The only downside is if an MFA module wants to update the data 🤔 |
|
That is current design: in mfa data store: {
"data": {
"users": [
{
"ota_secret": "some_secret",
"user_id": "some_id"
}
]
},
"key": "auth_module.totp",
"version": 1
}In auth "users": [
{
"id": "some_id",
"is_active": true,
"is_owner": true,
"mfa_modules": ["totp"],
"name": null,
"system_generated": false
}
] |
|
I can just delete |
|
Yeah, single source of truth 👍 |
|
Rebase against dev |
homeassistant/auth/__init__.py
Outdated
There was a problem hiding this comment.
We need to add a lot more documentation to this method . What is happening, when and why.
There was a problem hiding this comment.
So I am slightly confused why we are even making changes for this method?
All auth provider login flows will create async_start_mfa(flow_result). The MFA flow will show more forms if necessary and eventually will pass the original flow result on if MFA has passed. That means that this method will not see any new data?
There was a problem hiding this comment.
I changed design, now the auth provider (not the base class) will not know about mfa, they just call async_finish after validate credential. The _async_finish_login_flow will do the heave lift, if need mfa then change the result type to form by calling async_step_select_mfa_module
There was a problem hiding this comment.
Constructors should never have side effects. Add this to auth_mfa_module_from_config
There was a problem hiding this comment.
When would this not be the case?
There was a problem hiding this comment.
For trusted networks auth provider
There was a problem hiding this comment.
Where is async_start_mfa defined?
There was a problem hiding this comment.
I would expect async_start_mfa to not do anything if the context is type=link_user.
There was a problem hiding this comment.
Aha, that is from old design, missed to update document. It should change to
Return await self.async_finish(flow_result) if login init step pass
|
Rebase done, clean it up as much as possible, test should be able to pass, typing still need fix. And this PR is still 900+ lines need review 😄 |
There was a problem hiding this comment.
'..models.User' imported but unused
There was a problem hiding this comment.
'typing.Callable' imported but unused
There was a problem hiding this comment.
'collections.OrderedDict' imported but unused
Description:
Add multi-factor authentication support for new auth system.
Auth module
Multi-factor auth modules has been added to auth/modules folder.
~~totp is Time-based One Time Password module which compatible with Google Authenticator and Authy (not test yet). ~~ will be included in separate PR
insecure_exampleis a Example designed for demo and unit testing purpose, should not be used in any production system.Multi-facot auth module can be used mixed-match with auth providers. After normal auth provider validate, if there are auth modules enabled for the specific user, the login flow will direct to auth module input form. Auth module use separated storage, can be hardening it in future.
Related issue (if applicable): fixes #
Pull request in developers.home-assistant.io with documentation (if applicable): home-assistant/developers.home-assistant#52
Example entry for
configuration.yaml(if applicable):Checklist:
tox. Your PR cannot be merged unless tests passIf user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
REQUIREMENTSvariable (example).requirements_all.txtby runningscript/gen_requirements_all.py.If the code does not interact with devices: