Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2022 Project CHIP Authors 4 : * 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : #pragma once 19 : 20 : #include <access/AccessControl.h> 21 : #include <credentials/FabricTable.h> 22 : #include <lib/core/CHIPPersistentStorageDelegate.h> 23 : 24 : #include <app-common/zap-generated/cluster-objects.h> 25 : 26 : namespace chip { 27 : namespace app { 28 : 29 : /** 30 : * Storage specifically for access control entries, which correspond to the 31 : * ACL attribute of the access control cluster. 32 : * 33 : * An object of this class should be initialized directly after the access 34 : * control module is initialized, as it will populate entries in the system 35 : * module from storage, and also install a listener in the system module to 36 : * keep storage up to date as entries change. 37 : * 38 : * This class also provides facilities for converting between access control 39 : * entries (as used by the system module) and access control entries (as used 40 : * by the generated cluster code). 41 : */ 42 : class AclStorage 43 : { 44 : public: 45 : /** 46 : * Used for decoding access control entries. 47 : * 48 : * Typically used temporarily on the stack to decode: 49 : * - source: TLV 50 : * - staging: generated cluster level code 51 : * - destination: system level access control entry 52 : */ 53 : class DecodableEntry 54 : { 55 : using Entry = Access::AccessControl::Entry; 56 : using StagingEntry = Clusters::AccessControl::Structs::AccessControlEntryStruct::DecodableType; 57 : 58 : public: 59 0 : DecodableEntry() = default; 60 : 61 : /** 62 : * Reader decodes into a staging entry, which is then unstaged 63 : * into a member entry. 64 : */ 65 : CHIP_ERROR Decode(TLV::TLVReader & reader); 66 : 67 0 : Entry & GetEntry() { return mEntry; } 68 : 69 : const Entry & GetEntry() const { return mEntry; } 70 : 71 : public: 72 : static constexpr bool kIsFabricScoped = true; 73 : 74 : void SetFabricIndex(FabricIndex fabricIndex) { mEntry.SetFabricIndex(fabricIndex); } 75 : 76 : private: 77 : CHIP_ERROR Unstage(); 78 : 79 : private: 80 : Entry mEntry; 81 : 82 : StagingEntry mStagingEntry; 83 : }; 84 : 85 : /** 86 : * Used for encoding access control entries. 87 : * 88 : * Typically used temporarily on the stack to encode: 89 : * - source: system level access control entry 90 : * - staging: generated cluster level code 91 : * - destination: TLV 92 : */ 93 : class EncodableEntry 94 : { 95 : using Entry = Access::AccessControl::Entry; 96 : using StagingEntry = Clusters::AccessControl::Structs::AccessControlEntryStruct::Type; 97 : using StagingTarget = Clusters::AccessControl::Structs::AccessControlTargetStruct::Type; 98 : 99 : public: 100 0 : EncodableEntry(const Entry & entry) : mEntry(entry) {} 101 : 102 : /** 103 : * Constructor-provided entry is staged into a staging entry, 104 : * which is then encoded into a writer. 105 : */ 106 : CHIP_ERROR EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex fabric) const; 107 : 108 : /** 109 : * Constructor-provided entry is staged into a staging entry, 110 : * which is then encoded into a writer. 111 : */ 112 : CHIP_ERROR EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const; 113 : 114 : /** 115 : * Constructor-provided entry is staged into a staging entry. 116 : */ 117 : CHIP_ERROR Stage() const; 118 : 119 : StagingEntry & GetStagingEntry() { return mStagingEntry; } 120 : 121 : const StagingEntry & GetStagingEntry() const { return mStagingEntry; } 122 : 123 : public: 124 : static constexpr bool kIsFabricScoped = true; 125 : 126 : FabricIndex GetFabricIndex() const 127 : { 128 : FabricIndex fabricIndex = kUndefinedFabricIndex; 129 : mEntry.GetFabricIndex(fabricIndex); 130 : return fabricIndex; 131 : } 132 : 133 : private: 134 : const Entry & mEntry; 135 : 136 : mutable StagingEntry mStagingEntry; 137 : mutable NodeId mStagingSubjects[CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_SUBJECTS_PER_ENTRY]; 138 : mutable StagingTarget mStagingTargets[CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_TARGETS_PER_ENTRY]; 139 : }; 140 : 141 1 : virtual ~AclStorage() = default; 142 : 143 : /** 144 : * Initialize should be called after chip::Access::AccessControl is initialized. 145 : * 146 : * Implementations should take this opportunity to populate AccessControl with ACL entries 147 : * loaded from persistent storage. A half-open range of fabrics [first, last) is provided 148 : * so this can be done on a per-fabric basis. 149 : * 150 : * Implementations should also install an entry change listener on AccessControl to maintain 151 : * ACL entries in persistent storage as they are changed. 152 : */ 153 : virtual CHIP_ERROR Init(PersistentStorageDelegate & persistentStorage, ConstFabricIterator first, ConstFabricIterator last) = 0; 154 : }; 155 : 156 : } // namespace app 157 : } // namespace chip