Access camera images using access token
This commit is contained in:
parent
585fbb1c02
commit
fe794d7fd8
2 changed files with 35 additions and 18 deletions
|
@ -52,6 +52,11 @@ class Camera(Entity):
|
|||
"""Initialize a camera."""
|
||||
self.is_streaming = False
|
||||
|
||||
@property
|
||||
def access_token(self):
|
||||
"""Access token for this camera."""
|
||||
return str(id(self))
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No need to poll cameras."""
|
||||
|
@ -124,7 +129,9 @@ class Camera(Entity):
|
|||
@property
|
||||
def state_attributes(self):
|
||||
"""Camera state attributes."""
|
||||
attr = {}
|
||||
attr = {
|
||||
'access_token': self.access_token,
|
||||
}
|
||||
|
||||
if self.model:
|
||||
attr['model_name'] = self.model
|
||||
|
@ -138,11 +145,32 @@ class Camera(Entity):
|
|||
class CameraView(HomeAssistantView):
|
||||
"""Base CameraView."""
|
||||
|
||||
requires_auth = False
|
||||
|
||||
def __init__(self, hass, entities):
|
||||
"""Initialize a basic camera view."""
|
||||
super().__init__(hass)
|
||||
self.entities = entities
|
||||
|
||||
def get(self, request, entity_id):
|
||||
"""Start a get request."""
|
||||
camera = self.entities.get(entity_id)
|
||||
|
||||
if camera is None:
|
||||
return self.Response(status=404)
|
||||
|
||||
authenticated = (request.authenticated or
|
||||
request.args.get('token') == camera.access_token)
|
||||
|
||||
if not authenticated:
|
||||
return self.Response(status=401)
|
||||
|
||||
return self.handle(camera)
|
||||
|
||||
def handle(self, camera):
|
||||
"""Hanlde the camera request."""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class CameraImageView(CameraView):
|
||||
"""Camera view to serve an image."""
|
||||
|
@ -150,13 +178,8 @@ class CameraImageView(CameraView):
|
|||
url = "/api/camera_proxy/<entity(domain=camera):entity_id>"
|
||||
name = "api:camera:image"
|
||||
|
||||
def get(self, request, entity_id):
|
||||
def handle(self, camera):
|
||||
"""Serve camera image."""
|
||||
camera = self.entities.get(entity_id)
|
||||
|
||||
if camera is None:
|
||||
return self.Response(status=404)
|
||||
|
||||
response = camera.camera_image()
|
||||
|
||||
if response is None:
|
||||
|
@ -171,11 +194,6 @@ class CameraMjpegStream(CameraView):
|
|||
url = "/api/camera_proxy_stream/<entity(domain=camera):entity_id>"
|
||||
name = "api:camera:stream"
|
||||
|
||||
def get(self, request, entity_id):
|
||||
def handle(self, camera):
|
||||
"""Serve camera image."""
|
||||
camera = self.entities.get(entity_id)
|
||||
|
||||
if camera is None:
|
||||
return self.Response(status=404)
|
||||
|
||||
return camera.mjpeg_stream(self.Response())
|
||||
|
|
|
@ -339,10 +339,7 @@ class HomeAssistantView(object):
|
|||
# Auth code verbose on purpose
|
||||
authenticated = False
|
||||
|
||||
if not self.requires_auth:
|
||||
authenticated = True
|
||||
|
||||
elif self.hass.wsgi.api_password is None:
|
||||
if self.hass.wsgi.api_password is None:
|
||||
authenticated = True
|
||||
|
||||
elif hmac.compare_digest(request.headers.get(HTTP_HEADER_HA_AUTH, ''),
|
||||
|
@ -366,9 +363,11 @@ class HomeAssistantView(object):
|
|||
except BadRequest:
|
||||
pass
|
||||
|
||||
if not authenticated:
|
||||
if self.requires_auth and not authenticated:
|
||||
raise Unauthorized()
|
||||
|
||||
request.authenticated = authenticated
|
||||
|
||||
result = handler(request, **values)
|
||||
|
||||
if isinstance(result, self.Response):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue