8000 Allow auth providers to influence is_active by balloob · Pull Request #15557 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Allow auth providers to influence is_active #15557

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions homeassistant/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ async def async_get_or_create_user(self, credentials):
return await self._store.async_create_user(
credentials=credentials,
name=info.get('name'),
is_active=info.get('is_active', False)
)

async def async_link_user(self, user, credentials):
Expand Down
4 changes: 4 additions & 0 deletions homeassistant/auth/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,9 @@ async def async_user_meta_for_credentials(self, credentials):
"""Return extra user metadata for credentials.

Will be used to populate info when creating a new user.

Values to populate:
- name: string
- is_active: boolean
"""
return {}
3 changes: 2 additions & 1 deletion homeassistant/auth/providers/homeassistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ async def async_get_or_create_credentials(self, flow_result):
async def async_user_meta_for_credentials(self, credentials):
"""Get extra info for this credential."""
return {
'name': credentials.data['username']
'name': credentials.data['username'],
'is_active': True,
}

async def async_will_remove_credentials(self, credentials):
Expand Down
10 changes: 6 additions & 4 deletions homeassistant/auth/providers/insecure_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,16 @@ async def async_user_meta_for_credentials(self, credentials):
Will be used to populate info when creating a new user.
"""
username = credentials.data['username']
info = {
'is_active': True,
}

for user in self.config['users']:
if user['username'] == username:
return {
'name': user.get('name')
}
info['name'] = user.get('name')
break

return {}
return info


class LoginFlow(data_entry_flow.FlowHandler):
Expand Down
5 changes: 4 additions & 1 deletion homeassistant/auth/providers/legacy_api_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ async def async_user_meta_for_credentials(self, credentials):

Will be used to populate info when creating a new user.
"""
return {'name': LEGACY_USER}
return {
'name': LEGACY_USER,
'is_active': True,
}


class LoginFlow(data_entry_flow.FlowHandler):
Expand Down
9 changes: 1 addition & 8 deletions homeassistant/scripts/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,9 @@ async def add_user(hass, provider, args):
print("Username already exists!")
return

credentials = await provider.async_get_or_create_credentials({
'username': args.username
})

user = await hass.auth.async_create_user(args.username)
await hass.auth.async_link_user(user, credentials)

# Save username/password
await provider.data.async_save()
print("User created")
print("Auth created")


async def validate_login(hass, provider, args):
Expand Down
18 changes: 18 additions & 0 deletions tests/auth/providers/test_homeassistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest

from homeassistant import data_entry_flow
from homeassistant.auth import auth_manager_from_config
from homeassistant.auth.providers import (
auth_provider_from_config, homeassistant as hass_auth)

Expand Down Expand Up @@ -112,3 +113,20 @@ async def test_not_allow_set_id():
'id': 'invalid',
})
assert provider is None


async def test_new_users_populate_values(hass, data):
"""Test that we populate data for new users."""
data.add_auth('hello', 'test-pass')
await data.async_save()

manager = await auth_manager_from_config(hass, [{
'type': 'homeassistant'
}])
provider = manager.auth_providers[0]
credentials = await provider.async_get_or_create_credentials({
'username': 'hello'
})
user = await manager.async_get_or_create_user(credentials)
assert user.name == 'hello'
assert user.is_active
17 changes: 15 additions & 2 deletions tests/auth/providers/test_insecure_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest

from homeassistant.auth import auth_store, models as auth_models
from homeassistant.auth import auth_store, models as auth_models, AuthManager
from homeassistant.auth.providers import insecure_example

from tests.common import mock_coro
Expand All @@ -23,6 +23,7 @@ def provider(hass, store):
'type': 'insecure_example',
'users': [
{
'name': 'Test Name',
'username': 'user-test',
'password': 'password-test',
},
Expand All @@ -34,14 +35,26 @@ def provider(hass, store):
})


async def test_create_new_credential(provider):
@pytest.fixture
def manager(hass, store, provider):
"""Mock manager."""
return AuthManager(hass, store, {
(provider.type, provider.id): provider
})


async def test_create_new_credential(manager, provider):
"""Test that we create a new credential."""
credentials = await provider.async_get_or_create_credentials({
'username': 'user-test',
'password': 'password-test',
})
assert credentials.is_new is True

user = await manager.async_get_or_create_user(credentials)
assert user.name == 'Test Name'
assert user.is_active


async def test_match_existing_credentials(store, provider):
"""See if we match existing users."""
Expand Down
6 changes: 5 additions & 1 deletion tests/auth/providers/test_legacy_api_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ def manager(hass, store, provider):
})


async def test_create_new_credential(provider):
async def test_create_new_credential(manager, provider):
"""Test that we create a new credential."""
credentials = await provider.async_get_or_create_credentials({})
assert credentials.data["username"] is legacy_api_password.LEGACY_USER
assert credentials.is_new is True

user = await manager.async_get_or_create_user(credentials)
assert user.name == legacy_api_password.LEGACY_USER
assert user.is_active


async def test_only_one_credentials(manager, provider):
"""Call create twice will return same credential."""
Expand Down
30 changes: 25 additions & 5 deletions tests/components/auth/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,31 @@ async def test_login_new_user_and_trying_refresh_token(hass, aiohttp_client):
'code': code
})

# User is not active
assert resp.status == 403
data = await resp.json()
assert data['error'] == 'access_denied'
assert data['error_description'] == 'User is not active'
assert resp.status == 200
tokens = await resp.json()

assert hass.auth.async_get_access_token(tokens['access_token']) is not None

# Use refresh token to get more tokens.
resp = await client.post('/auth/token', data={
'client_id': CLIENT_ID,
'grant_type': 'refresh_token',
'refresh_token': tokens['refresh_token']
})

assert resp.status == 200
tokens = await resp.json()
assert 'refresh_token' not in tokens
assert hass.auth.async_get_access_token(tokens['access_token']) is not None

# Test using access token to hit API.
resp = await client.get('/api/')
assert resp.status == 401

resp = await client.get('/api/', headers={
'authorization': 'Bearer {}'.format(tokens['access_token'])
})
assert resp.status == 200


def test_credential_store_expiration():
Expand Down
2 changes: 1 addition & 1 deletion tests/scripts/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async def test_add_user(hass, provider, capsys, hass_storage):
assert len(hass_storage[hass_auth.STORAGE_KEY]['data']['users']) == 1

captured = capsys.readouterr()
assert captured.out == 'User created\n'
assert captured.out == 'Auth created\n'

assert len(data.users) == 1
data.validate_login('paulus', 'test-pass')
Expand Down
0