mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Allow passing in user id instead of username to change password (#39266)
This commit is contained in:
parent
1bc4de2bd3
commit
6348884735
@ -34,29 +34,21 @@ async def websocket_create(hass, connection, msg):
|
|||||||
user = await hass.auth.async_get_user(msg["user_id"])
|
user = await hass.auth.async_get_user(msg["user_id"])
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
connection.send_message(
|
connection.send_error(msg["id"], "not_found", "User not found")
|
||||||
websocket_api.error_message(msg["id"], "not_found", "User not found")
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if user.system_generated:
|
if user.system_generated:
|
||||||
connection.send_message(
|
connection.send_error(
|
||||||
websocket_api.error_message(
|
msg["id"],
|
||||||
msg["id"],
|
"system_generated",
|
||||||
"system_generated",
|
"Cannot add credentials to a system generated user.",
|
||||||
"Cannot add credentials to a system generated user.",
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await provider.async_add_auth(msg["username"], msg["password"])
|
await provider.async_add_auth(msg["username"], msg["password"])
|
||||||
except auth_ha.InvalidUser:
|
except auth_ha.InvalidUser:
|
||||||
connection.send_message(
|
connection.send_error(msg["id"], "username_exists", "Username already exists")
|
||||||
websocket_api.error_message(
|
|
||||||
msg["id"], "username_exists", "Username already exists"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
credentials = await provider.async_get_or_create_credentials(
|
credentials = await provider.async_get_or_create_credentials(
|
||||||
@ -64,7 +56,7 @@ async def websocket_create(hass, connection, msg):
|
|||||||
)
|
)
|
||||||
await hass.auth.async_link_user(user, credentials)
|
await hass.auth.async_link_user(user, credentials)
|
||||||
|
|
||||||
connection.send_message(websocket_api.result_message(msg["id"]))
|
connection.send_result(msg["id"])
|
||||||
|
|
||||||
|
|
||||||
@decorators.websocket_command(
|
@decorators.websocket_command(
|
||||||
@ -87,20 +79,18 @@ async def websocket_delete(hass, connection, msg):
|
|||||||
if not credentials.is_new:
|
if not credentials.is_new:
|
||||||
await hass.auth.async_remove_credentials(credentials)
|
await hass.auth.async_remove_credentials(credentials)
|
||||||
|
|
||||||
connection.send_message(websocket_api.result_message(msg["id"]))
|
connection.send_result(msg["id"])
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await provider.async_remove_auth(msg["username"])
|
await provider.async_remove_auth(msg["username"])
|
||||||
except auth_ha.InvalidUser:
|
except auth_ha.InvalidUser:
|
||||||
connection.send_message(
|
connection.send_error(
|
||||||
websocket_api.error_message(
|
msg["id"], "auth_not_found", "Given username was not found."
|
||||||
msg["id"], "auth_not_found", "Given username was not found."
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
connection.send_message(websocket_api.result_message(msg["id"]))
|
connection.send_result(msg["id"])
|
||||||
|
|
||||||
|
|
||||||
@decorators.websocket_command(
|
@decorators.websocket_command(
|
||||||
@ -115,9 +105,7 @@ async def websocket_change_password(hass, connection, msg):
|
|||||||
"""Change current user password."""
|
"""Change current user password."""
|
||||||
user = connection.user
|
user = connection.user
|
||||||
if user is None:
|
if user is None:
|
||||||
connection.send_message(
|
connection.send_error(msg["id"], "user_not_found", "User not found")
|
||||||
websocket_api.error_message(msg["id"], "user_not_found", "User not found")
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
provider = auth_ha.async_get_provider(hass)
|
provider = auth_ha.async_get_provider(hass)
|
||||||
@ -128,26 +116,20 @@ async def websocket_change_password(hass, connection, msg):
|
|||||||
break
|
break
|
||||||
|
|
||||||
if username is None:
|
if username is None:
|
||||||
connection.send_message(
|
connection.send_error(
|
||||||
websocket_api.error_message(
|
msg["id"], "credentials_not_found", "Credentials not found"
|
||||||
msg["id"], "credentials_not_found", "Credentials not found"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await provider.async_validate_login(username, msg["current_password"])
|
await provider.async_validate_login(username, msg["current_password"])
|
||||||
except auth_ha.InvalidAuth:
|
except auth_ha.InvalidAuth:
|
||||||
connection.send_message(
|
connection.send_error(msg["id"], "invalid_password", "Invalid password")
|
||||||
websocket_api.error_message(
|
|
||||||
msg["id"], "invalid_password", "Invalid password"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
await provider.async_change_password(username, msg["new_password"])
|
await provider.async_change_password(username, msg["new_password"])
|
||||||
|
|
||||||
connection.send_message(websocket_api.result_message(msg["id"]))
|
connection.send_result(msg["id"])
|
||||||
|
|
||||||
|
|
||||||
@decorators.websocket_command(
|
@decorators.websocket_command(
|
||||||
@ -155,7 +137,7 @@ async def websocket_change_password(hass, connection, msg):
|
|||||||
vol.Required(
|
vol.Required(
|
||||||
"type"
|
"type"
|
||||||
): "config/auth_provider/homeassistant/admin_change_password",
|
): "config/auth_provider/homeassistant/admin_change_password",
|
||||||
vol.Required("username"): str,
|
vol.Required("user_id"): str,
|
||||||
vol.Required("password"): str,
|
vol.Required("password"): str,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -166,14 +148,31 @@ async def websocket_admin_change_password(hass, connection, msg):
|
|||||||
if not connection.user.is_owner:
|
if not connection.user.is_owner:
|
||||||
raise Unauthorized(context=connection.context(msg))
|
raise Unauthorized(context=connection.context(msg))
|
||||||
|
|
||||||
|
user = await hass.auth.async_get_user(msg["user_id"])
|
||||||
|
|
||||||
|
if user is None:
|
||||||
|
connection.send_error(msg["id"], "user_not_found", "User not found")
|
||||||
|
return
|
||||||
|
|
||||||
provider = auth_ha.async_get_provider(hass)
|
provider = auth_ha.async_get_provider(hass)
|
||||||
try:
|
|
||||||
await provider.async_change_password(msg["username"], msg["password"])
|
username = None
|
||||||
connection.send_message(websocket_api.result_message(msg["id"]))
|
for credential in user.credentials:
|
||||||
except auth_ha.InvalidUser:
|
if credential.auth_provider_type == provider.type:
|
||||||
connection.send_message(
|
username = credential.data["username"]
|
||||||
websocket_api.error_message(
|
break
|
||||||
msg["id"], "credentials_not_found", "Credentials not found"
|
|
||||||
)
|
if username is None:
|
||||||
|
connection.send_error(
|
||||||
|
msg["id"], "credentials_not_found", "Credentials not found"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
await provider.async_change_password(username, msg["password"])
|
||||||
|
connection.send_result(msg["id"])
|
||||||
|
except auth_ha.InvalidUser:
|
||||||
|
connection.send_error(
|
||||||
|
msg["id"], "credentials_not_found", "Credentials not found"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
@ -323,7 +323,7 @@ async def test_admin_change_password_not_owner(
|
|||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"type": "config/auth_provider/homeassistant/admin_change_password",
|
"type": "config/auth_provider/homeassistant/admin_change_password",
|
||||||
"username": "test-user",
|
"user_id": "test-user",
|
||||||
"password": "new-pass",
|
"password": "new-pass",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -336,15 +336,35 @@ async def test_admin_change_password_not_owner(
|
|||||||
await auth_provider.async_validate_login("test-user", "test-pass")
|
await auth_provider.async_validate_login("test-user", "test-pass")
|
||||||
|
|
||||||
|
|
||||||
async def test_admin_change_password_no_creds(hass, hass_ws_client, owner_access_token):
|
async def test_admin_change_password_no_user(hass, hass_ws_client, owner_access_token):
|
||||||
"""Test that change password fails with unknown credentials."""
|
"""Test that change password fails with unknown user."""
|
||||||
client = await hass_ws_client(hass, owner_access_token)
|
client = await hass_ws_client(hass, owner_access_token)
|
||||||
|
|
||||||
await client.send_json(
|
await client.send_json(
|
||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"type": "config/auth_provider/homeassistant/admin_change_password",
|
"type": "config/auth_provider/homeassistant/admin_change_password",
|
||||||
"username": "non-existing",
|
"user_id": "non-existing",
|
||||||
|
"password": "new-pass",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await client.receive_json()
|
||||||
|
assert not result["success"], result
|
||||||
|
assert result["error"]["code"] == "user_not_found"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_admin_change_password_no_cred(
|
||||||
|
hass, hass_ws_client, owner_access_token, hass_admin_user
|
||||||
|
):
|
||||||
|
"""Test that change password fails with unknown credential."""
|
||||||
|
client = await hass_ws_client(hass, owner_access_token)
|
||||||
|
|
||||||
|
await client.send_json(
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"type": "config/auth_provider/homeassistant/admin_change_password",
|
||||||
|
"user_id": hass_admin_user.id,
|
||||||
"password": "new-pass",
|
"password": "new-pass",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -355,16 +375,23 @@ async def test_admin_change_password_no_creds(hass, hass_ws_client, owner_access
|
|||||||
|
|
||||||
|
|
||||||
async def test_admin_change_password(
|
async def test_admin_change_password(
|
||||||
hass, hass_ws_client, owner_access_token, auth_provider, test_user_credential
|
hass,
|
||||||
|
hass_ws_client,
|
||||||
|
owner_access_token,
|
||||||
|
auth_provider,
|
||||||
|
test_user_credential,
|
||||||
|
hass_admin_user,
|
||||||
):
|
):
|
||||||
"""Test that owners can change any password."""
|
"""Test that owners can change any password."""
|
||||||
|
await hass.auth.async_link_user(hass_admin_user, test_user_credential)
|
||||||
|
|
||||||
client = await hass_ws_client(hass, owner_access_token)
|
client = await hass_ws_client(hass, owner_access_token)
|
||||||
|
|
||||||
await client.send_json(
|
await client.send_json(
|
||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"type": "config/auth_provider/homeassistant/admin_change_password",
|
"type": "config/auth_provider/homeassistant/admin_change_password",
|
||||||
"username": "test-user",
|
"user_id": hass_admin_user.id,
|
||||||
"password": "new-pass",
|
"password": "new-pass",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user