@project-chip/matter.js 0.10.4 → 0.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/device/LegacyInteractionServer.d.ts +1 -1
- package/dist/cjs/device/LegacyInteractionServer.d.ts.map +1 -1
- package/dist/cjs/device/LegacyInteractionServer.js +4 -2
- package/dist/cjs/device/LegacyInteractionServer.js.map +2 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.d.ts +1 -1
- package/dist/cjs/node/server/TransactionalInteractionServer.d.ts.map +1 -1
- package/dist/cjs/node/server/TransactionalInteractionServer.js +6 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.js.map +2 -2
- package/dist/cjs/protocol/interaction/AccessControlManager.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/AccessControlManager.js +6 -2
- package/dist/cjs/protocol/interaction/AccessControlManager.js.map +2 -2
- package/dist/cjs/protocol/interaction/InteractionServer.d.ts +1 -1
- package/dist/cjs/protocol/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/InteractionServer.js +5 -4
- package/dist/cjs/protocol/interaction/InteractionServer.js.map +2 -2
- package/dist/cjs/protocol/interaction/SubscriptionHandler.d.ts +1 -1
- package/dist/cjs/protocol/interaction/SubscriptionHandler.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/SubscriptionHandler.js +1 -1
- package/dist/cjs/protocol/interaction/SubscriptionHandler.js.map +2 -2
- package/dist/cjs/session/SecureSession.d.ts.map +1 -1
- package/dist/cjs/session/SecureSession.js +2 -1
- package/dist/cjs/session/SecureSession.js.map +2 -2
- package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseServer.js +6 -2
- package/dist/cjs/session/case/CaseServer.js.map +2 -2
- package/dist/esm/device/LegacyInteractionServer.d.ts +1 -1
- package/dist/esm/device/LegacyInteractionServer.d.ts.map +1 -1
- package/dist/esm/device/LegacyInteractionServer.js +4 -2
- package/dist/esm/device/LegacyInteractionServer.js.map +2 -2
- package/dist/esm/node/server/TransactionalInteractionServer.d.ts +1 -1
- package/dist/esm/node/server/TransactionalInteractionServer.d.ts.map +1 -1
- package/dist/esm/node/server/TransactionalInteractionServer.js +6 -2
- package/dist/esm/node/server/TransactionalInteractionServer.js.map +2 -2
- package/dist/esm/protocol/interaction/AccessControlManager.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/AccessControlManager.js +6 -2
- package/dist/esm/protocol/interaction/AccessControlManager.js.map +2 -2
- package/dist/esm/protocol/interaction/InteractionServer.d.ts +1 -1
- package/dist/esm/protocol/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/InteractionServer.js +5 -4
- package/dist/esm/protocol/interaction/InteractionServer.js.map +2 -2
- package/dist/esm/protocol/interaction/SubscriptionHandler.d.ts +1 -1
- package/dist/esm/protocol/interaction/SubscriptionHandler.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/SubscriptionHandler.js +1 -1
- package/dist/esm/protocol/interaction/SubscriptionHandler.js.map +2 -2
- package/dist/esm/session/SecureSession.d.ts.map +1 -1
- package/dist/esm/session/SecureSession.js +2 -1
- package/dist/esm/session/SecureSession.js.map +2 -2
- package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
- package/dist/esm/session/case/CaseServer.js +6 -2
- package/dist/esm/session/case/CaseServer.js.map +2 -2
- package/package.json +3 -3
- package/src/device/LegacyInteractionServer.ts +5 -1
- package/src/node/server/TransactionalInteractionServer.ts +9 -1
- package/src/protocol/interaction/AccessControlManager.ts +5 -1
- package/src/protocol/interaction/InteractionServer.ts +4 -2
- package/src/protocol/interaction/SubscriptionHandler.ts +8 -4
- package/src/session/SecureSession.ts +1 -0
- package/src/session/case/CaseServer.ts +4 -0
|
@@ -38,7 +38,7 @@ export declare class TransactionalInteractionServer extends InteractionServer {
|
|
|
38
38
|
blockNewActivity(): void;
|
|
39
39
|
onNewExchange(exchange: MessageExchange<MatterDevice>): Promise<void>;
|
|
40
40
|
get aclServer(): AccessControlServer;
|
|
41
|
-
protected readAttribute(path: AttributePath, attribute: AnyAttributeServer<any>, exchange: MessageExchange<MatterDevice>, fabricFiltered: boolean, message: Message, endpoint: EndpointInterface): Promise<{
|
|
41
|
+
protected readAttribute(path: AttributePath, attribute: AnyAttributeServer<any>, exchange: MessageExchange<MatterDevice>, fabricFiltered: boolean, message: Message, endpoint: EndpointInterface, offline?: boolean): Promise<{
|
|
42
42
|
version: number;
|
|
43
43
|
value: any;
|
|
44
44
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionalInteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/node/server/TransactionalInteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"TransactionalInteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/node/server/TransactionalInteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAOrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAGvG,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAIxE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAE9E,OAAO,EAEH,YAAY,EACZ,aAAa,EAChB,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,OAAO,EACH,aAAa,EACb,WAAW,EACX,SAAS,EACT,iBAAiB,EACpB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAW9C;;;;;;;;;;;GAWG;AACH,qBAAa,8BAA+B,SAAQ,iBAAiB;;WASpD,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;gBAcnD,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,aAAa;IA0B1F,CAAC,MAAM,CAAC,YAAY,CAAC;IAM3B,gBAAgB;IAID,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC;IAiBpE,IAAI,SAAS,wBASZ;cAEwB,aAAa,CAClC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAClC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,UAAQ;;;;cAsBM,SAAS,CAC9B,IAAI,EAAE,SAAS,EACf,YAAY,EAAE,cAAc,CAAC,OAAO,cAAc,CAAC,EAAE,GAAG,SAAS,EACjE,KAAK,EAAE,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAC/B,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;IAsBpB,kBAAkB,CAC7B,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,OAAO,GACjB,OAAO,CAAC,aAAa,CAAC;cAWA,cAAc,CACnC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAC/B,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,UAAQ,EACb,WAAW,CAAC,EAAE,OAAO;cA6BA,aAAa,CAClC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAChC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,GAAG,EAClB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,UAAQ;;;;;;CAmCpB"}
|
|
@@ -50,6 +50,7 @@ var __callDispose = (stack, error, hasError) => {
|
|
|
50
50
|
*/
|
|
51
51
|
import { ActionTracer } from "../../behavior/context/ActionTracer.js";
|
|
52
52
|
import { NodeActivity } from "../../behavior/context/NodeActivity.js";
|
|
53
|
+
import { OfflineContext } from "../../behavior/context/server/OfflineContext.js";
|
|
53
54
|
import { OnlineContext } from "../../behavior/context/server/OnlineContext.js";
|
|
54
55
|
import { AccessControlServer } from "../../behavior/definitions/access-control/AccessControlServer.js";
|
|
55
56
|
import { BasicInformationServer } from "../../behavior/definitions/basic-information/BasicInformationServer.js";
|
|
@@ -141,8 +142,11 @@ class TransactionalInteractionServer extends InteractionServer {
|
|
|
141
142
|
}
|
|
142
143
|
return this.#aclServer = aclServer;
|
|
143
144
|
}
|
|
144
|
-
async readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint) {
|
|
145
|
-
const readAttribute = () => super.readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint);
|
|
145
|
+
async readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint, offline = false) {
|
|
146
|
+
const readAttribute = () => super.readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint, offline);
|
|
147
|
+
if (offline) {
|
|
148
|
+
return OfflineContext.act("offline-read", this.#activity, readAttribute);
|
|
149
|
+
}
|
|
146
150
|
return OnlineContext({
|
|
147
151
|
activity: exchange[activityKey],
|
|
148
152
|
fabricFiltered,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/node/server/TransactionalInteractionServer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterDevice } from \"../../MatterDevice.js\";\nimport { AccessControl } from \"../../behavior/AccessControl.js\";\nimport { ActionContext } from \"../../behavior/context/ActionContext.js\";\nimport { ActionTracer } from \"../../behavior/context/ActionTracer.js\";\nimport { NodeActivity } from \"../../behavior/context/NodeActivity.js\";\nimport { OnlineContext } from \"../../behavior/context/server/OnlineContext.js\";\nimport { AccessControlServer } from \"../../behavior/definitions/access-control/AccessControlServer.js\";\nimport { BasicInformationServer } from \"../../behavior/definitions/basic-information/BasicInformationServer.js\";\nimport { AccessControlCluster } from \"../../cluster/definitions/AccessControlCluster.js\";\nimport { AnyAttributeServer, AttributeServer } from \"../../cluster/server/AttributeServer.js\";\nimport { CommandServer } from \"../../cluster/server/CommandServer.js\";\nimport { AnyEventServer } from \"../../cluster/server/EventServer.js\";\nimport { Message } from \"../../codec/MessageCodec.js\";\nimport { InternalError } from \"../../common/MatterError.js\";\nimport { Endpoint } from \"../../endpoint/Endpoint.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { EndpointServer } from \"../../endpoint/EndpointServer.js\";\nimport { EndpointLifecycle } from \"../../endpoint/properties/EndpointLifecycle.js\";\nimport { Diagnostic } from \"../../log/Diagnostic.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { AccessDeniedError } from \"../../protocol/interaction/AccessControlManager.js\";\nimport { EventStorageData } from \"../../protocol/interaction/EventHandler.js\";\nimport { InteractionEndpointStructure } from \"../../protocol/interaction/InteractionEndpointStructure.js\";\nimport {\n InteractionServerMessenger,\n WriteRequest,\n WriteResponse,\n} from \"../../protocol/interaction/InteractionMessenger.js\";\nimport { TlvEventFilter } from \"../../protocol/interaction/InteractionProtocol.js\";\nimport {\n AttributePath,\n CommandPath,\n EventPath,\n InteractionServer,\n} from \"../../protocol/interaction/InteractionServer.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport { MaybePromise } from \"../../util/Promises.js\";\nimport { ServerNode } from \"../ServerNode.js\";\n\nconst activityKey = Symbol(\"activity\");\n\ninterface WithActivity {\n [activityKey]?: NodeActivity.Activity;\n}\n\nconst AclClusterId = AccessControlCluster.id;\nconst AclAttributeId = AccessControlCluster.attributes.acl.id;\n\n/**\n * Wire up an InteractionServer that initializes an InvocationContext earlier than the cluster API supports.\n *\n * This is necessary for attributes because the ClusterServer attribute APIs are synchronous while transaction\n * management is asynchronous.\n *\n * It's not necessary for command handling because that API is entirely async. We do it here, however, just for the\n * sake of consistency.\n *\n * This could be integrated directly into InteractionServer but this further refactoring is probably warranted there\n * regardless. This keeps the touch light for now.\n */\nexport class TransactionalInteractionServer extends InteractionServer {\n #endpointStructure: InteractionEndpointStructure;\n #changeListener: (type: EndpointLifecycle.Change) => void;\n #endpoint: Endpoint<ServerNode.RootEndpoint>;\n #activity: NodeActivity;\n #newActivityBlocked = false;\n #aclServer?: AccessControlServer;\n #aclUpdateIsDelayed = false;\n\n static async create(endpoint: Endpoint<ServerNode.RootEndpoint>) {\n const endpointStructure = new InteractionEndpointStructure();\n\n const maxPathsPerInvoke = await endpoint.act(\n agent => agent.get(BasicInformationServer).state.maxPathsPerInvoke,\n );\n\n return new TransactionalInteractionServer(endpoint, {\n endpointStructure,\n subscriptionOptions: endpoint.state.network.subscriptionOptions,\n maxPathsPerInvoke,\n });\n }\n\n constructor(endpoint: Endpoint<ServerNode.RootEndpoint>, config: InteractionServer.Configuration) {\n super(config);\n\n const { endpointStructure } = config;\n\n this.#activity = endpoint.env.get(NodeActivity);\n\n this.#endpoint = endpoint;\n this.#endpointStructure = endpointStructure;\n\n // TODO - rewrite element lookup so we don't need to build the secondary endpoint structure cache\n this.#updateStructure();\n this.#changeListener = type => {\n switch (type) {\n case EndpointLifecycle.Change.PartsReady:\n case EndpointLifecycle.Change.ClientsChanged:\n case EndpointLifecycle.Change.ServersChanged:\n case EndpointLifecycle.Change.Destroyed:\n this.#updateStructure();\n break;\n }\n };\n\n endpoint.lifecycle.changed.on(this.#changeListener);\n }\n\n async [Symbol.asyncDispose]() {\n this.#endpoint.lifecycle.changed.off(this.#changeListener);\n await this.close();\n this.#endpointStructure.close();\n }\n\n blockNewActivity() {\n this.#newActivityBlocked = true;\n }\n\n override async onNewExchange(exchange: MessageExchange<MatterDevice>) {\n // When closing, ignore anything newly incoming\n if (this.#newActivityBlocked || this.isClosing) {\n return;\n }\n\n // Activity tracking. This provides diagnostic information and prevents the server from shutting down whilst\n // the exchange is active\n using activity = this.#activity.begin(`session#${exchange.session.id.toString(16)}`);\n (exchange as WithActivity)[activityKey] = activity;\n\n // Delegate to InteractionServerMessenger\n return new InteractionServerMessenger(exchange)\n .handleRequest(this)\n .finally(() => delete (exchange as WithActivity)[activityKey]);\n }\n\n get aclServer() {\n if (this.#aclServer !== undefined) {\n return this.#aclServer;\n }\n const aclServer = this.#endpoint.act(agent => agent.get(AccessControlServer));\n if (MaybePromise.is(aclServer)) {\n throw new InternalError(\"AccessControlServer should already be initialized.\");\n }\n return (this.#aclServer = aclServer);\n }\n\n protected override async readAttribute(\n path: AttributePath,\n attribute: AnyAttributeServer<any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ) {\n const readAttribute = () => super.readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint);\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n exchange,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readAttribute);\n }\n\n protected override async readEvent(\n path: EventPath,\n eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined,\n event: AnyEventServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ): Promise<EventStorageData<any>[]> {\n const readEvent = (context: ActionContext) => {\n if (!context.authorizedFor(event.readAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.readEvent(path, eventFilters, event, exchange, fabricFiltered, message, endpoint);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n exchange,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readEvent);\n }\n\n override async handleWriteRequest(\n exchange: MessageExchange<MatterDevice>,\n writeRequest: WriteRequest,\n message: Message,\n ): Promise<WriteResponse> {\n const result = await super.handleWriteRequest(exchange, writeRequest, message);\n\n // We delayed the ACL update during the write transaction, so we need to update it now that anything is written\n if (this.#aclUpdateIsDelayed) {\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n return result;\n }\n\n protected override async writeAttribute(\n path: AttributePath,\n attribute: AttributeServer<any>,\n value: any,\n exchange: MessageExchange<MatterDevice>,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n isListWrite?: boolean,\n ) {\n const writeAttribute = () =>\n super.writeAttribute(path, attribute, value, exchange, message, endpoint, timed, isListWrite);\n\n if (path.endpointId === 0 && path.clusterId === AclClusterId && path.attributeId === AclAttributeId) {\n // This is a hack to prevent the ACL from updating while we are in the middle of a write transaction\n // and is needed because Acl should not become effective during writing of the ACL itself.\n this.aclServer.aclUpdateDelayed = true;\n this.#aclUpdateIsDelayed = true;\n } else if (this.#aclUpdateIsDelayed) {\n // Ok it seems that acl was written, but we now write another path, so we can update Acl attribute now\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n timed,\n message,\n exchange,\n fabricFiltered: true,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Write,\n endpoint,\n root: this.#endpoint,\n }).act(writeAttribute);\n }\n\n protected override async invokeCommand(\n path: CommandPath,\n command: CommandServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n commandFields: any,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n ) {\n const invokeCommand = (context: ActionContext) => {\n if (!context.authorizedFor(command.invokeAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.invokeCommand(path, command, exchange, commandFields, message, endpoint, timed);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n command: true,\n timed,\n message,\n exchange,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Invoke,\n endpoint,\n root: this.#endpoint,\n }).act(invokeCommand);\n }\n\n get #tracer() {\n if (this.#endpoint.env.has(ActionTracer)) {\n return this.#endpoint.env.get(ActionTracer);\n }\n }\n\n #updateStructure() {\n if (this.#endpoint.lifecycle.isPartsReady) {\n this.#endpointStructure.initializeFromEndpoint(EndpointServer.forEndpoint(this.#endpoint));\n }\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AAKrC,SAAS,qBAAqB;AAG9B,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAE3B,SAAS,yBAAyB;AAElC,SAAS,oCAAoC;AAC7C;AAAA,EACI;AAAA,OAGG;AAEP;AAAA,EAII;AAAA,OACG;AAEP,SAAS,oBAAoB;AAG7B,MAAM,cAAc,OAAO,UAAU;AAMrC,MAAM,eAAe,qBAAqB;AAC1C,MAAM,iBAAiB,qBAAqB,WAAW,IAAI;AAcpD,MAAM,uCAAuC,kBAAkB;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB;AAAA,EACA,sBAAsB;AAAA,EAEtB,aAAa,OAAO,UAA6C;AAC7D,UAAM,oBAAoB,IAAI,6BAA6B;AAE3D,UAAM,oBAAoB,MAAM,SAAS;AAAA,MACrC,WAAS,MAAM,IAAI,sBAAsB,EAAE,MAAM;AAAA,IACrD;AAEA,WAAO,IAAI,+BAA+B,UAAU;AAAA,MAChD;AAAA,MACA,qBAAqB,SAAS,MAAM,QAAQ;AAAA,MAC5C;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,YAAY,UAA6C,QAAyC;AAC9F,UAAM,MAAM;AAEZ,UAAM,EAAE,kBAAkB,IAAI;AAE9B,SAAK,YAAY,SAAS,IAAI,IAAI,YAAY;AAE9C,SAAK,YAAY;AACjB,SAAK,qBAAqB;AAG1B,SAAK,iBAAiB;AACtB,SAAK,kBAAkB,UAAQ;AAC3B,cAAQ,MAAM;AAAA,QACV,KAAK,kBAAkB,OAAO;AAAA,QAC9B,KAAK,kBAAkB,OAAO;AAAA,QAC9B,KAAK,kBAAkB,OAAO;AAAA,QAC9B,KAAK,kBAAkB,OAAO;AAC1B,eAAK,iBAAiB;AACtB;AAAA,MACR;AAAA,IACJ;AAEA,aAAS,UAAU,QAAQ,GAAG,KAAK,eAAe;AAAA,EACtD;AAAA,EAEA,OAAO,OAAO,YAAY,IAAI;AAC1B,SAAK,UAAU,UAAU,QAAQ,IAAI,KAAK,eAAe;AACzD,UAAM,KAAK,MAAM;AACjB,SAAK,mBAAmB,MAAM;AAAA,EAClC;AAAA,EAEA,mBAAmB;AACf,SAAK,sBAAsB;AAAA,EAC/B;AAAA,EAEA,MAAe,cAAc,UAAyC;AAQlE;AAAA;AANA,UAAI,KAAK,uBAAuB,KAAK,WAAW;AAC5C;AAAA,MACJ;AAIA,YAAM,WAAW,qBAAK,UAAU,MAAM,WAAW,SAAS,QAAQ,GAAG,SAAS,EAAE,CAAC,EAAE;AACnF,MAAC,SAA0B,WAAW,IAAI;AAG1C,aAAO,IAAI,2BAA2B,QAAQ,EACzC,cAAc,IAAI,EAClB,QAAQ,MAAM,OAAQ,SAA0B,WAAW,CAAC;AAAA,aANjE;AAAA;AAAA;AAAA;AAAA;AAAA,EAOJ;AAAA,EAEA,IAAI,YAAY;AACZ,QAAI,KAAK,eAAe,QAAW;AAC/B,aAAO,KAAK;AAAA,IAChB;AACA,UAAM,YAAY,KAAK,UAAU,IAAI,WAAS,MAAM,IAAI,mBAAmB,CAAC;AAC5E,QAAI,aAAa,GAAG,SAAS,GAAG;AAC5B,YAAM,IAAI,cAAc,oDAAoD;AAAA,IAChF;AACA,WAAQ,KAAK,aAAa;AAAA,EAC9B;AAAA,EAEA,MAAyB,cACrB,MACA,WACA,UACA,gBACA,SACA,
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterDevice } from \"../../MatterDevice.js\";\nimport { AccessControl } from \"../../behavior/AccessControl.js\";\nimport { ActionContext } from \"../../behavior/context/ActionContext.js\";\nimport { ActionTracer } from \"../../behavior/context/ActionTracer.js\";\nimport { NodeActivity } from \"../../behavior/context/NodeActivity.js\";\nimport { OfflineContext } from \"../../behavior/context/server/OfflineContext.js\";\nimport { OnlineContext } from \"../../behavior/context/server/OnlineContext.js\";\nimport { AccessControlServer } from \"../../behavior/definitions/access-control/AccessControlServer.js\";\nimport { BasicInformationServer } from \"../../behavior/definitions/basic-information/BasicInformationServer.js\";\nimport { AccessControlCluster } from \"../../cluster/definitions/AccessControlCluster.js\";\nimport { AnyAttributeServer, AttributeServer } from \"../../cluster/server/AttributeServer.js\";\nimport { CommandServer } from \"../../cluster/server/CommandServer.js\";\nimport { AnyEventServer } from \"../../cluster/server/EventServer.js\";\nimport { Message } from \"../../codec/MessageCodec.js\";\nimport { InternalError } from \"../../common/MatterError.js\";\nimport { Endpoint } from \"../../endpoint/Endpoint.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { EndpointServer } from \"../../endpoint/EndpointServer.js\";\nimport { EndpointLifecycle } from \"../../endpoint/properties/EndpointLifecycle.js\";\nimport { Diagnostic } from \"../../log/Diagnostic.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { AccessDeniedError } from \"../../protocol/interaction/AccessControlManager.js\";\nimport { EventStorageData } from \"../../protocol/interaction/EventHandler.js\";\nimport { InteractionEndpointStructure } from \"../../protocol/interaction/InteractionEndpointStructure.js\";\nimport {\n InteractionServerMessenger,\n WriteRequest,\n WriteResponse,\n} from \"../../protocol/interaction/InteractionMessenger.js\";\nimport { TlvEventFilter } from \"../../protocol/interaction/InteractionProtocol.js\";\nimport {\n AttributePath,\n CommandPath,\n EventPath,\n InteractionServer,\n} from \"../../protocol/interaction/InteractionServer.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport { MaybePromise } from \"../../util/Promises.js\";\nimport { ServerNode } from \"../ServerNode.js\";\n\nconst activityKey = Symbol(\"activity\");\n\ninterface WithActivity {\n [activityKey]?: NodeActivity.Activity;\n}\n\nconst AclClusterId = AccessControlCluster.id;\nconst AclAttributeId = AccessControlCluster.attributes.acl.id;\n\n/**\n * Wire up an InteractionServer that initializes an InvocationContext earlier than the cluster API supports.\n *\n * This is necessary for attributes because the ClusterServer attribute APIs are synchronous while transaction\n * management is asynchronous.\n *\n * It's not necessary for command handling because that API is entirely async. We do it here, however, just for the\n * sake of consistency.\n *\n * This could be integrated directly into InteractionServer but this further refactoring is probably warranted there\n * regardless. This keeps the touch light for now.\n */\nexport class TransactionalInteractionServer extends InteractionServer {\n #endpointStructure: InteractionEndpointStructure;\n #changeListener: (type: EndpointLifecycle.Change) => void;\n #endpoint: Endpoint<ServerNode.RootEndpoint>;\n #activity: NodeActivity;\n #newActivityBlocked = false;\n #aclServer?: AccessControlServer;\n #aclUpdateIsDelayed = false;\n\n static async create(endpoint: Endpoint<ServerNode.RootEndpoint>) {\n const endpointStructure = new InteractionEndpointStructure();\n\n const maxPathsPerInvoke = await endpoint.act(\n agent => agent.get(BasicInformationServer).state.maxPathsPerInvoke,\n );\n\n return new TransactionalInteractionServer(endpoint, {\n endpointStructure,\n subscriptionOptions: endpoint.state.network.subscriptionOptions,\n maxPathsPerInvoke,\n });\n }\n\n constructor(endpoint: Endpoint<ServerNode.RootEndpoint>, config: InteractionServer.Configuration) {\n super(config);\n\n const { endpointStructure } = config;\n\n this.#activity = endpoint.env.get(NodeActivity);\n\n this.#endpoint = endpoint;\n this.#endpointStructure = endpointStructure;\n\n // TODO - rewrite element lookup so we don't need to build the secondary endpoint structure cache\n this.#updateStructure();\n this.#changeListener = type => {\n switch (type) {\n case EndpointLifecycle.Change.PartsReady:\n case EndpointLifecycle.Change.ClientsChanged:\n case EndpointLifecycle.Change.ServersChanged:\n case EndpointLifecycle.Change.Destroyed:\n this.#updateStructure();\n break;\n }\n };\n\n endpoint.lifecycle.changed.on(this.#changeListener);\n }\n\n async [Symbol.asyncDispose]() {\n this.#endpoint.lifecycle.changed.off(this.#changeListener);\n await this.close();\n this.#endpointStructure.close();\n }\n\n blockNewActivity() {\n this.#newActivityBlocked = true;\n }\n\n override async onNewExchange(exchange: MessageExchange<MatterDevice>) {\n // When closing, ignore anything newly incoming\n if (this.#newActivityBlocked || this.isClosing) {\n return;\n }\n\n // Activity tracking. This provides diagnostic information and prevents the server from shutting down whilst\n // the exchange is active\n using activity = this.#activity.begin(`session#${exchange.session.id.toString(16)}`);\n (exchange as WithActivity)[activityKey] = activity;\n\n // Delegate to InteractionServerMessenger\n return new InteractionServerMessenger(exchange)\n .handleRequest(this)\n .finally(() => delete (exchange as WithActivity)[activityKey]);\n }\n\n get aclServer() {\n if (this.#aclServer !== undefined) {\n return this.#aclServer;\n }\n const aclServer = this.#endpoint.act(agent => agent.get(AccessControlServer));\n if (MaybePromise.is(aclServer)) {\n throw new InternalError(\"AccessControlServer should already be initialized.\");\n }\n return (this.#aclServer = aclServer);\n }\n\n protected override async readAttribute(\n path: AttributePath,\n attribute: AnyAttributeServer<any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n offline = false,\n ) {\n const readAttribute = () =>\n super.readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint, offline);\n\n // Offline read do not require ACL checks\n if (offline) {\n return OfflineContext.act(\"offline-read\", this.#activity, readAttribute);\n }\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n exchange,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readAttribute);\n }\n\n protected override async readEvent(\n path: EventPath,\n eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined,\n event: AnyEventServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ): Promise<EventStorageData<any>[]> {\n const readEvent = (context: ActionContext) => {\n if (!context.authorizedFor(event.readAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.readEvent(path, eventFilters, event, exchange, fabricFiltered, message, endpoint);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n exchange,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readEvent);\n }\n\n override async handleWriteRequest(\n exchange: MessageExchange<MatterDevice>,\n writeRequest: WriteRequest,\n message: Message,\n ): Promise<WriteResponse> {\n const result = await super.handleWriteRequest(exchange, writeRequest, message);\n\n // We delayed the ACL update during the write transaction, so we need to update it now that anything is written\n if (this.#aclUpdateIsDelayed) {\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n return result;\n }\n\n protected override async writeAttribute(\n path: AttributePath,\n attribute: AttributeServer<any>,\n value: any,\n exchange: MessageExchange<MatterDevice>,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n isListWrite?: boolean,\n ) {\n const writeAttribute = () =>\n super.writeAttribute(path, attribute, value, exchange, message, endpoint, timed, isListWrite);\n\n if (path.endpointId === 0 && path.clusterId === AclClusterId && path.attributeId === AclAttributeId) {\n // This is a hack to prevent the ACL from updating while we are in the middle of a write transaction\n // and is needed because Acl should not become effective during writing of the ACL itself.\n this.aclServer.aclUpdateDelayed = true;\n this.#aclUpdateIsDelayed = true;\n } else if (this.#aclUpdateIsDelayed) {\n // Ok it seems that acl was written, but we now write another path, so we can update Acl attribute now\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n timed,\n message,\n exchange,\n fabricFiltered: true,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Write,\n endpoint,\n root: this.#endpoint,\n }).act(writeAttribute);\n }\n\n protected override async invokeCommand(\n path: CommandPath,\n command: CommandServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n commandFields: any,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n ) {\n const invokeCommand = (context: ActionContext) => {\n if (!context.authorizedFor(command.invokeAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.invokeCommand(path, command, exchange, commandFields, message, endpoint, timed);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n command: true,\n timed,\n message,\n exchange,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Invoke,\n endpoint,\n root: this.#endpoint,\n }).act(invokeCommand);\n }\n\n get #tracer() {\n if (this.#endpoint.env.has(ActionTracer)) {\n return this.#endpoint.env.get(ActionTracer);\n }\n }\n\n #updateStructure() {\n if (this.#endpoint.lifecycle.isPartsReady) {\n this.#endpointStructure.initializeFromEndpoint(EndpointServer.forEndpoint(this.#endpoint));\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccessControlManager.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/AccessControlManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAGlF,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAGxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAc,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAIlE,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,aAAa,CAAC,qBAAqB,CAAC,EAAE,WAAW,CAAC,GAAG;IACzG,SAAS,EAAE,WAAW,CAAC;CAC1B,CAAC;AACF,MAAM,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;AAEjC,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,OAAO,aAAa,CAAC,yBAAyB,CAAC,CAAC;AACrG,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;AAUnD,aAAK,YAAY;IACb,IAAI,IAAI;CACX;AAED,MAAM,MAAM,yBAAyB,GAAG;IACpC,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC,0BAA0B,GAAG,YAAY,CAAC;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;CAC5B,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,mBAAmB;gBAC1C,OAAO,CAAC,EAAE,MAAM;CAG/B;AAED;;GAEG;AACH,qBAAa,oBAAoB;;gBAWzB,OAAO,GAAE,aAAa,CAAC,kBAAkB,EAAO,EAChD,yBAAyB,CAAC,EAAE,CACxB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,yBAAyB,EACtC,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,SAAS,KACnB,OAAO;IAQhB;;OAEG;IACH,uBAAuB,CAAC,OAAO,GAAE,aAAa,CAAC,kBAAkB,EAAO,GAAG,IAAI;IAyD/E;;OAEG;IACH,eAAe,CACX,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,EAC3B,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,WAAW,GACvB,OAAO;
|
|
1
|
+
{"version":3,"file":"AccessControlManager.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/AccessControlManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAGlF,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAGxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAc,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAIlE,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,aAAa,CAAC,qBAAqB,CAAC,EAAE,WAAW,CAAC,GAAG;IACzG,SAAS,EAAE,WAAW,CAAC;CAC1B,CAAC;AACF,MAAM,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;AAEjC,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,OAAO,aAAa,CAAC,yBAAyB,CAAC,CAAC;AACrG,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;AAUnD,aAAK,YAAY;IACb,IAAI,IAAI;CACX;AAED,MAAM,MAAM,yBAAyB,GAAG;IACpC,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC,0BAA0B,GAAG,YAAY,CAAC;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;CAC5B,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,mBAAmB;gBAC1C,OAAO,CAAC,EAAE,MAAM;CAG/B;AAED;;GAEG;AACH,qBAAa,oBAAoB;;gBAWzB,OAAO,GAAE,aAAa,CAAC,kBAAkB,EAAO,EAChD,yBAAyB,CAAC,EAAE,CACxB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,yBAAyB,EACtC,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,SAAS,KACnB,OAAO;IAQhB;;OAEG;IACH,uBAAuB,CAAC,OAAO,GAAE,aAAa,CAAC,kBAAkB,EAAO,GAAG,IAAI;IAyD/E;;OAEG;IACH,eAAe,CACX,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,EAC3B,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,WAAW,GACvB,OAAO;IAoBV;;OAEG;IACH,oBAAoB,CAChB,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,EAC3B,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,SAAS,GACrB,WAAW,EAAE;CA8KnB"}
|
|
@@ -99,10 +99,14 @@ class AccessControlManager {
|
|
|
99
99
|
return true;
|
|
100
100
|
}
|
|
101
101
|
logger.notice(
|
|
102
|
-
`Failed access control check for ${endpoint.number}
|
|
102
|
+
`Failed access control check for ${endpoint.number}/0x${toHex(clusterId)} and fabricIndex ${session.associatedFabric.fabricIndex}, acl=`,
|
|
103
103
|
this.#getAccessControlEntriesForFabric(session.associatedFabric),
|
|
104
|
+
"with ISD=",
|
|
105
|
+
this.#getIsdFromMessage(session),
|
|
104
106
|
"granted privileges=",
|
|
105
|
-
grantedPrivileges
|
|
107
|
+
grantedPrivileges,
|
|
108
|
+
"not contains",
|
|
109
|
+
privilege
|
|
106
110
|
);
|
|
107
111
|
return false;
|
|
108
112
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/protocol/interaction/AccessControlManager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2023 Project CHIP Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { AccessLevel } from \"../../cluster/Cluster.js\";\nimport { AccessControl } from \"../../cluster/definitions/AccessControlCluster.js\";\nimport { MatterFlowError } from \"../../common/MatterError.js\";\nimport { CaseAuthenticatedTag } from \"../../datatype/CaseAuthenticatedTag.js\";\nimport { ClusterId } from \"../../datatype/ClusterId.js\";\nimport { FabricIndex } from \"../../datatype/FabricIndex.js\";\nimport { NodeId } from \"../../datatype/NodeId.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { Fabric } from \"../../fabric/Fabric.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { TypeFromBitmapSchema } from \"../../schema/BitmapSchema.js\";\nimport { SecureSession } from \"../../session/SecureSession.js\";\nimport { toHex } from \"../../util/Number.js\";\nimport { StatusCode, StatusResponseError } from \"./StatusCode.js\";\n\nconst logger = Logger.get(\"AccessControlManager\");\n\nexport type AclEntry = Omit<TypeFromBitmapSchema<typeof AccessControl.TlvAccessControlEntry>, \"privilege\"> & {\n privilege: AccessLevel;\n};\nexport type AclList = AclEntry[];\n\nexport type AclExtensionEntry = TypeFromBitmapSchema<typeof AccessControl.TlvAccessControlExtension>;\nexport type AclExtensionList = AclExtensionEntry[];\n\nconst ImplicitDefaultPaseAclEntry: AclEntry = {\n fabricIndex: FabricIndex.NO_FABRIC, // not fabric-specific\n privilege: AccessLevel.Administer,\n authMode: AccessControl.AccessControlEntryAuthMode.Pase,\n subjects: [],\n targets: [], // entire node\n};\n\nenum AuthModeNone {\n None = 0,\n}\n\nexport type IncomingSubjectDescriptor = {\n isCommissioning: boolean;\n authMode: AccessControl.AccessControlEntryAuthMode | AuthModeNone;\n subjects: NodeId[];\n fabricIndex: FabricIndex;\n};\n\nexport class AccessDeniedError extends StatusResponseError {\n constructor(message?: string) {\n super(message ?? \"Unauthorized\", StatusCode.UnsupportedAccess);\n }\n}\n\n/**\n * Implements Access Control Logic as per Matter Specification @see {@link MatterSpecification.v12.Core} \u00A7 6.6.5.2.\n */\nexport class AccessControlManager {\n #aclList: AclList;\n #extensionEntryAccessCheck: (\n aclList: AclList,\n aclEntry: AclEntry,\n subjectDesc: IncomingSubjectDescriptor,\n endpoint: EndpointInterface,\n clusterId: ClusterId,\n ) => boolean = () => true;\n\n constructor(\n aclList: AccessControl.AccessControlEntry[] = [],\n extensionEntryAccessCheck?: (\n aclList: AclList,\n aclEntry: AclEntry,\n subjectDesc: IncomingSubjectDescriptor,\n endpoint: EndpointInterface,\n clusterId: ClusterId,\n ) => boolean,\n ) {\n this.#aclList = aclList as unknown as AclList; // It is the same structure we just use an internal type for privilege\n if (extensionEntryAccessCheck !== undefined) {\n this.#extensionEntryAccessCheck = extensionEntryAccessCheck;\n }\n }\n\n /**\n * Public method used to update the Access Control List on changes.\n */\n updateAccessControlList(aclList: AccessControl.AccessControlEntry[] = []): void {\n this.#aclList = [...aclList] as unknown as AclList; // It is the same structure we just use an internal type for privilege\n }\n\n /**\n * Get the Access Control List for a given fabric.\n */\n #getAccessControlEntriesForFabric(fabric: Fabric): AclList {\n return this.#aclList.filter(entry => entry.fabricIndex === fabric.fabricIndex);\n }\n\n /**\n * Subjects must match exactly, or both are CAT with matching CAT ID and acceptable CAT version\n */\n #subjectMatches(aclSubject: NodeId, isdSubject: NodeId): boolean {\n if (aclSubject === isdSubject) {\n return true;\n }\n if (!NodeId.isCaseAuthenticatedTag(aclSubject) || !NodeId.isCaseAuthenticatedTag(isdSubject)) {\n return false;\n }\n const aclSubjectCat = NodeId.extractAsCaseAuthenticatedTag(aclSubject);\n const isdSubjectCat = NodeId.extractAsCaseAuthenticatedTag(isdSubject);\n return (\n CaseAuthenticatedTag.getIdentifyValue(aclSubjectCat) ===\n CaseAuthenticatedTag.getIdentifyValue(isdSubjectCat) &&\n CaseAuthenticatedTag.getVersion(isdSubjectCat) >= CaseAuthenticatedTag.getVersion(aclSubjectCat)\n );\n }\n\n /**\n * Add the new privilege to the granted privileges set and also add any privileges subsumed by the new privilege.\n */\n #addGrantedPrivilege(grantedPrivileges: Set<AccessLevel>, privilege: AccessLevel): void {\n // Add the new privilege to the granted privileges set\n grantedPrivileges.add(privilege);\n // Also add any privileges subsumed by the new privilege\n switch (privilege) {\n case AccessLevel.ProxyView:\n grantedPrivileges.add(AccessLevel.View);\n break;\n case AccessLevel.Operate:\n grantedPrivileges.add(AccessLevel.View);\n break;\n case AccessLevel.Manage:\n grantedPrivileges.add(AccessLevel.Operate);\n grantedPrivileges.add(AccessLevel.View);\n break;\n case AccessLevel.Administer:\n grantedPrivileges.add(AccessLevel.Manage);\n grantedPrivileges.add(AccessLevel.Operate);\n grantedPrivileges.add(AccessLevel.ProxyView);\n grantedPrivileges.add(AccessLevel.View);\n break;\n }\n }\n\n /**\n * Check if the given ACL entry is allowed to be used for the given subject descriptor, endpoint, and cluster ID.\n */\n allowsPrivilege(\n session: SecureSession<any>,\n endpoint: EndpointInterface,\n clusterId: ClusterId,\n privilege: AccessLevel,\n ): boolean {\n const grantedPrivileges = this.getGrantedPrivileges(session, endpoint, clusterId);\n if (grantedPrivileges.includes(privilege)) {\n return true;\n }\n\n logger.notice(\n `Failed access control check for ${endpoint.number}/${toHex(clusterId)} and fabricIndex ${session.associatedFabric.fabricIndex}, acl=`,\n this.#getAccessControlEntriesForFabric(session.associatedFabric),\n \"granted privileges=\",\n grantedPrivileges,\n );\n\n return false;\n }\n\n /**\n * Determines the granted privileges for the given session, endpoint, and cluster ID and returns them.\n */\n getGrantedPrivileges(\n session: SecureSession<any>,\n endpoint: EndpointInterface,\n clusterId: ClusterId,\n ): AccessLevel[] {\n const endpointId = endpoint.number;\n const fabric = session.fabric;\n const subjectDesc = this.#getIsdFromMessage(session);\n const acl = fabric ? this.#getAccessControlEntriesForFabric(fabric) : [ImplicitDefaultPaseAclEntry];\n\n // Granted privileges set is initially empty\n const grantedPrivileges = new Set<AccessLevel>();\n\n // PASE commissioning channel implicitly grants administer privilege to commissioner\n if (subjectDesc.authMode === AccessControl.AccessControlEntryAuthMode.Pase && subjectDesc.isCommissioning) {\n this.#addGrantedPrivilege(grantedPrivileges, AccessLevel.Administer);\n }\n\n for (const aclEntry of acl) {\n if (grantedPrivileges.has(AccessLevel.Administer)) {\n // End checking if highest privilege is granted\n break;\n }\n\n // Fabric index must match, there are no valid entries with FabricIndex == 0\n // other than the implicit PASE entry, which we will not see explicitly in the\n // access control list\n if (aclEntry.fabricIndex === FabricIndex.NO_FABRIC || aclEntry.fabricIndex !== subjectDesc.fabricIndex) {\n logger.debug(\n \"Skipping ACL entry with mismatched fabric index\",\n aclEntry.fabricIndex,\n subjectDesc.fabricIndex,\n );\n continue;\n }\n\n // Auth mode must match\n if (aclEntry.authMode !== subjectDesc.authMode) {\n logger.debug(\"Skipping ACL entry with mismatched auth mode\", aclEntry.authMode, subjectDesc.authMode);\n continue;\n }\n\n // Subject must match, or be \"wildcard\"\n if (aclEntry.subjects === null || aclEntry.subjects.length === 0) {\n // Precondition: only CASE and Group auth can have empty subjects\n if (\n aclEntry.authMode !== AccessControl.AccessControlEntryAuthMode.Case &&\n aclEntry.authMode !== AccessControl.AccessControlEntryAuthMode.Group\n ) {\n throw new MatterFlowError(\"ACL error: only CASE and Group auth can have empty subjects\");\n }\n // ... Empty is wildcard, no match required\n } else {\n // Non-empty requires a match\n let matchedSubject = false;\n subjectLoop: for (const aclSubject of aclEntry.subjects) {\n for (const isdSubject of subjectDesc.subjects) {\n if (this.#subjectMatches(aclSubject, isdSubject)) {\n matchedSubject = true;\n break subjectLoop;\n }\n }\n }\n if (!matchedSubject) {\n continue;\n }\n }\n\n // Target must match, or be \"wildcard\"\n if (aclEntry.targets === null || aclEntry.targets.length === 0) {\n // Empty is wildcard, no match required\n } else {\n // Non-empty requires a match\n let matchedTarget = false;\n for (const {\n cluster: targetClusterId,\n endpoint: targetEndpointId,\n deviceType: targetDeviceType,\n } of aclEntry.targets) {\n // Precondition: target cannot be empty\n if (targetClusterId === null && targetEndpointId === null && targetDeviceType === null) {\n throw new MatterFlowError(\"ACL error: target cannot be empty\");\n }\n // Precondition: target cannot specify both endpoint and device type\n if (targetEndpointId !== null && targetDeviceType !== null) {\n throw new MatterFlowError(\"ACL error: target cannot specify both endpoint and device type\");\n }\n // Cluster must match, or be wildcard\n if (targetClusterId !== null && targetClusterId !== clusterId) {\n continue;\n }\n // Endpoint must match, or be wildcard\n if (targetEndpointId !== null && targetEndpointId !== endpointId) {\n continue;\n }\n // Endpoint may be specified indirectly via device type\n // TODO adjust to array check once we use multiple devicetypes\n if (targetDeviceType !== null && endpoint.deviceType !== targetDeviceType) {\n continue;\n }\n matchedTarget = true;\n break;\n }\n if (!matchedTarget) {\n continue;\n }\n }\n\n // Extensions processing must not fail\n if (!this.#extensionEntryAccessCheck(acl, aclEntry, subjectDesc, endpoint, clusterId)) {\n continue;\n }\n\n // All checks have passed, add privilege to granted privilege set\n this.#addGrantedPrivilege(grantedPrivileges, aclEntry.privilege);\n }\n // Should never grant Administer privilege to a Group.\n if (\n subjectDesc.authMode === AccessControl.AccessControlEntryAuthMode.Group &&\n grantedPrivileges.has(AccessLevel.Administer)\n ) {\n throw new MatterFlowError(\"ACL error: should never grant Administer privilege to a Group\");\n }\n\n return [...grantedPrivileges];\n }\n\n /**\n * Determines the Incoming Subject Descriptor (ISD) from the given session.\n */\n #getIsdFromMessage(session: SecureSession<any>) {\n const fabric = session.fabric;\n const isd: IncomingSubjectDescriptor = {\n isCommissioning: false,\n authMode: AuthModeNone.None,\n subjects: new Array<NodeId>(),\n fabricIndex: FabricIndex.NO_FABRIC,\n };\n\n if (session.isPase) {\n isd.authMode = AccessControl.AccessControlEntryAuthMode.Pase;\n isd.isCommissioning = true; // Or how \"commissioning channel\" is defined?\n isd.subjects.push(NodeId(0)); // Default Commissioning Passcode ID\n if (fabric) {\n isd.fabricIndex = fabric.fabricIndex;\n }\n } else {\n // TODO Add Group session handling when implementing groups\n // if (session instanceof SecureGroupSession) {\n // Groups\n // # Message is assumed to have been decrypted and matched properly prior to\n // # this procedure occurring.\n // group_id = message.get_dst_group_id()\n // group_key_id = sessions_metadata.get_group_key_id(message)\n // # Group membership must be verified against Group Key Management Cluster\n // if group_key_management_cluster.group_key_map_has_mapping(group_id, group_key_id):\n // isd.AuthMode = AuthModeEnum.Group\n // isd.Subjects.append(group_id)\n // isd.FabricIndex = sessions_metadata.get_fabric_index(message)\n // assert(isd.FabricIndex != 0) # cannot be zero\n //\n // isd.authMode = AccessControl.AccessControlEntryAuthMode.Group;\n // } else {\n\n // CASE session\n isd.authMode = AccessControl.AccessControlEntryAuthMode.Case;\n isd.subjects.push(session.peerNodeId);\n // Append CASE session CATs which also serve as subjects\n session.caseAuthenticatedTags.forEach(cat => isd.subjects.push(NodeId.fromCaseAuthenticatedTag(cat)));\n // }\n if (fabric === undefined) {\n throw new MatterFlowError(\"ACL error: fabric is undefined\");\n }\n isd.fabricIndex = fabric.fabricIndex;\n }\n\n return isd;\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AAErC,SAAS,mBAAmB;AAC5B,SAAS,cAAc;AAGvB,SAAS,cAAc;AAGvB,SAAS,aAAa;AACtB,SAAS,YAAY,2BAA2B;AAEhD,MAAM,SAAS,OAAO,IAAI,sBAAsB;AAUhD,MAAM,8BAAwC;AAAA,EAC1C,aAAa,YAAY;AAAA;AAAA,EACzB,WAAW,YAAY;AAAA,EACvB,UAAU,cAAc,2BAA2B;AAAA,EACnD,UAAU,CAAC;AAAA,EACX,SAAS,CAAC;AAAA;AACd;AAEA,IAAK,eAAL,kBAAKA,kBAAL;AACI,EAAAA,4BAAA,UAAO,KAAP;AADC,SAAAA;AAAA,GAAA;AAWE,MAAM,0BAA0B,oBAAoB;AAAA,EACvD,YAAY,SAAkB;AAC1B,UAAM,WAAW,gBAAgB,WAAW,iBAAiB;AAAA,EACjE;AACJ;AAKO,MAAM,qBAAqB;AAAA,EAC9B;AAAA,EACA,6BAMe,MAAM;AAAA,EAErB,YACI,UAA8C,CAAC,GAC/C,2BAOF;AACE,SAAK,WAAW;AAChB,QAAI,8BAA8B,QAAW;AACzC,WAAK,6BAA6B;AAAA,IACtC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB,UAA8C,CAAC,GAAS;AAC5E,SAAK,WAAW,CAAC,GAAG,OAAO;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,kCAAkC,QAAyB;AACvD,WAAO,KAAK,SAAS,OAAO,WAAS,MAAM,gBAAgB,OAAO,WAAW;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,YAAoB,YAA6B;AAC7D,QAAI,eAAe,YAAY;AAC3B,aAAO;AAAA,IACX;AACA,QAAI,CAAC,OAAO,uBAAuB,UAAU,KAAK,CAAC,OAAO,uBAAuB,UAAU,GAAG;AAC1F,aAAO;AAAA,IACX;AACA,UAAM,gBAAgB,OAAO,8BAA8B,UAAU;AACrE,UAAM,gBAAgB,OAAO,8BAA8B,UAAU;AACrE,WACI,qBAAqB,iBAAiB,aAAa,MAC/C,qBAAqB,iBAAiB,aAAa,KACvD,qBAAqB,WAAW,aAAa,KAAK,qBAAqB,WAAW,aAAa;AAAA,EAEvG;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,mBAAqC,WAA8B;AAEpF,sBAAkB,IAAI,SAAS;AAE/B,YAAQ,WAAW;AAAA,MACf,KAAK,YAAY;AACb,0BAAkB,IAAI,YAAY,IAAI;AACtC;AAAA,MACJ,KAAK,YAAY;AACb,0BAAkB,IAAI,YAAY,IAAI;AACtC;AAAA,MACJ,KAAK,YAAY;AACb,0BAAkB,IAAI,YAAY,OAAO;AACzC,0BAAkB,IAAI,YAAY,IAAI;AACtC;AAAA,MACJ,KAAK,YAAY;AACb,0BAAkB,IAAI,YAAY,MAAM;AACxC,0BAAkB,IAAI,YAAY,OAAO;AACzC,0BAAkB,IAAI,YAAY,SAAS;AAC3C,0BAAkB,IAAI,YAAY,IAAI;AACtC;AAAA,IACR;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,gBACI,SACA,UACA,WACA,WACO;AACP,UAAM,oBAAoB,KAAK,qBAAqB,SAAS,UAAU,SAAS;AAChF,QAAI,kBAAkB,SAAS,SAAS,GAAG;AACvC,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,MACH,mCAAmC,SAAS,MAAM,
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2023 Project CHIP Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { AccessLevel } from \"../../cluster/Cluster.js\";\nimport { AccessControl } from \"../../cluster/definitions/AccessControlCluster.js\";\nimport { MatterFlowError } from \"../../common/MatterError.js\";\nimport { CaseAuthenticatedTag } from \"../../datatype/CaseAuthenticatedTag.js\";\nimport { ClusterId } from \"../../datatype/ClusterId.js\";\nimport { FabricIndex } from \"../../datatype/FabricIndex.js\";\nimport { NodeId } from \"../../datatype/NodeId.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { Fabric } from \"../../fabric/Fabric.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { TypeFromBitmapSchema } from \"../../schema/BitmapSchema.js\";\nimport { SecureSession } from \"../../session/SecureSession.js\";\nimport { toHex } from \"../../util/Number.js\";\nimport { StatusCode, StatusResponseError } from \"./StatusCode.js\";\n\nconst logger = Logger.get(\"AccessControlManager\");\n\nexport type AclEntry = Omit<TypeFromBitmapSchema<typeof AccessControl.TlvAccessControlEntry>, \"privilege\"> & {\n privilege: AccessLevel;\n};\nexport type AclList = AclEntry[];\n\nexport type AclExtensionEntry = TypeFromBitmapSchema<typeof AccessControl.TlvAccessControlExtension>;\nexport type AclExtensionList = AclExtensionEntry[];\n\nconst ImplicitDefaultPaseAclEntry: AclEntry = {\n fabricIndex: FabricIndex.NO_FABRIC, // not fabric-specific\n privilege: AccessLevel.Administer,\n authMode: AccessControl.AccessControlEntryAuthMode.Pase,\n subjects: [],\n targets: [], // entire node\n};\n\nenum AuthModeNone {\n None = 0,\n}\n\nexport type IncomingSubjectDescriptor = {\n isCommissioning: boolean;\n authMode: AccessControl.AccessControlEntryAuthMode | AuthModeNone;\n subjects: NodeId[];\n fabricIndex: FabricIndex;\n};\n\nexport class AccessDeniedError extends StatusResponseError {\n constructor(message?: string) {\n super(message ?? \"Unauthorized\", StatusCode.UnsupportedAccess);\n }\n}\n\n/**\n * Implements Access Control Logic as per Matter Specification @see {@link MatterSpecification.v12.Core} \u00A7 6.6.5.2.\n */\nexport class AccessControlManager {\n #aclList: AclList;\n #extensionEntryAccessCheck: (\n aclList: AclList,\n aclEntry: AclEntry,\n subjectDesc: IncomingSubjectDescriptor,\n endpoint: EndpointInterface,\n clusterId: ClusterId,\n ) => boolean = () => true;\n\n constructor(\n aclList: AccessControl.AccessControlEntry[] = [],\n extensionEntryAccessCheck?: (\n aclList: AclList,\n aclEntry: AclEntry,\n subjectDesc: IncomingSubjectDescriptor,\n endpoint: EndpointInterface,\n clusterId: ClusterId,\n ) => boolean,\n ) {\n this.#aclList = aclList as unknown as AclList; // It is the same structure we just use an internal type for privilege\n if (extensionEntryAccessCheck !== undefined) {\n this.#extensionEntryAccessCheck = extensionEntryAccessCheck;\n }\n }\n\n /**\n * Public method used to update the Access Control List on changes.\n */\n updateAccessControlList(aclList: AccessControl.AccessControlEntry[] = []): void {\n this.#aclList = [...aclList] as unknown as AclList; // It is the same structure we just use an internal type for privilege\n }\n\n /**\n * Get the Access Control List for a given fabric.\n */\n #getAccessControlEntriesForFabric(fabric: Fabric): AclList {\n return this.#aclList.filter(entry => entry.fabricIndex === fabric.fabricIndex);\n }\n\n /**\n * Subjects must match exactly, or both are CAT with matching CAT ID and acceptable CAT version\n */\n #subjectMatches(aclSubject: NodeId, isdSubject: NodeId): boolean {\n if (aclSubject === isdSubject) {\n return true;\n }\n if (!NodeId.isCaseAuthenticatedTag(aclSubject) || !NodeId.isCaseAuthenticatedTag(isdSubject)) {\n return false;\n }\n const aclSubjectCat = NodeId.extractAsCaseAuthenticatedTag(aclSubject);\n const isdSubjectCat = NodeId.extractAsCaseAuthenticatedTag(isdSubject);\n return (\n CaseAuthenticatedTag.getIdentifyValue(aclSubjectCat) ===\n CaseAuthenticatedTag.getIdentifyValue(isdSubjectCat) &&\n CaseAuthenticatedTag.getVersion(isdSubjectCat) >= CaseAuthenticatedTag.getVersion(aclSubjectCat)\n );\n }\n\n /**\n * Add the new privilege to the granted privileges set and also add any privileges subsumed by the new privilege.\n */\n #addGrantedPrivilege(grantedPrivileges: Set<AccessLevel>, privilege: AccessLevel): void {\n // Add the new privilege to the granted privileges set\n grantedPrivileges.add(privilege);\n // Also add any privileges subsumed by the new privilege\n switch (privilege) {\n case AccessLevel.ProxyView:\n grantedPrivileges.add(AccessLevel.View);\n break;\n case AccessLevel.Operate:\n grantedPrivileges.add(AccessLevel.View);\n break;\n case AccessLevel.Manage:\n grantedPrivileges.add(AccessLevel.Operate);\n grantedPrivileges.add(AccessLevel.View);\n break;\n case AccessLevel.Administer:\n grantedPrivileges.add(AccessLevel.Manage);\n grantedPrivileges.add(AccessLevel.Operate);\n grantedPrivileges.add(AccessLevel.ProxyView);\n grantedPrivileges.add(AccessLevel.View);\n break;\n }\n }\n\n /**\n * Check if the given ACL entry is allowed to be used for the given subject descriptor, endpoint, and cluster ID.\n */\n allowsPrivilege(\n session: SecureSession<any>,\n endpoint: EndpointInterface,\n clusterId: ClusterId,\n privilege: AccessLevel,\n ): boolean {\n const grantedPrivileges = this.getGrantedPrivileges(session, endpoint, clusterId);\n if (grantedPrivileges.includes(privilege)) {\n return true;\n }\n\n logger.notice(\n `Failed access control check for ${endpoint.number}/0x${toHex(clusterId)} and fabricIndex ${session.associatedFabric.fabricIndex}, acl=`,\n this.#getAccessControlEntriesForFabric(session.associatedFabric),\n \"with ISD=\",\n this.#getIsdFromMessage(session),\n \"granted privileges=\",\n grantedPrivileges,\n \"not contains\",\n privilege,\n );\n\n return false;\n }\n\n /**\n * Determines the granted privileges for the given session, endpoint, and cluster ID and returns them.\n */\n getGrantedPrivileges(\n session: SecureSession<any>,\n endpoint: EndpointInterface,\n clusterId: ClusterId,\n ): AccessLevel[] {\n const endpointId = endpoint.number;\n const fabric = session.fabric;\n const subjectDesc = this.#getIsdFromMessage(session);\n const acl = fabric ? this.#getAccessControlEntriesForFabric(fabric) : [ImplicitDefaultPaseAclEntry];\n\n // Granted privileges set is initially empty\n const grantedPrivileges = new Set<AccessLevel>();\n\n // PASE commissioning channel implicitly grants administer privilege to commissioner\n if (subjectDesc.authMode === AccessControl.AccessControlEntryAuthMode.Pase && subjectDesc.isCommissioning) {\n this.#addGrantedPrivilege(grantedPrivileges, AccessLevel.Administer);\n }\n\n for (const aclEntry of acl) {\n if (grantedPrivileges.has(AccessLevel.Administer)) {\n // End checking if highest privilege is granted\n break;\n }\n\n // Fabric index must match, there are no valid entries with FabricIndex == 0\n // other than the implicit PASE entry, which we will not see explicitly in the\n // access control list\n if (aclEntry.fabricIndex === FabricIndex.NO_FABRIC || aclEntry.fabricIndex !== subjectDesc.fabricIndex) {\n logger.debug(\n \"Skipping ACL entry with mismatched fabric index\",\n aclEntry.fabricIndex,\n subjectDesc.fabricIndex,\n );\n continue;\n }\n\n // Auth mode must match\n if (aclEntry.authMode !== subjectDesc.authMode) {\n logger.debug(\"Skipping ACL entry with mismatched auth mode\", aclEntry.authMode, subjectDesc.authMode);\n continue;\n }\n\n // Subject must match, or be \"wildcard\"\n if (aclEntry.subjects === null || aclEntry.subjects.length === 0) {\n // Precondition: only CASE and Group auth can have empty subjects\n if (\n aclEntry.authMode !== AccessControl.AccessControlEntryAuthMode.Case &&\n aclEntry.authMode !== AccessControl.AccessControlEntryAuthMode.Group\n ) {\n throw new MatterFlowError(\"ACL error: only CASE and Group auth can have empty subjects\");\n }\n // ... Empty is wildcard, no match required\n } else {\n // Non-empty requires a match\n let matchedSubject = false;\n subjectLoop: for (const aclSubject of aclEntry.subjects) {\n for (const isdSubject of subjectDesc.subjects) {\n if (this.#subjectMatches(aclSubject, isdSubject)) {\n matchedSubject = true;\n break subjectLoop;\n }\n }\n }\n if (!matchedSubject) {\n continue;\n }\n }\n\n // Target must match, or be \"wildcard\"\n if (aclEntry.targets === null || aclEntry.targets.length === 0) {\n // Empty is wildcard, no match required\n } else {\n // Non-empty requires a match\n let matchedTarget = false;\n for (const {\n cluster: targetClusterId,\n endpoint: targetEndpointId,\n deviceType: targetDeviceType,\n } of aclEntry.targets) {\n // Precondition: target cannot be empty\n if (targetClusterId === null && targetEndpointId === null && targetDeviceType === null) {\n throw new MatterFlowError(\"ACL error: target cannot be empty\");\n }\n // Precondition: target cannot specify both endpoint and device type\n if (targetEndpointId !== null && targetDeviceType !== null) {\n throw new MatterFlowError(\"ACL error: target cannot specify both endpoint and device type\");\n }\n // Cluster must match, or be wildcard\n if (targetClusterId !== null && targetClusterId !== clusterId) {\n continue;\n }\n // Endpoint must match, or be wildcard\n if (targetEndpointId !== null && targetEndpointId !== endpointId) {\n continue;\n }\n // Endpoint may be specified indirectly via device type\n // TODO adjust to array check once we use multiple devicetypes\n if (targetDeviceType !== null && endpoint.deviceType !== targetDeviceType) {\n continue;\n }\n matchedTarget = true;\n break;\n }\n if (!matchedTarget) {\n continue;\n }\n }\n\n // Extensions processing must not fail\n if (!this.#extensionEntryAccessCheck(acl, aclEntry, subjectDesc, endpoint, clusterId)) {\n continue;\n }\n\n // All checks have passed, add privilege to granted privilege set\n this.#addGrantedPrivilege(grantedPrivileges, aclEntry.privilege);\n }\n // Should never grant Administer privilege to a Group.\n if (\n subjectDesc.authMode === AccessControl.AccessControlEntryAuthMode.Group &&\n grantedPrivileges.has(AccessLevel.Administer)\n ) {\n throw new MatterFlowError(\"ACL error: should never grant Administer privilege to a Group\");\n }\n\n return [...grantedPrivileges];\n }\n\n /**\n * Determines the Incoming Subject Descriptor (ISD) from the given session.\n */\n #getIsdFromMessage(session: SecureSession<any>) {\n const fabric = session.fabric;\n const isd: IncomingSubjectDescriptor = {\n isCommissioning: false,\n authMode: AuthModeNone.None,\n subjects: new Array<NodeId>(),\n fabricIndex: FabricIndex.NO_FABRIC,\n };\n\n if (session.isPase) {\n isd.authMode = AccessControl.AccessControlEntryAuthMode.Pase;\n isd.isCommissioning = true; // Or how \"commissioning channel\" is defined?\n isd.subjects.push(NodeId(0)); // Default Commissioning Passcode ID\n if (fabric) {\n isd.fabricIndex = fabric.fabricIndex;\n }\n } else {\n // TODO Add Group session handling when implementing groups\n // if (session instanceof SecureGroupSession) {\n // Groups\n // # Message is assumed to have been decrypted and matched properly prior to\n // # this procedure occurring.\n // group_id = message.get_dst_group_id()\n // group_key_id = sessions_metadata.get_group_key_id(message)\n // # Group membership must be verified against Group Key Management Cluster\n // if group_key_management_cluster.group_key_map_has_mapping(group_id, group_key_id):\n // isd.AuthMode = AuthModeEnum.Group\n // isd.Subjects.append(group_id)\n // isd.FabricIndex = sessions_metadata.get_fabric_index(message)\n // assert(isd.FabricIndex != 0) # cannot be zero\n //\n // isd.authMode = AccessControl.AccessControlEntryAuthMode.Group;\n // } else {\n\n // CASE session\n isd.authMode = AccessControl.AccessControlEntryAuthMode.Case;\n isd.subjects.push(session.peerNodeId);\n // Append CASE session CATs which also serve as subjects\n session.caseAuthenticatedTags.forEach(cat => isd.subjects.push(NodeId.fromCaseAuthenticatedTag(cat)));\n // }\n if (fabric === undefined) {\n throw new MatterFlowError(\"ACL error: fabric is undefined\");\n }\n isd.fabricIndex = fabric.fabricIndex;\n }\n\n return isd;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["AuthModeNone"]
|
|
7
7
|
}
|
|
@@ -79,7 +79,7 @@ export declare class InteractionServer implements ProtocolHandler<MatterDevice>,
|
|
|
79
79
|
get maxPathsPerInvoke(): number;
|
|
80
80
|
onNewExchange(exchange: MessageExchange<MatterDevice>): Promise<void>;
|
|
81
81
|
handleReadRequest(exchange: MessageExchange<MatterDevice>, { attributeRequests, dataVersionFilters, eventRequests, eventFilters, isFabricFiltered, interactionModelRevision, }: ReadRequest, message: Message): Promise<DataReportPayload>;
|
|
82
|
-
protected readAttribute(_path: AttributePath, attribute: AnyAttributeServer<any>, exchange: MessageExchange<MatterDevice>, isFabricFiltered: boolean, message: Message, _endpoint: EndpointInterface): Promise<{
|
|
82
|
+
protected readAttribute(_path: AttributePath, attribute: AnyAttributeServer<any>, exchange: MessageExchange<MatterDevice>, isFabricFiltered: boolean, message: Message, _endpoint: EndpointInterface, offline?: boolean): Promise<{
|
|
83
83
|
version: number;
|
|
84
84
|
value: any;
|
|
85
85
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/InteractionServer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"InteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/InteractionServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -390,8 +390,8 @@ class InteractionServer {
|
|
|
390
390
|
eventReportsPayload
|
|
391
391
|
};
|
|
392
392
|
}
|
|
393
|
-
async readAttribute(_path, attribute, exchange, isFabricFiltered, message, _endpoint) {
|
|
394
|
-
return attribute.getWithVersion(exchange.session, isFabricFiltered, message);
|
|
393
|
+
async readAttribute(_path, attribute, exchange, isFabricFiltered, message, _endpoint, offline = false) {
|
|
394
|
+
return attribute.getWithVersion(exchange.session, isFabricFiltered, offline ? void 0 : message);
|
|
395
395
|
}
|
|
396
396
|
async readEvent(_path, eventFilters, event, exchange, isFabricFiltered, message, _endpoint) {
|
|
397
397
|
return event.get(exchange.session, isFabricFiltered, message, eventFilters);
|
|
@@ -703,13 +703,14 @@ class InteractionServer {
|
|
|
703
703
|
maxIntervalCeiling: maxIntervalCeilingSeconds,
|
|
704
704
|
cancelCallback: () => this.#subscriptionMap.delete(subscriptionId),
|
|
705
705
|
subscriptionOptions: this.#subscriptionConfig,
|
|
706
|
-
readAttribute: (path, attribute) => this.readAttribute(
|
|
706
|
+
readAttribute: (path, attribute, offline) => this.readAttribute(
|
|
707
707
|
path,
|
|
708
708
|
attribute,
|
|
709
709
|
exchange,
|
|
710
710
|
isFabricFiltered,
|
|
711
711
|
message,
|
|
712
|
-
this.#endpointStructure.getEndpoint(path.endpointId)
|
|
712
|
+
this.#endpointStructure.getEndpoint(path.endpointId),
|
|
713
|
+
offline
|
|
713
714
|
),
|
|
714
715
|
readEvent: (path, event, eventFilters2) => this.readEvent(
|
|
715
716
|
path,
|