Skip to content
Merged

Context #15674

Show file tree
Hide file tree
Changes from 4 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
9 changes: 6 additions & 3 deletions homeassistant/components/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ async def post(self, request, entity_id):
is_new_state = hass.states.get(entity_id) is None

# Write state
hass.states.async_set(entity_id, new_state, attributes, force_update)
hass.states.async_set(entity_id, new_state, attributes, force_update,
self.context(request))

# Read the state back for our response
status_code = HTTP_CREATED if is_new_state else 200
Expand Down Expand Up @@ -279,7 +280,8 @@ async def post(self, request, event_type):
event_data[key] = state

request.app['hass'].bus.async_fire(
event_type, event_data, ha.EventOrigin.remote)
event_type, event_data, ha.EventOrigin.remote,
self.context(request))

return self.json_message("Event {} fired.".format(event_type))

Expand Down Expand Up @@ -316,7 +318,8 @@ async def post(self, request, domain, service):
"Data should be valid JSON.", HTTP_BAD_REQUEST)

with AsyncTrackStates(hass) as changed_states:
await hass.services.async_call(domain, service, data, True)
await hass.services.async_call(
domain, service, data, True, self.context(request))

return self.json(changed_states)

Expand Down
10 changes: 9 additions & 1 deletion homeassistant/components/http/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import homeassistant.remote as rem
from homeassistant.components.http.ban import process_success_login
from homeassistant.core import is_callback
from homeassistant.core import Context, is_callback
from homeassistant.const import CONTENT_TYPE_JSON

from .const import KEY_AUTHENTICATED, KEY_REAL_IP
Expand All @@ -32,6 +32,14 @@ class HomeAssistantView:
cors_allowed = False

# pylint: disable=no-self-use
def context(self, request):
"""Generate a context from a request."""
user = request.get('hass_user')
if user is None:
return Context()

return Context(user_id=user.id)

def json(self, result, status_code=200, headers=None):
"""Return a JSON response."""
try:
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/components/light/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,9 @@ async def async_handle_light_service(service):

if not light.should_poll:
continue
update_tasks.append(light.async_update_ha_state(True))

update_tasks.append(
light.async_update_ha_state(True, service.context))

if update_tasks:
await asyncio.wait(update_tasks, loop=hass.loop)
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/switch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ async def async_handle_switch_service(service):

if not switch.should_poll:
continue
update_tasks.append(switch.async_update_ha_state(True))
update_tasks.append(
switch.async_update_ha_state(True, service.context))

if update_tasks:
await asyncio.wait(update_tasks, loop=hass.loop)
Expand Down
19 changes: 16 additions & 3 deletions homeassistant/components/websocket_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from homeassistant.const import (
MATCH_ALL, EVENT_TIME_CHANGED, EVENT_HOMEASSISTANT_STOP,
__version__)
from homeassistant.core import callback
from homeassistant.core import Context, callback
from homeassistant.loader import bind_hass
from homeassistant.remote import JSONEncoder
from homeassistant.helpers import config_validation as cv
Expand Down Expand Up @@ -262,6 +262,18 @@ def __init__(self, hass, request):
self._handle_task = None
self._writer_task = None

@property
def user(self):
"""Return the user associated with the connection."""
return self.request.get('hass_user')

def context(self, msg):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

msg seems unused, change to property?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to future proof it. Making a breaking change is a pain, especially for custom components.

"""Return a context."""
user = self.user
if user is None:
return Context()
return Context(user_id=user.id)

def debug(self, message1, message2=''):
"""Print a debug message."""
_LOGGER.debug("WS %s: %s %s", id(self.wsock), message1, message2)
Expand All @@ -287,7 +299,7 @@ async def _writer(self):

@callback
def send_message_outside(self, message):
"""Send a message to the client outside of the main task.
"""Send a message to the client.

Closes connection if the client is not reading the messages.

Expand Down Expand Up @@ -508,7 +520,8 @@ def handle_call_service(hass, connection, msg):
async def call_service_helper(msg):
"""Call a service and fire complete message."""
await hass.services.async_call(
msg['domain'], msg['service'], msg.get('service_data'), True)
msg['domain'], msg['service'], msg.get('service_data'), True,
connection.context(msg))
connection.send_message_outside(result_message(msg['id']))

hass.async_add_job(call_service_helper(msg))
Expand Down
3 changes: 0 additions & 3 deletions homeassistant/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,6 @@
# Name
ATTR_NAME = 'name'

# Data for a SERVICE_EXECUTED event
ATTR_SERVICE_CALL_ID = 'service_call_id'

# Contains one string or a list of strings, each being an entity id
ATTR_ENTITY_ID = 'entity_id'

Expand Down
Loading