From 2c4689d7ba6b77f5fa5dcebeff113ce1a33fbff4 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 21 Dec 2021 22:48:15 -0500 Subject: [PATCH] Revert "Add persistent storage for the example ACL implementation. (#12814)" This reverts commit 381fc553fc9ab589b49149f8cf199d7923da17b8 because that code was never reviewed and clearly wasn't tested either (it's comparing TLV::Tag values to tag numbers, which can't possibly work). --- src/access/AccessControlEntryCodec.h | 333 ------------------ src/access/BUILD.gn | 1 - .../examples/ExampleAccessControlDelegate.cpp | 128 +------ .../examples/ExampleAccessControlDelegate.h | 3 - .../access-control-server.cpp | 298 ++++++++++++++-- src/lib/support/DefaultStorageKeyAllocator.h | 5 - 6 files changed, 279 insertions(+), 489 deletions(-) delete mode 100644 src/access/AccessControlEntryCodec.h diff --git a/src/access/AccessControlEntryCodec.h b/src/access/AccessControlEntryCodec.h deleted file mode 100644 index 541ff4c1735ec1..00000000000000 --- a/src/access/AccessControlEntryCodec.h +++ /dev/null @@ -1,333 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include -#include - -namespace chip { -namespace Access { - -struct AccessControlEntryCodecConstants -{ - uint32_t encodedAuthPase; - uint32_t encodedAuthCase; - uint32_t encodedAuthGroup; - uint32_t encodedPrivilegeView; - uint32_t encodedPrivilegeProxyView; - uint32_t encodedPrivilegeOperate; - uint32_t encodedPrivilegeManage; - uint32_t encodedPrivilegeAdminister; - - TLV::Tag fabricIndexTag; - TLV::Tag privilegeTag; - TLV::Tag authModeTag; - TLV::Tag subjectsTag; - TLV::Tag targetsTag; - - TLV::Tag targetClusterTag; - TLV::Tag targetEndpointTag; - TLV::Tag targetDeviceTypeTag; -}; -static_assert(std::is_trivially_copyable::value, "Constants type must be trivially copyable"); - -template -class AccessControlEntryCodec -{ -public: - static_assert(std::is_base_of::value, - "T must inherit from AccessControlEntryCodecConstants"); - - AccessControlEntryCodec() : mConstants(T()) {} - - CHIP_ERROR Convert(AuthMode from, uint32_t & to) const - { - switch (from) - { - case AuthMode::kPase: - to = mConstants.encodedAuthPase; - break; - case AuthMode::kCase: - to = mConstants.encodedAuthCase; - break; - case AuthMode::kGroup: - to = mConstants.encodedAuthGroup; - break; - default: - return CHIP_ERROR_INVALID_ARGUMENT; - } - return CHIP_NO_ERROR; - } - - CHIP_ERROR Convert(uint32_t from, AuthMode & to) const - { - if (from == mConstants.encodedAuthPase) - { - to = AuthMode::kPase; - } - else if (from == mConstants.encodedAuthCase) - { - to = AuthMode::kCase; - } - else if (from == mConstants.encodedAuthGroup) - { - to = AuthMode::kGroup; - } - else - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - return CHIP_NO_ERROR; - } - - CHIP_ERROR Convert(Privilege from, uint32_t & to) const - { - switch (from) - { - case Privilege::kView: - to = mConstants.encodedPrivilegeView; - break; - case Privilege::kProxyView: - to = mConstants.encodedPrivilegeProxyView; - break; - case Privilege::kOperate: - to = mConstants.encodedPrivilegeOperate; - break; - case Privilege::kManage: - to = mConstants.encodedPrivilegeManage; - break; - case Privilege::kAdminister: - to = mConstants.encodedPrivilegeAdminister; - break; - default: - return CHIP_ERROR_INVALID_ARGUMENT; - } - return CHIP_NO_ERROR; - } - - CHIP_ERROR Convert(uint32_t from, Privilege & to) const - { - if (from == mConstants.encodedPrivilegeView) - { - to = Privilege::kView; - } - else if (from == mConstants.encodedPrivilegeProxyView) - { - to = Privilege::kProxyView; - } - else if (from == mConstants.encodedPrivilegeOperate) - { - to = Privilege::kOperate; - } - else if (from == mConstants.encodedPrivilegeManage) - { - to = Privilege::kManage; - } - else if (from == mConstants.encodedPrivilegeAdminister) - { - to = Privilege::kAdminister; - } - else - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - return CHIP_NO_ERROR; - } - - CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const - { - TLV::TLVType accessControlEntryContainer; - ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, accessControlEntryContainer)); - { - FabricIndex fabricIndex; - ReturnErrorOnFailure(entry.GetFabricIndex(fabricIndex)); - ReturnErrorOnFailure(aWriter.Put(mConstants.fabricIndexTag, fabricIndex)); - } - { - Privilege privilege; - ReturnErrorOnFailure(entry.GetPrivilege(privilege)); - uint32_t privilegeTemp; - ReturnErrorOnFailure(Convert(privilege, privilegeTemp)); - ReturnErrorOnFailure(aWriter.Put(mConstants.privilegeTag, privilegeTemp)); - } - { - AuthMode authMode; - ReturnErrorOnFailure(entry.GetAuthMode(authMode)); - uint32_t authModeTemp; - ReturnErrorOnFailure(Convert(authMode, authModeTemp)); - ReturnErrorOnFailure(aWriter.Put(mConstants.authModeTag, authModeTemp)); - } - { - size_t count = 0; - ReturnErrorOnFailure(entry.GetSubjectCount(count)); - if (count > 0) - { - TLV::TLVType subjectsContainer; - ReturnErrorOnFailure(aWriter.StartContainer(mConstants.subjectsTag, TLV::kTLVType_Array, subjectsContainer)); - for (size_t i = 0; i < count; ++i) - { - NodeId subject; - ReturnErrorOnFailure(entry.GetSubject(i, subject)); - ReturnErrorOnFailure(aWriter.Put(TLV::AnonymousTag, subject)); - } - ReturnErrorOnFailure(aWriter.EndContainer(subjectsContainer)); - } - } - { - size_t count = 0; - ReturnErrorOnFailure(entry.GetTargetCount(count)); - if (count > 0) - { - TLV::TLVType targetsContainer; - ReturnErrorOnFailure(aWriter.StartContainer(mConstants.targetsTag, TLV::kTLVType_Array, targetsContainer)); - for (size_t i = 0; i < count; ++i) - { - TLV::TLVType targetContainer; - ReturnErrorOnFailure(aWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, targetContainer)); - AccessControl::Entry::Target target; - ReturnErrorOnFailure(entry.GetTarget(i, target)); - if (target.flags & AccessControl::Entry::Target::kCluster) - { - ReturnErrorOnFailure(aWriter.Put(mConstants.targetClusterTag, target.cluster)); - } - if (target.flags & AccessControl::Entry::Target::kEndpoint) - { - ReturnErrorOnFailure(aWriter.Put(mConstants.targetEndpointTag, target.endpoint)); - } - if (target.flags & AccessControl::Entry::Target::kDeviceType) - { - ReturnErrorOnFailure(aWriter.Put(mConstants.targetDeviceTypeTag, target.deviceType)); - } - ReturnErrorOnFailure(aWriter.EndContainer(targetContainer)); - } - ReturnErrorOnFailure(aWriter.EndContainer(targetsContainer)); - } - } - ReturnErrorOnFailure(aWriter.EndContainer(accessControlEntryContainer)); - return CHIP_NO_ERROR; - } - - CHIP_ERROR Decode(TLV::TLVReader & aReader) - { - ReturnErrorOnFailure(GetAccessControl().PrepareEntry(entry)); - CHIP_ERROR err = CHIP_NO_ERROR; - TLV::TLVType accessControlEntryContainer; - VerifyOrReturnError(TLV::kTLVType_Structure == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); - ReturnErrorOnFailure(aReader.EnterContainer(accessControlEntryContainer)); - while ((err = aReader.Next()) == CHIP_NO_ERROR) - { - VerifyOrReturnError(TLV::IsContextTag(aReader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG); - auto tag = aReader.GetTag(); - if (tag == mConstants.fabricIndexTag) - { - chip::FabricIndex fabricIndex; - ReturnErrorOnFailure(aReader.Get(fabricIndex)); - ReturnErrorOnFailure(entry.SetFabricIndex(fabricIndex)); - } - else if (tag == mConstants.privilegeTag) - { - uint32_t privilegeTemp; - ReturnErrorOnFailure(aReader.Get(privilegeTemp)); - Privilege privilege; - ReturnErrorOnFailure(Convert(privilegeTemp, privilege)); - ReturnErrorOnFailure(entry.SetPrivilege(privilege)); - } - else if (tag == mConstants.authModeTag) - { - uint32_t authModeTemp; - ReturnErrorOnFailure(aReader.Get(authModeTemp)); - AuthMode authMode; - ReturnErrorOnFailure(Convert(authModeTemp, authMode)); - ReturnErrorOnFailure(entry.SetAuthMode(authMode)); - } - else if (tag == mConstants.subjectsTag) - { - TLV::TLVType subjectsContainer; - VerifyOrReturnError(TLV::kTLVType_Array == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); - ReturnErrorOnFailure(aReader.EnterContainer(subjectsContainer)); - while ((err = aReader.Next()) == CHIP_NO_ERROR) - { - NodeId subject = kUndefinedNodeId; - ReturnErrorOnFailure(aReader.Get(subject)); - ReturnErrorOnFailure(entry.AddSubject(nullptr, subject)); - } - VerifyOrReturnError(err == CHIP_END_OF_TLV, err); - ReturnErrorOnFailure(aReader.ExitContainer(subjectsContainer)); - } - else if (tag == mConstants.targetsTag) - { - TLV::TLVType targetsContainer; - VerifyOrReturnError(TLV::kTLVType_Array == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); - ReturnErrorOnFailure(aReader.EnterContainer(targetsContainer)); - while ((err = aReader.Next()) == CHIP_NO_ERROR) - { - AccessControl::Entry::Target target; - TLV::TLVType targetContainer; - VerifyOrReturnError(TLV::kTLVType_Structure == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); - ReturnErrorOnFailure(aReader.EnterContainer(targetContainer)); - while ((err = aReader.Next()) == CHIP_NO_ERROR) - { - VerifyOrReturnError(TLV::IsContextTag(aReader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG); - auto targetTag = TLV::TagNumFromTag(aReader.GetTag()); - if (targetTag == mConstants.targetClusterTag) - { - if (aReader.GetType() != TLV::kTLVType_Null) - { - ReturnErrorOnFailure(aReader.Get(target.cluster)); - target.flags |= target.kCluster; - } - } - else if (targetTag == mConstants.targetEndpointTag) - { - if (aReader.GetType() != TLV::kTLVType_Null) - { - ReturnErrorOnFailure(aReader.Get(target.endpoint)); - target.flags |= target.kEndpoint; - } - } - else if (targetTag == mConstants.targetDeviceTypeTag) - { - if (aReader.GetType() != TLV::kTLVType_Null) - { - ReturnErrorOnFailure(aReader.Get(target.deviceType)); - target.flags |= target.kDeviceType; - } - } - } - VerifyOrReturnError(err == CHIP_END_OF_TLV, err); - ReturnErrorOnFailure(aReader.ExitContainer(targetContainer)); - ReturnErrorOnFailure(entry.AddTarget(nullptr, target)); - } - VerifyOrReturnError(err == CHIP_END_OF_TLV, err); - ReturnErrorOnFailure(aReader.ExitContainer(targetsContainer)); - break; - } - } - VerifyOrReturnError(err == CHIP_END_OF_TLV, err); - ReturnErrorOnFailure(aReader.ExitContainer(accessControlEntryContainer)); - return CHIP_NO_ERROR; - } - - AccessControl::Entry entry; - -private: - const AccessControlEntryCodecConstants mConstants; -}; - -} // namespace Access -} // namespace chip diff --git a/src/access/BUILD.gn b/src/access/BUILD.gn index dbea6209123eff..bca34a9f1a9bd3 100644 --- a/src/access/BUILD.gn +++ b/src/access/BUILD.gn @@ -20,7 +20,6 @@ static_library("access") { sources = [ "AccessControl.cpp", "AccessControl.h", - "AccessControlEntryCodec.h", "AuthMode.h", "Privilege.h", "RequestPath.h", diff --git a/src/access/examples/ExampleAccessControlDelegate.cpp b/src/access/examples/ExampleAccessControlDelegate.cpp index 1cca4b31386752..f5ea7d02d0bd38 100644 --- a/src/access/examples/ExampleAccessControlDelegate.cpp +++ b/src/access/examples/ExampleAccessControlDelegate.cpp @@ -18,10 +18,7 @@ #include "ExampleAccessControlDelegate.h" -#include #include -#include -#include #include #include @@ -1100,125 +1097,10 @@ class AccessControlDelegate : public AccessControl::Delegate bool IsTransitional() const override { return false; } -public: - void SetStorageDelegate(chip::PersistentStorageDelegate * storageDelegate) { mStorageDelegate = storageDelegate; } - private: - chip::PersistentStorageDelegate * mStorageDelegate = nullptr; - - // The version of the storage data format. Increment this key when the format of the data model changes. - static const uint32_t kExampleAclStorageVersion = 1; - static const size_t kMetadataStorageBufferSize = 32; - static const size_t kEntryStorageBufferSize = 192; - static const chip::TLV::Tag kTagVersion = chip::TLV::ContextTag(1); - static const chip::TLV::Tag kTagEntryCount = chip::TLV::ContextTag(2); - - struct Constants : public chip::Access::AccessControlEntryCodecConstants - { - Constants() - { - encodedAuthPase = 1; - encodedAuthCase = 2; - encodedAuthGroup = 3; - encodedPrivilegeView = 4; - encodedPrivilegeProxyView = 5; - encodedPrivilegeOperate = 6; - encodedPrivilegeManage = 7; - encodedPrivilegeAdminister = 8; - fabricIndexTag = chip::TLV::ContextTag(1); - privilegeTag = chip::TLV::ContextTag(2); - authModeTag = chip::TLV::ContextTag(3); - subjectsTag = chip::TLV::ContextTag(4); - targetsTag = chip::TLV::ContextTag(5); - targetClusterTag = chip::TLV::ContextTag(6); - targetEndpointTag = chip::TLV::ContextTag(7); - targetDeviceTypeTag = chip::TLV::ContextTag(8); - } - }; - - CHIP_ERROR LoadFromFlash() - { - VerifyOrReturnError(mStorageDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); - - uint8_t buffer[kMetadataStorageBufferSize] = { 0 }; - uint16_t size = static_cast(sizeof(buffer)); - chip::DefaultStorageKeyAllocator key; - ReturnErrorOnFailure(mStorageDelegate->SyncGetKeyValue(key.AccessControlList(), buffer, size)); - - chip::TLV::TLVReader reader; - reader.Init(buffer, size); - - ReturnErrorOnFailure(reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag)); - - chip::TLV::TLVType container; - ReturnErrorOnFailure(reader.EnterContainer(container)); + CHIP_ERROR LoadFromFlash() { return CHIP_NO_ERROR; } - // Version - ReturnErrorOnFailure(reader.Next(kTagVersion)); - uint32_t version; - ReturnErrorOnFailure(reader.Get(version)); - VerifyOrReturnError(version == kExampleAclStorageVersion, CHIP_ERROR_VERSION_MISMATCH); - - // Entry count - ReturnErrorOnFailure(reader.Next(kTagEntryCount)); - uint32_t entryCount; - ReturnErrorOnFailure(reader.Get(entryCount)); - - for (auto & storage : EntryStorage::acl) - { - storage.Clear(); - } - - // Entries - chip::Access::AccessControlEntryCodec codec; - for (size_t i = 0; i < entryCount; ++i) - { - uint8_t entryBuffer[kEntryStorageBufferSize] = { 0 }; - uint16_t bufferSize = static_cast(sizeof(buffer)); - ReturnErrorOnFailure(mStorageDelegate->SyncGetKeyValue(key.AccessControlEntry(i), entryBuffer, bufferSize)); - chip::TLV::TLVReader entryReader; - entryReader.Init(entryBuffer, bufferSize); - ReturnErrorOnFailure(entryReader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag)); - ReturnErrorOnFailure(codec.Decode(entryReader)); - ReturnErrorOnFailure(CreateEntry(nullptr, codec.entry, nullptr)); - } - return reader.ExitContainer(container); - } - - CHIP_ERROR SaveToFlash() - { - VerifyOrReturnError(mStorageDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); - - uint8_t buffer[kMetadataStorageBufferSize] = { 0 }; - chip::TLV::TLVWriter writer; - writer.Init(buffer); - chip::DefaultStorageKeyAllocator key; - chip::TLV::TLVType container; - ReturnErrorOnFailure(writer.StartContainer(chip::TLV::AnonymousTag, chip::TLV::TLVType::kTLVType_Structure, container)); - ReturnErrorOnFailure(writer.Put(kTagVersion, kExampleAclStorageVersion)); - - size_t entryCount; - ReturnErrorOnFailure(GetEntryCount(entryCount)); - ReturnErrorOnFailure(writer.Put(kTagEntryCount, static_cast(entryCount))); - - ReturnErrorOnFailure(writer.EndContainer(container)); - ReturnErrorOnFailure(writer.Finalize()); - - chip::Access::AccessControlEntryCodec codec; - for (size_t i = 0; i < entryCount; ++i) - { - uint8_t entryBuffer[kEntryStorageBufferSize] = { 0 }; - chip::TLV::TLVWriter entryWriter; - entryWriter.Init(entryBuffer); - ReturnErrorOnFailure(ReadEntry(i, codec.entry, nullptr)); - ReturnErrorOnFailure(codec.Encode(entryWriter, chip::TLV::AnonymousTag)); - ReturnErrorOnFailure(entryWriter.Finalize()); - ReturnErrorOnFailure(mStorageDelegate->SyncSetKeyValue(key.AccessControlEntry(i), entryBuffer, - static_cast(entryWriter.GetLengthWritten()))); - } - - return mStorageDelegate->SyncSetKeyValue(key.AccessControlList(), buffer, static_cast(writer.GetLengthWritten())); - } + CHIP_ERROR SaveToFlash() { return CHIP_NO_ERROR; } }; static_assert(std::is_pod(), "Storage type must be POD"); @@ -1242,12 +1124,6 @@ AccessControl::Delegate & GetAccessControlDelegate() return accessControlDelegate; } -void SetAccessControlDelegateStorage(chip::PersistentStorageDelegate * storageDelegate) -{ - AccessControlDelegate & accessControlDelegate = static_cast(GetAccessControlDelegate()); - accessControlDelegate.SetStorageDelegate(storageDelegate); -} - } // namespace Examples } // namespace Access } // namespace chip diff --git a/src/access/examples/ExampleAccessControlDelegate.h b/src/access/examples/ExampleAccessControlDelegate.h index e2a3bd04d913e3..f411de1339df3c 100644 --- a/src/access/examples/ExampleAccessControlDelegate.h +++ b/src/access/examples/ExampleAccessControlDelegate.h @@ -17,7 +17,6 @@ #pragma once #include "access/AccessControl.h" -#include namespace chip { namespace Access { @@ -25,8 +24,6 @@ namespace Examples { AccessControl::Delegate & GetAccessControlDelegate(); -void SetAccessControlDelegateStorage(chip::PersistentStorageDelegate * storageDelegate); - } // namespace Examples } // namespace Access } // namespace chip diff --git a/src/app/clusters/access-control-server/access-control-server.cpp b/src/app/clusters/access-control-server/access-control-server.cpp index 36ae21cde4a9e0..bc60dbafc08477 100644 --- a/src/app/clusters/access-control-server/access-control-server.cpp +++ b/src/app/clusters/access-control-server/access-control-server.cpp @@ -16,7 +16,6 @@ */ #include -#include #include #include @@ -38,27 +37,284 @@ namespace AccessControlCluster = chip::app::Clusters::AccessControl; namespace { -struct Constants : public AccessControlEntryCodecConstants +struct AccessControlEntryCodec { - Constants() + static CHIP_ERROR Convert(AuthMode from, AccessControlCluster::AuthMode & to) { - encodedAuthPase = static_cast(AccessControlCluster::AuthMode::kPase); - encodedAuthCase = static_cast(AccessControlCluster::AuthMode::kCase); - encodedAuthGroup = static_cast(AccessControlCluster::AuthMode::kGroup); - encodedPrivilegeView = static_cast(AccessControlCluster::Privilege::kView); - encodedPrivilegeProxyView = static_cast(AccessControlCluster::Privilege::kProxyView); - encodedPrivilegeOperate = static_cast(AccessControlCluster::Privilege::kOperate); - encodedPrivilegeManage = static_cast(AccessControlCluster::Privilege::kManage); - encodedPrivilegeAdminister = static_cast(AccessControlCluster::Privilege::kAdminister); - fabricIndexTag = TLV::ContextTag(to_underlying(AccessControlCluster::Structs::AccessControlEntry::Fields::kFabricIndex)); - privilegeTag = TLV::ContextTag(to_underlying(AccessControlCluster::Structs::AccessControlEntry::Fields::kPrivilege)); - authModeTag = TLV::ContextTag(to_underlying(AccessControlCluster::Structs::AccessControlEntry::Fields::kAuthMode)); - subjectsTag = TLV::ContextTag(to_underlying(AccessControlCluster::Structs::AccessControlEntry::Fields::kSubjects)); - targetsTag = TLV::ContextTag(to_underlying(AccessControlCluster::Structs::AccessControlEntry::Fields::kTargets)); - targetClusterTag = TLV::ContextTag(to_underlying(AccessControlCluster::Structs::Target::Fields::kCluster)); - targetEndpointTag = TLV::ContextTag(to_underlying(AccessControlCluster::Structs::Target::Fields::kEndpoint)); - targetDeviceTypeTag = TLV::ContextTag(to_underlying(AccessControlCluster::Structs::Target::Fields::kDeviceType)); + switch (from) + { + case AuthMode::kPase: + to = AccessControlCluster::AuthMode::kPase; + break; + case AuthMode::kCase: + to = AccessControlCluster::AuthMode::kCase; + break; + case AuthMode::kGroup: + to = AccessControlCluster::AuthMode::kGroup; + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + return CHIP_NO_ERROR; + } + + static CHIP_ERROR Convert(AccessControlCluster::AuthMode from, AuthMode & to) + { + switch (from) + { + case AccessControlCluster::AuthMode::kPase: + to = AuthMode::kPase; + break; + case AccessControlCluster::AuthMode::kCase: + to = AuthMode::kCase; + break; + case AccessControlCluster::AuthMode::kGroup: + to = AuthMode::kGroup; + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + return CHIP_NO_ERROR; + } + + static CHIP_ERROR Convert(Privilege from, AccessControlCluster::Privilege & to) + { + switch (from) + { + case Privilege::kView: + to = AccessControlCluster::Privilege::kView; + break; + case Privilege::kProxyView: + to = AccessControlCluster::Privilege::kProxyView; + break; + case Privilege::kOperate: + to = AccessControlCluster::Privilege::kOperate; + break; + case Privilege::kManage: + to = AccessControlCluster::Privilege::kManage; + break; + case Privilege::kAdminister: + to = AccessControlCluster::Privilege::kAdminister; + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + return CHIP_NO_ERROR; + } + + static CHIP_ERROR Convert(AccessControlCluster::Privilege from, Privilege & to) + { + switch (from) + { + case AccessControlCluster::Privilege::kView: + to = Privilege::kView; + break; + case AccessControlCluster::Privilege::kProxyView: + to = Privilege::kProxyView; + break; + case AccessControlCluster::Privilege::kOperate: + to = Privilege::kOperate; + break; + case AccessControlCluster::Privilege::kManage: + to = Privilege::kManage; + break; + case AccessControlCluster::Privilege::kAdminister: + to = Privilege::kAdminister; + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + return CHIP_NO_ERROR; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const + { + TLV::TLVType accessControlEntryContainer; + ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, accessControlEntryContainer)); + using Fields = AccessControlCluster::Structs::AccessControlEntry::Fields; + { + FabricIndex fabricIndex; + ReturnErrorOnFailure(entry.GetFabricIndex(fabricIndex)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex)); + } + { + Privilege privilege; + ReturnErrorOnFailure(entry.GetPrivilege(privilege)); + AccessControlCluster::Privilege privilegeTemp; + ReturnErrorOnFailure(Convert(privilege, privilegeTemp)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(to_underlying(Fields::kPrivilege)), privilegeTemp)); + } + { + AuthMode authMode; + ReturnErrorOnFailure(entry.GetAuthMode(authMode)); + AccessControlCluster::AuthMode authModeTemp; + ReturnErrorOnFailure(Convert(authMode, authModeTemp)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(to_underlying(Fields::kAuthMode)), authModeTemp)); + } + { + size_t count = 0; + ReturnErrorOnFailure(entry.GetSubjectCount(count)); + if (count > 0) + { + TLV::TLVType subjectsContainer; + ReturnErrorOnFailure(aWriter.StartContainer(TLV::ContextTag(to_underlying(Fields::kSubjects)), TLV::kTLVType_Array, + subjectsContainer)); + for (size_t i = 0; i < count; ++i) + { + NodeId subject; + ReturnErrorOnFailure(entry.GetSubject(i, subject)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::AnonymousTag, subject)); + } + ReturnErrorOnFailure(aWriter.EndContainer(subjectsContainer)); + } + } + { + size_t count = 0; + ReturnErrorOnFailure(entry.GetTargetCount(count)); + if (count > 0) + { + TLV::TLVType targetsContainer; + ReturnErrorOnFailure(aWriter.StartContainer(TLV::ContextTag(to_underlying(Fields::kTargets)), TLV::kTLVType_Array, + targetsContainer)); + using TargetFields = AccessControlCluster::Structs::Target::Fields; + for (size_t i = 0; i < count; ++i) + { + TLV::TLVType targetContainer; + ReturnErrorOnFailure(aWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, targetContainer)); + AccessControl::Entry::Target target; + ReturnErrorOnFailure(entry.GetTarget(i, target)); + if (target.flags & AccessControl::Entry::Target::kCluster) + { + ReturnErrorOnFailure( + DataModel::Encode(aWriter, TLV::ContextTag(to_underlying(TargetFields::kCluster)), target.cluster)); + } + if (target.flags & AccessControl::Entry::Target::kEndpoint) + { + ReturnErrorOnFailure( + DataModel::Encode(aWriter, TLV::ContextTag(to_underlying(TargetFields::kEndpoint)), target.endpoint)); + } + if (target.flags & AccessControl::Entry::Target::kDeviceType) + { + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(to_underlying(TargetFields::kDeviceType)), + target.deviceType)); + } + ReturnErrorOnFailure(aWriter.EndContainer(targetContainer)); + } + ReturnErrorOnFailure(aWriter.EndContainer(targetsContainer)); + } + } + ReturnErrorOnFailure(aWriter.EndContainer(accessControlEntryContainer)); + return CHIP_NO_ERROR; + } + + CHIP_ERROR Decode(TLV::TLVReader & aReader) + { + ReturnErrorOnFailure(GetAccessControl().PrepareEntry(entry)); + CHIP_ERROR err = CHIP_NO_ERROR; + TLV::TLVType accessControlEntryContainer; + VerifyOrReturnError(TLV::kTLVType_Structure == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnErrorOnFailure(aReader.EnterContainer(accessControlEntryContainer)); + using Fields = AccessControlCluster::Structs::AccessControlEntry::Fields; + while ((err = aReader.Next()) == CHIP_NO_ERROR) + { + VerifyOrReturnError(TLV::IsContextTag(aReader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG); + switch (TLV::TagNumFromTag(aReader.GetTag())) + { + case to_underlying(Fields::kFabricIndex): { + chip::FabricIndex fabricIndex; + ReturnErrorOnFailure(DataModel::Decode(aReader, fabricIndex)); + ReturnErrorOnFailure(entry.SetFabricIndex(fabricIndex)); + break; + } + case to_underlying(Fields::kPrivilege): { + AccessControlCluster::Privilege privilegeTemp; + ReturnErrorOnFailure(DataModel::Decode(aReader, privilegeTemp)); + Privilege privilege; + ReturnErrorOnFailure(Convert(privilegeTemp, privilege)); + ReturnErrorOnFailure(entry.SetPrivilege(privilege)); + break; + } + case to_underlying(Fields::kAuthMode): { + AccessControlCluster::AuthMode authModeTemp; + ReturnErrorOnFailure(DataModel::Decode(aReader, authModeTemp)); + AuthMode authMode; + ReturnErrorOnFailure(Convert(authModeTemp, authMode)); + ReturnErrorOnFailure(entry.SetAuthMode(authMode)); + break; + } + case to_underlying(Fields::kSubjects): { + TLV::TLVType subjectsContainer; + VerifyOrReturnError(TLV::kTLVType_Array == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnErrorOnFailure(aReader.EnterContainer(subjectsContainer)); + while ((err = aReader.Next()) == CHIP_NO_ERROR) + { + NodeId subject = kUndefinedNodeId; + ReturnErrorOnFailure(DataModel::Decode(aReader, subject)); + ReturnErrorOnFailure(entry.AddSubject(nullptr, subject)); + } + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(aReader.ExitContainer(subjectsContainer)); + break; + } + case to_underlying(Fields::kTargets): { + TLV::TLVType targetsContainer; + VerifyOrReturnError(TLV::kTLVType_Array == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnErrorOnFailure(aReader.EnterContainer(targetsContainer)); + while ((err = aReader.Next()) == CHIP_NO_ERROR) + { + AccessControl::Entry::Target target; + TLV::TLVType targetContainer; + VerifyOrReturnError(TLV::kTLVType_Structure == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnErrorOnFailure(aReader.EnterContainer(targetContainer)); + using TargetFields = AccessControlCluster::Structs::Target::Fields; + while ((err = aReader.Next()) == CHIP_NO_ERROR) + { + VerifyOrReturnError(TLV::IsContextTag(aReader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG); + switch (TLV::TagNumFromTag(aReader.GetTag())) + { + case to_underlying(TargetFields::kCluster): + if (aReader.GetType() != TLV::kTLVType_Null) + { + ReturnErrorOnFailure(DataModel::Decode(aReader, target.cluster)); + target.flags |= target.kCluster; + } + break; + case to_underlying(TargetFields::kEndpoint): + if (aReader.GetType() != TLV::kTLVType_Null) + { + ReturnErrorOnFailure(DataModel::Decode(aReader, target.endpoint)); + target.flags |= target.kEndpoint; + } + break; + case to_underlying(TargetFields::kDeviceType): + if (aReader.GetType() != TLV::kTLVType_Null) + { + ReturnErrorOnFailure(DataModel::Decode(aReader, target.deviceType)); + target.flags |= target.kDeviceType; + } + break; + default: + break; + } + } + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(aReader.ExitContainer(targetContainer)); + ReturnErrorOnFailure(entry.AddTarget(nullptr, target)); + } + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(aReader.ExitContainer(targetsContainer)); + break; + } + default: + break; + } + } + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(aReader.ExitContainer(accessControlEntryContainer)); + return CHIP_NO_ERROR; + } + + AccessControl::Entry entry; }; class AccessControlAttribute : public chip::app::AttributeAccessInterface @@ -97,7 +353,7 @@ CHIP_ERROR AccessControlAttribute::Read(const ConcreteReadAttributePath & aPath, CHIP_ERROR AccessControlAttribute::ReadAcl(AttributeValueEncoder & aEncoder) { - AccessControlEntryCodec codec; + AccessControlEntryCodec codec; AccessControl::EntryIterator iterator; ReturnErrorOnFailure(GetAccessControl().Entries(iterator)); @@ -133,7 +389,7 @@ CHIP_ERROR AccessControlAttribute::Write(const ConcreteDataAttributePath & aPath CHIP_ERROR AccessControlAttribute::WriteAcl(AttributeValueDecoder & aDecoder) { - DataModel::DecodableList> list; + DataModel::DecodableList list; ReturnErrorOnFailure(aDecoder.Decode(list)); size_t oldCount; diff --git a/src/lib/support/DefaultStorageKeyAllocator.h b/src/lib/support/DefaultStorageKeyAllocator.h index 4846a04139d2e9..4a8ada7e653b72 100644 --- a/src/lib/support/DefaultStorageKeyAllocator.h +++ b/src/lib/support/DefaultStorageKeyAllocator.h @@ -34,11 +34,6 @@ class DefaultStorageKeyAllocator const char * FabricTable(chip::FabricIndex fabric) { return Format("f/%x/t", fabric); } - // Access Control List - - const char * AccessControlList() { return Format("acl"); } - const char * AccessControlEntry(size_t index) { return Format("acl/%x", index); } - // Group Data Provider const char * FabricGroups(chip::FabricIndex fabric) { return Format("f/%x/g", fabric); }