Merge pull request #1478 from home-assistant/dev

Release 198
This commit is contained in:
Pascal Vizeli 2020-02-05 10:58:59 +01:00 committed by GitHub
commit cd9034b3f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 110 additions and 51 deletions

View File

@ -89,6 +89,11 @@ class RestAPI(CoreSysAttributes):
self.webapp.add_routes( self.webapp.add_routes(
[ [
web.get("/os/info", api_hassos.info),
web.post("/os/update", api_hassos.update),
web.post("/os/update/cli", api_hassos.update_cli),
web.post("/os/config/sync", api_hassos.config_sync),
# Remove with old Hass.io fallback
web.get("/hassos/info", api_hassos.info), web.get("/hassos/info", api_hassos.info),
web.post("/hassos/update", api_hassos.update), web.post("/hassos/update", api_hassos.update),
web.post("/hassos/update/cli", api_hassos.update_cli), web.post("/hassos/update/cli", api_hassos.update_cli),
@ -150,6 +155,17 @@ class RestAPI(CoreSysAttributes):
self.webapp.add_routes( self.webapp.add_routes(
[ [
web.get("/core/info", api_hass.info),
web.get("/core/logs", api_hass.logs),
web.get("/core/stats", api_hass.stats),
web.post("/core/options", api_hass.options),
web.post("/core/update", api_hass.update),
web.post("/core/restart", api_hass.restart),
web.post("/core/stop", api_hass.stop),
web.post("/core/start", api_hass.start),
web.post("/core/check", api_hass.check),
web.post("/core/rebuild", api_hass.rebuild),
# Remove with old Hass.io fallback
web.get("/homeassistant/info", api_hass.info), web.get("/homeassistant/info", api_hass.info),
web.get("/homeassistant/logs", api_hass.logs), web.get("/homeassistant/logs", api_hass.logs),
web.get("/homeassistant/stats", api_hass.stats), web.get("/homeassistant/stats", api_hass.stats),
@ -170,6 +186,13 @@ class RestAPI(CoreSysAttributes):
self.webapp.add_routes( self.webapp.add_routes(
[ [
web.get("/core/api/websocket", api_proxy.websocket),
web.get("/core/websocket", api_proxy.websocket),
web.get("/core/api/stream", api_proxy.stream),
web.post("/core/api/{path:.+}", api_proxy.api),
web.get("/core/api/{path:.+}", api_proxy.api),
web.get("/core/api/", api_proxy.api),
# Remove with old Hass.io fallback
web.get("/homeassistant/api/websocket", api_proxy.websocket), web.get("/homeassistant/api/websocket", api_proxy.websocket),
web.get("/homeassistant/websocket", api_proxy.websocket), web.get("/homeassistant/websocket", api_proxy.websocket),
web.get("/homeassistant/api/stream", api_proxy.stream), web.get("/homeassistant/api/stream", api_proxy.stream),

View File

@ -23,6 +23,7 @@ from ..const import (
ATTR_ENABLE, ATTR_ENABLE,
COOKIE_INGRESS, COOKIE_INGRESS,
HEADER_TOKEN, HEADER_TOKEN,
HEADER_TOKEN_OLD,
REQUEST_FROM, REQUEST_FROM,
) )
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
@ -212,6 +213,7 @@ def _init_header(
hdrs.SEC_WEBSOCKET_VERSION, hdrs.SEC_WEBSOCKET_VERSION,
hdrs.SEC_WEBSOCKET_KEY, hdrs.SEC_WEBSOCKET_KEY,
istr(HEADER_TOKEN), istr(HEADER_TOKEN),
istr(HEADER_TOKEN_OLD),
): ):
continue continue
headers[name] = value headers[name] = value

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
!function(e){function n(n){for(var t,o,a=n[0],i=n[1],c=0,u=[];c<a.length;c++)o=a[c],Object.prototype.hasOwnProperty.call(r,o)&&r[o]&&u.push(r[o][0]),r[o]=0;for(t in i)Object.prototype.hasOwnProperty.call(i,t)&&(e[t]=i[t]);for(f&&f(n);u.length;)u.shift()()}var t={},r={6:0};function o(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,o),r.l=!0,r.exports}o.e=function(e){var n=[],t=r[e];if(0!==t)if(t)n.push(t[2]);else{var a=new Promise(function(n,o){t=r[e]=[n,o]});n.push(t[2]=a);var i,c=document.createElement("script");c.charset="utf-8",c.timeout=120,o.nc&&c.setAttribute("nonce",o.nc),c.src=function(e){return o.p+"chunk."+{0:"87b1d37fc9b8a6f7e2a6",1:"e46c606dd9100816af4e",2:"92a11ac1b80e0d7839d2",3:"170381dce1aef5f33cec",4:"00de7352e51443687ebb",5:"0c4f6887f9b7e7b11ef5",7:"2412396b4c6d55f3dec7",8:"0b82745c7bdffe5c1404",9:"990ee58006b248f55d23",10:"a9c5cc5386711b03c031",11:"b60200a57d6f63941b30",12:"b2dce600432c76a53d8c",13:"8527374a266cecf93aa9",14:"f49e500cf58ea310d452",15:"d4931d72592ad48ba2be"}[e]+".js"}(e);var f=new Error;i=function(n){c.onerror=c.onload=null,clearTimeout(u);var t=r[e];if(0!==t){if(t){var o=n&&("load"===n.type?"missing":n.type),a=n&&n.target&&n.target.src;f.message="Loading chunk "+e+" failed.\n("+o+": "+a+")",f.name="ChunkLoadError",f.type=o,f.request=a,t[1](f)}r[e]=void 0}};var u=setTimeout(function(){i({type:"timeout",target:c})},12e4);c.onerror=c.onload=i,document.head.appendChild(c)}return Promise.all(n)},o.m=e,o.c=t,o.d=function(e,n,t){o.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,n){if(1&n&&(e=o(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(o.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)o.d(t,r,function(n){return e[n]}.bind(null,r));return t},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="/api/hassio/app/",o.oe=function(e){throw console.error(e),e};var a=self.webpackJsonp=self.webpackJsonp||[],i=a.push.bind(a);a.push=n,a=a.slice();for(var c=0;c<a.length;c++)n(a[c]);var f=i;o(o.s=0)}([function(e,n,t){window.loadES5Adapter().then(function(){t.e(12).then(t.t.bind(null,1,7)),Promise.all([t.e(1),t.e(8)]).then(t.bind(null,3)),Promise.all([t.e(1),t.e(15),t.e(10)]).then(t.bind(null,2))});var r=document.createElement("style");r.innerHTML="\nbody {\n font-family: Roboto, sans-serif;\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-weight: 400;\n margin: 0;\n padding: 0;\n height: 100vh;\n}\n",document.head.appendChild(r)}]); !function(e){function n(n){for(var t,o,a=n[0],i=n[1],c=0,d=[];c<a.length;c++)o=a[c],Object.prototype.hasOwnProperty.call(r,o)&&r[o]&&d.push(r[o][0]),r[o]=0;for(t in i)Object.prototype.hasOwnProperty.call(i,t)&&(e[t]=i[t]);for(u&&u(n);d.length;)d.shift()()}var t={},r={6:0};function o(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,o),r.l=!0,r.exports}o.e=function(e){var n=[],t=r[e];if(0!==t)if(t)n.push(t[2]);else{var a=new Promise(function(n,o){t=r[e]=[n,o]});n.push(t[2]=a);var i,c=document.createElement("script");c.charset="utf-8",c.timeout=120,o.nc&&c.setAttribute("nonce",o.nc),c.src=function(e){return o.p+"chunk."+{0:"87b1d37fc9b8a6f7e2a6",1:"e46c606dd9100816af4e",2:"92a11ac1b80e0d7839d2",3:"429840c83fad61bc51a8",4:"715824f4764bdbe425b1",5:"9d371c8143226d4eaaee",7:"43e40fd69686ad51301d",8:"0b82745c7bdffe5c1404",9:"990ee58006b248f55d23",10:"4d45ee0a3d852768f97e",11:"b60200a57d6f63941b30",12:"b2dce600432c76a53d8c",13:"8527374a266cecf93aa9",14:"f49e500cf58ea310d452",15:"d4931d72592ad48ba2be"}[e]+".js"}(e);var u=new Error;i=function(n){c.onerror=c.onload=null,clearTimeout(d);var t=r[e];if(0!==t){if(t){var o=n&&("load"===n.type?"missing":n.type),a=n&&n.target&&n.target.src;u.message="Loading chunk "+e+" failed.\n("+o+": "+a+")",u.name="ChunkLoadError",u.type=o,u.request=a,t[1](u)}r[e]=void 0}};var d=setTimeout(function(){i({type:"timeout",target:c})},12e4);c.onerror=c.onload=i,document.head.appendChild(c)}return Promise.all(n)},o.m=e,o.c=t,o.d=function(e,n,t){o.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,n){if(1&n&&(e=o(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(o.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)o.d(t,r,function(n){return e[n]}.bind(null,r));return t},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="/api/hassio/app/",o.oe=function(e){throw console.error(e),e};var a=self.webpackJsonp=self.webpackJsonp||[],i=a.push.bind(a);a.push=n,a=a.slice();for(var c=0;c<a.length;c++)n(a[c]);var u=i;o(o.s=0)}([function(e,n,t){window.loadES5Adapter().then(function(){t.e(12).then(t.t.bind(null,1,7)),Promise.all([t.e(1),t.e(8)]).then(t.bind(null,3)),Promise.all([t.e(1),t.e(15),t.e(10)]).then(t.bind(null,2))});var r=document.createElement("style");r.innerHTML="\nbody {\n font-family: Roboto, sans-serif;\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-weight: 400;\n margin: 0;\n padding: 0;\n height: 100vh;\n}\n",document.head.appendChild(r)}]);
//# sourceMappingURL=entrypoint.js.map //# sourceMappingURL=entrypoint.js.map

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -5,22 +5,22 @@
"vendors~hassio-icons~hassio-main.js.map": "/api/hassio/app/chunk.e46c606dd9100816af4e.js.map", "vendors~hassio-icons~hassio-main.js.map": "/api/hassio/app/chunk.e46c606dd9100816af4e.js.map",
"codemirror.js": "/api/hassio/app/chunk.92a11ac1b80e0d7839d2.js", "codemirror.js": "/api/hassio/app/chunk.92a11ac1b80e0d7839d2.js",
"codemirror.js.map": "/api/hassio/app/chunk.92a11ac1b80e0d7839d2.js.map", "codemirror.js.map": "/api/hassio/app/chunk.92a11ac1b80e0d7839d2.js.map",
"confirmation.js": "/api/hassio/app/chunk.170381dce1aef5f33cec.js", "confirmation.js": "/api/hassio/app/chunk.429840c83fad61bc51a8.js",
"confirmation.js.map": "/api/hassio/app/chunk.170381dce1aef5f33cec.js.map", "confirmation.js.map": "/api/hassio/app/chunk.429840c83fad61bc51a8.js.map",
"dialog-hassio-markdown.js": "/api/hassio/app/chunk.00de7352e51443687ebb.js", "dialog-hassio-markdown.js": "/api/hassio/app/chunk.715824f4764bdbe425b1.js",
"dialog-hassio-markdown.js.map": "/api/hassio/app/chunk.00de7352e51443687ebb.js.map", "dialog-hassio-markdown.js.map": "/api/hassio/app/chunk.715824f4764bdbe425b1.js.map",
"dialog-hassio-snapshot.js": "/api/hassio/app/chunk.0c4f6887f9b7e7b11ef5.js", "dialog-hassio-snapshot.js": "/api/hassio/app/chunk.9d371c8143226d4eaaee.js",
"dialog-hassio-snapshot.js.map": "/api/hassio/app/chunk.0c4f6887f9b7e7b11ef5.js.map", "dialog-hassio-snapshot.js.map": "/api/hassio/app/chunk.9d371c8143226d4eaaee.js.map",
"entrypoint.js": "/api/hassio/app/entrypoint.js", "entrypoint.js": "/api/hassio/app/entrypoint.js",
"entrypoint.js.map": "/api/hassio/app/entrypoint.js.map", "entrypoint.js.map": "/api/hassio/app/entrypoint.js.map",
"hassio-addon-view.js": "/api/hassio/app/chunk.2412396b4c6d55f3dec7.js", "hassio-addon-view.js": "/api/hassio/app/chunk.43e40fd69686ad51301d.js",
"hassio-addon-view.js.map": "/api/hassio/app/chunk.2412396b4c6d55f3dec7.js.map", "hassio-addon-view.js.map": "/api/hassio/app/chunk.43e40fd69686ad51301d.js.map",
"hassio-icons.js": "/api/hassio/app/chunk.0b82745c7bdffe5c1404.js", "hassio-icons.js": "/api/hassio/app/chunk.0b82745c7bdffe5c1404.js",
"hassio-icons.js.map": "/api/hassio/app/chunk.0b82745c7bdffe5c1404.js.map", "hassio-icons.js.map": "/api/hassio/app/chunk.0b82745c7bdffe5c1404.js.map",
"hassio-ingress-view.js": "/api/hassio/app/chunk.990ee58006b248f55d23.js", "hassio-ingress-view.js": "/api/hassio/app/chunk.990ee58006b248f55d23.js",
"hassio-ingress-view.js.map": "/api/hassio/app/chunk.990ee58006b248f55d23.js.map", "hassio-ingress-view.js.map": "/api/hassio/app/chunk.990ee58006b248f55d23.js.map",
"hassio-main.js": "/api/hassio/app/chunk.a9c5cc5386711b03c031.js", "hassio-main.js": "/api/hassio/app/chunk.4d45ee0a3d852768f97e.js",
"hassio-main.js.map": "/api/hassio/app/chunk.a9c5cc5386711b03c031.js.map", "hassio-main.js.map": "/api/hassio/app/chunk.4d45ee0a3d852768f97e.js.map",
"mdi-icons.js": "/api/hassio/app/chunk.b60200a57d6f63941b30.js", "mdi-icons.js": "/api/hassio/app/chunk.b60200a57d6f63941b30.js",
"mdi-icons.js.map": "/api/hassio/app/chunk.b60200a57d6f63941b30.js.map", "mdi-icons.js.map": "/api/hassio/app/chunk.b60200a57d6f63941b30.js.map",
"roboto.js": "/api/hassio/app/chunk.b2dce600432c76a53d8c.js", "roboto.js": "/api/hassio/app/chunk.b2dce600432c76a53d8c.js",
@ -33,10 +33,10 @@
"vendors~hassio-main.js.map": "/api/hassio/app/chunk.d4931d72592ad48ba2be.js.map", "vendors~hassio-main.js.map": "/api/hassio/app/chunk.d4931d72592ad48ba2be.js.map",
"201359fd5a526afe13ef.worker.js": "/api/hassio/app/201359fd5a526afe13ef.worker.js", "201359fd5a526afe13ef.worker.js": "/api/hassio/app/201359fd5a526afe13ef.worker.js",
"201359fd5a526afe13ef.worker.js.map": "/api/hassio/app/201359fd5a526afe13ef.worker.js.map", "201359fd5a526afe13ef.worker.js.map": "/api/hassio/app/201359fd5a526afe13ef.worker.js.map",
"chunk.00de7352e51443687ebb.js.LICENSE": "/api/hassio/app/chunk.00de7352e51443687ebb.js.LICENSE", "chunk.429840c83fad61bc51a8.js.LICENSE": "/api/hassio/app/chunk.429840c83fad61bc51a8.js.LICENSE",
"chunk.0c4f6887f9b7e7b11ef5.js.LICENSE": "/api/hassio/app/chunk.0c4f6887f9b7e7b11ef5.js.LICENSE", "chunk.715824f4764bdbe425b1.js.LICENSE": "/api/hassio/app/chunk.715824f4764bdbe425b1.js.LICENSE",
"chunk.170381dce1aef5f33cec.js.LICENSE": "/api/hassio/app/chunk.170381dce1aef5f33cec.js.LICENSE",
"chunk.87b1d37fc9b8a6f7e2a6.js.LICENSE": "/api/hassio/app/chunk.87b1d37fc9b8a6f7e2a6.js.LICENSE", "chunk.87b1d37fc9b8a6f7e2a6.js.LICENSE": "/api/hassio/app/chunk.87b1d37fc9b8a6f7e2a6.js.LICENSE",
"chunk.9d371c8143226d4eaaee.js.LICENSE": "/api/hassio/app/chunk.9d371c8143226d4eaaee.js.LICENSE",
"chunk.d4931d72592ad48ba2be.js.LICENSE": "/api/hassio/app/chunk.d4931d72592ad48ba2be.js.LICENSE", "chunk.d4931d72592ad48ba2be.js.LICENSE": "/api/hassio/app/chunk.d4931d72592ad48ba2be.js.LICENSE",
"chunk.e46c606dd9100816af4e.js.LICENSE": "/api/hassio/app/chunk.e46c606dd9100816af4e.js.LICENSE", "chunk.e46c606dd9100816af4e.js.LICENSE": "/api/hassio/app/chunk.e46c606dd9100816af4e.js.LICENSE",
"chunk.f49e500cf58ea310d452.js.LICENSE": "/api/hassio/app/chunk.f49e500cf58ea310d452.js.LICENSE" "chunk.f49e500cf58ea310d452.js.LICENSE": "/api/hassio/app/chunk.f49e500cf58ea310d452.js.LICENSE"

View File

@ -9,7 +9,6 @@ from aiohttp.web_exceptions import HTTPBadGateway, HTTPUnauthorized
from aiohttp.client_exceptions import ClientConnectorError from aiohttp.client_exceptions import ClientConnectorError
from aiohttp.hdrs import CONTENT_TYPE, AUTHORIZATION from aiohttp.hdrs import CONTENT_TYPE, AUTHORIZATION
from ..const import HEADER_HA_ACCESS
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import HomeAssistantAuthError, HomeAssistantAPIError, APIError from ..exceptions import HomeAssistantAuthError, HomeAssistantAPIError, APIError
@ -17,6 +16,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
FORWARD_HEADERS = ("X-Speech-Content",) FORWARD_HEADERS = ("X-Speech-Content",)
HEADER_HA_ACCESS = "X-Ha-Access"
class APIProxy(CoreSysAttributes): class APIProxy(CoreSysAttributes):

View File

@ -3,16 +3,16 @@ import logging
import re import re
from aiohttp.web import middleware from aiohttp.web import middleware
from aiohttp.web_exceptions import HTTPUnauthorized, HTTPForbidden from aiohttp.web_exceptions import HTTPForbidden, HTTPUnauthorized
from .utils import excract_supervisor_token
from ..const import ( from ..const import (
HEADER_TOKEN,
REQUEST_FROM, REQUEST_FROM,
ROLE_ADMIN, ROLE_ADMIN,
ROLE_BACKUP,
ROLE_DEFAULT, ROLE_DEFAULT,
ROLE_HOMEASSISTANT, ROLE_HOMEASSISTANT,
ROLE_MANAGER, ROLE_MANAGER,
ROLE_BACKUP,
) )
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
@ -24,6 +24,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
BLACKLIST = re.compile( BLACKLIST = re.compile(
r"^(?:" r"^(?:"
r"|/homeassistant/api/hassio/.*" r"|/homeassistant/api/hassio/.*"
r"|/core/api/hassio/.*"
r")$" r")$"
) )
@ -32,6 +33,8 @@ NO_SECURITY_CHECK = re.compile(
r"^(?:" r"^(?:"
r"|/homeassistant/api/.*" r"|/homeassistant/api/.*"
r"|/homeassistant/websocket" r"|/homeassistant/websocket"
r"|/core/api/.*"
r"|/core/websocket"
r"|/supervisor/ping" r"|/supervisor/ping"
r")$" r")$"
) )
@ -59,6 +62,7 @@ ADDONS_ROLE_ACCESS = {
), ),
ROLE_HOMEASSISTANT: re.compile( ROLE_HOMEASSISTANT: re.compile(
r"^(?:" r"^(?:"
r"|/core/.+"
r"|/homeassistant/.+" r"|/homeassistant/.+"
r")$" r")$"
), ),
@ -70,9 +74,11 @@ ADDONS_ROLE_ACCESS = {
ROLE_MANAGER: re.compile( ROLE_MANAGER: re.compile(
r"^(?:" r"^(?:"
r"|/dns/.*" r"|/dns/.*"
r"|/core/.+"
r"|/homeassistant/.+" r"|/homeassistant/.+"
r"|/host/.+" r"|/host/.+"
r"|/hardware/.+" r"|/hardware/.+"
r"|/os/.+"
r"|/hassos/.+" r"|/hassos/.+"
r"|/supervisor/.+" r"|/supervisor/.+"
r"|/addons(?:/[^/]+/(?!security).+|/reload)?" r"|/addons(?:/[^/]+/(?!security).+|/reload)?"
@ -98,7 +104,7 @@ class SecurityMiddleware(CoreSysAttributes):
async def token_validation(self, request, handler): async def token_validation(self, request, handler):
"""Check security access of this layer.""" """Check security access of this layer."""
request_from = None request_from = None
hassio_token = request.headers.get(HEADER_TOKEN) supervisor_token = excract_supervisor_token(request)
# Blacklist # Blacklist
if BLACKLIST.match(request.path): if BLACKLIST.match(request.path):
@ -111,24 +117,24 @@ class SecurityMiddleware(CoreSysAttributes):
return await handler(request) return await handler(request)
# Not token # Not token
if not hassio_token: if not supervisor_token:
_LOGGER.warning("No API token provided for %s", request.path) _LOGGER.warning("No API token provided for %s", request.path)
raise HTTPUnauthorized() raise HTTPUnauthorized()
# Home-Assistant # Home-Assistant
if hassio_token == self.sys_homeassistant.hassio_token: if supervisor_token == self.sys_homeassistant.hassio_token:
_LOGGER.debug("%s access from Home Assistant", request.path) _LOGGER.debug("%s access from Home Assistant", request.path)
request_from = self.sys_homeassistant request_from = self.sys_homeassistant
# Host # Host
if hassio_token == self.sys_machine_id: if supervisor_token == self.sys_machine_id:
_LOGGER.debug("%s access from Host", request.path) _LOGGER.debug("%s access from Host", request.path)
request_from = self.sys_host request_from = self.sys_host
# Add-on # Add-on
addon = None addon = None
if hassio_token and not request_from: if supervisor_token and not request_from:
addon = self.sys_addons.from_token(hassio_token) addon = self.sys_addons.from_token(supervisor_token)
# Check Add-on API access # Check Add-on API access
if addon and ADDONS_API_BYPASS.match(request.path): if addon and ADDONS_API_BYPASS.match(request.path):

View File

@ -4,11 +4,14 @@ import logging
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from aiohttp import web from aiohttp import web
from aiohttp.hdrs import AUTHORIZATION
import voluptuous as vol import voluptuous as vol
from voluptuous.humanize import humanize_error from voluptuous.humanize import humanize_error
from ..const import ( from ..const import (
CONTENT_TYPE_BINARY, CONTENT_TYPE_BINARY,
HEADER_TOKEN,
HEADER_TOKEN_OLD,
JSON_DATA, JSON_DATA,
JSON_MESSAGE, JSON_MESSAGE,
JSON_RESULT, JSON_RESULT,
@ -20,6 +23,22 @@ from ..exceptions import APIError, APIForbidden, HassioError
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
def excract_supervisor_token(request: web.Request) -> Optional[str]:
"""Extract Supervisor token from request."""
supervisor_token = request.headers.get(AUTHORIZATION)
if supervisor_token:
return supervisor_token.split(" ")[-1]
# Header token handling
supervisor_token = request.headers.get(HEADER_TOKEN)
# Remove with old Hass.io fallback
if not supervisor_token:
supervisor_token = request.headers.get(HEADER_TOKEN_OLD)
return supervisor_token
def json_loads(data: Any) -> Dict[str, Any]: def json_loads(data: Any) -> Dict[str, Any]:
"""Extract json from string with support for '' and None.""" """Extract json from string with support for '' and None."""
if not data: if not data:

View File

@ -3,7 +3,7 @@ from enum import Enum
from ipaddress import ip_network from ipaddress import ip_network
from pathlib import Path from pathlib import Path
HASSIO_VERSION = "197" HASSIO_VERSION = "198"
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons" URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"
@ -58,11 +58,13 @@ CONTENT_TYPE_JSON = "application/json"
CONTENT_TYPE_TEXT = "text/plain" CONTENT_TYPE_TEXT = "text/plain"
CONTENT_TYPE_TAR = "application/tar" CONTENT_TYPE_TAR = "application/tar"
CONTENT_TYPE_URL = "application/x-www-form-urlencoded" CONTENT_TYPE_URL = "application/x-www-form-urlencoded"
HEADER_HA_ACCESS = "X-Ha-Access"
HEADER_TOKEN = "X-Hassio-Key"
COOKIE_INGRESS = "ingress_session" COOKIE_INGRESS = "ingress_session"
ENV_TOKEN = "HASSIO_TOKEN" HEADER_TOKEN = "X-Supervisor-Token"
HEADER_TOKEN_OLD = "X-Hassio-Key"
ENV_TOKEN_OLD = "HASSIO_TOKEN"
ENV_TOKEN = "SUPERVISOR_TOKEN"
ENV_TIME = "TZ" ENV_TIME = "TZ"
REQUEST_FROM = "HASSIO_FROM" REQUEST_FROM = "HASSIO_FROM"

View File

@ -6,7 +6,7 @@ from ipaddress import IPv4Address, ip_address
import logging import logging
import os import os
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Dict, List, Optional, Union, Awaitable from typing import TYPE_CHECKING, Awaitable, Dict, List, Optional, Union
import docker import docker
import requests import requests
@ -15,6 +15,7 @@ from ..addons.build import AddonBuild
from ..const import ( from ..const import (
ENV_TIME, ENV_TIME,
ENV_TOKEN, ENV_TOKEN,
ENV_TOKEN_OLD,
MAP_ADDONS, MAP_ADDONS,
MAP_BACKUP, MAP_BACKUP,
MAP_CONFIG, MAP_CONFIG,
@ -118,6 +119,7 @@ class DockerAddon(DockerInterface):
**addon_env, **addon_env,
ENV_TIME: self.sys_timezone, ENV_TIME: self.sys_timezone,
ENV_TOKEN: self.addon.hassio_token, ENV_TOKEN: self.addon.hassio_token,
ENV_TOKEN_OLD: self.addon.hassio_token,
} }
@property @property
@ -189,7 +191,10 @@ class DockerAddon(DockerInterface):
@property @property
def network_mapping(self) -> Dict[str, str]: def network_mapping(self) -> Dict[str, str]:
"""Return hosts mapping.""" """Return hosts mapping."""
return {"hassio": self.sys_docker.network.supervisor} return {
"supervisor": self.sys_docker.network.supervisor,
"hassio": self.sys_docker.network.supervisor,
}
@property @property
def network_mode(self) -> Optional[str]: def network_mode(self) -> Optional[str]:

View File

@ -6,7 +6,7 @@ from typing import Awaitable, Optional
import docker import docker
from ..const import ENV_TIME, ENV_TOKEN, LABEL_MACHINE from ..const import ENV_TIME, ENV_TOKEN, ENV_TOKEN_OLD, LABEL_MACHINE
from ..exceptions import DockerAPIError from ..exceptions import DockerAPIError
from .interface import CommandReturn, DockerInterface from .interface import CommandReturn, DockerInterface
@ -69,8 +69,10 @@ class DockerHomeAssistant(DockerInterface):
network_mode="host", network_mode="host",
environment={ environment={
"HASSIO": self.sys_docker.network.supervisor, "HASSIO": self.sys_docker.network.supervisor,
"SUPERVISOR": self.sys_docker.network.supervisor,
ENV_TIME: self.sys_timezone, ENV_TIME: self.sys_timezone,
ENV_TOKEN: self.sys_homeassistant.hassio_token, ENV_TOKEN: self.sys_homeassistant.hassio_token,
ENV_TOKEN_OLD: self.sys_homeassistant.hassio_token,
}, },
volumes={ volumes={
str(self.sys_config.path_extern_homeassistant): { str(self.sys_config.path_extern_homeassistant): {

@ -1 +1 @@
Subproject commit 004ff58c21c85db045ce87db972167cb05b331d4 Subproject commit 8518f774d44d4b9cd7e9b824dc9e9372e665347d