Matter SDK Coverage Report
Current view: top level - app/server - AclStorage.cpp (source / functions) Coverage Total Hit
Test: SHA:3f9cd168e84cd831b7699126f5296f5c5498690f Lines: 0.0 % 204 0
Test Date: 2026-04-27 19:52:19 Functions: 0.0 % 15 0

            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              : #include <app/server/AclStorage.h>
      19              : 
      20              : #include <lib/support/DefaultStorageKeyAllocator.h>
      21              : 
      22              : using namespace chip;
      23              : using namespace chip::app;
      24              : using namespace chip::Access;
      25              : 
      26              : using Entry                = AccessControl::Entry;
      27              : using EntryListener        = AccessControl::EntryListener;
      28              : using StagingAuthMode      = Clusters::AccessControl::AccessControlEntryAuthModeEnum;
      29              : using StagingPrivilege     = Clusters::AccessControl::AccessControlEntryPrivilegeEnum;
      30              : using StagingAuxiliaryType = Clusters::AccessControl::AccessControlAuxiliaryTypeEnum;
      31              : using StagingTarget        = Clusters::AccessControl::Structs::AccessControlTargetStruct::Type;
      32              : using Target               = AccessControl::Entry::Target;
      33              : 
      34              : namespace {
      35              : 
      36              : struct StagingSubject
      37              : {
      38              :     NodeId nodeId;
      39              :     StagingAuthMode authMode;
      40              : };
      41              : 
      42            0 : CHIP_ERROR Convert(AuthMode from, StagingAuthMode & to)
      43              : {
      44            0 :     switch (from)
      45              :     {
      46            0 :     case AuthMode::kPase:
      47            0 :         to = StagingAuthMode::kPase;
      48            0 :         break;
      49            0 :     case AuthMode::kCase:
      50            0 :         to = StagingAuthMode::kCase;
      51            0 :         break;
      52            0 :     case AuthMode::kGroup:
      53            0 :         to = StagingAuthMode::kGroup;
      54            0 :         break;
      55            0 :     default:
      56            0 :         return CHIP_ERROR_INVALID_ARGUMENT;
      57              :     }
      58            0 :     return CHIP_NO_ERROR;
      59              : }
      60              : 
      61            0 : CHIP_ERROR Convert(StagingAuthMode from, AuthMode & to)
      62              : {
      63            0 :     switch (from)
      64              :     {
      65            0 :     case StagingAuthMode::kPase:
      66            0 :         to = AuthMode::kPase;
      67            0 :         break;
      68            0 :     case StagingAuthMode::kCase:
      69            0 :         to = AuthMode::kCase;
      70            0 :         break;
      71            0 :     case StagingAuthMode::kGroup:
      72            0 :         to = AuthMode::kGroup;
      73            0 :         break;
      74            0 :     default:
      75            0 :         return CHIP_ERROR_INVALID_ARGUMENT;
      76              :     }
      77            0 :     return CHIP_NO_ERROR;
      78              : }
      79              : 
      80            0 : CHIP_ERROR Convert(Privilege from, StagingPrivilege & to)
      81              : {
      82            0 :     switch (from)
      83              :     {
      84            0 :     case Privilege::kView:
      85            0 :         to = StagingPrivilege::kView;
      86            0 :         break;
      87            0 :     case Privilege::kProxyView:
      88            0 :         to = StagingPrivilege::kProxyView;
      89            0 :         break;
      90            0 :     case Privilege::kOperate:
      91            0 :         to = StagingPrivilege::kOperate;
      92            0 :         break;
      93            0 :     case Privilege::kManage:
      94            0 :         to = StagingPrivilege::kManage;
      95            0 :         break;
      96            0 :     case Privilege::kAdminister:
      97            0 :         to = StagingPrivilege::kAdminister;
      98            0 :         break;
      99            0 :     default:
     100            0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     101              :     }
     102            0 :     return CHIP_NO_ERROR;
     103              : }
     104              : 
     105            0 : CHIP_ERROR Convert(StagingPrivilege from, Privilege & to)
     106              : {
     107            0 :     switch (from)
     108              :     {
     109            0 :     case StagingPrivilege::kView:
     110            0 :         to = Privilege::kView;
     111            0 :         break;
     112            0 :     case StagingPrivilege::kProxyView:
     113            0 :         to = Privilege::kProxyView;
     114            0 :         break;
     115            0 :     case StagingPrivilege::kOperate:
     116            0 :         to = Privilege::kOperate;
     117            0 :         break;
     118            0 :     case StagingPrivilege::kManage:
     119            0 :         to = Privilege::kManage;
     120            0 :         break;
     121            0 :     case StagingPrivilege::kAdminister:
     122            0 :         to = Privilege::kAdminister;
     123            0 :         break;
     124            0 :     default:
     125            0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     126              :     }
     127            0 :     return CHIP_NO_ERROR;
     128              : }
     129              : 
     130            0 : CHIP_ERROR Convert(AuxiliaryType from, StagingAuxiliaryType & to)
     131              : {
     132            0 :     switch (from)
     133              :     {
     134            0 :     case AuxiliaryType::kSystem:
     135            0 :         to = StagingAuxiliaryType::kSystem;
     136            0 :         break;
     137            0 :     case AuxiliaryType::kGroupcast:
     138            0 :         to = StagingAuxiliaryType::kGroupcast;
     139            0 :         break;
     140            0 :     default:
     141            0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     142              :     }
     143            0 :     return CHIP_NO_ERROR;
     144              : }
     145              : 
     146            0 : CHIP_ERROR Convert(StagingAuxiliaryType from, AuxiliaryType & to)
     147              : {
     148            0 :     switch (from)
     149              :     {
     150            0 :     case StagingAuxiliaryType::kSystem:
     151            0 :         to = AuxiliaryType::kSystem;
     152            0 :         break;
     153            0 :     case StagingAuxiliaryType::kGroupcast:
     154            0 :         to = AuxiliaryType::kGroupcast;
     155            0 :         break;
     156            0 :     default:
     157            0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     158              :     }
     159            0 :     return CHIP_NO_ERROR;
     160              : }
     161              : 
     162            0 : CHIP_ERROR Convert(NodeId from, StagingSubject & to)
     163              : {
     164            0 :     if (IsOperationalNodeId(from) || IsCASEAuthTag(from))
     165              :     {
     166            0 :         to = { .nodeId = from, .authMode = StagingAuthMode::kCase };
     167              :     }
     168            0 :     else if (IsGroupId(from))
     169              :     {
     170            0 :         to = { .nodeId = GroupIdFromNodeId(from), .authMode = StagingAuthMode::kGroup };
     171              :     }
     172            0 :     else if (IsPAKEKeyId(from))
     173              :     {
     174            0 :         to = { .nodeId = PAKEKeyIdFromNodeId(from), .authMode = StagingAuthMode::kPase };
     175              :     }
     176              :     else
     177              :     {
     178            0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     179              :     }
     180            0 :     return CHIP_NO_ERROR;
     181              : }
     182              : 
     183            0 : CHIP_ERROR Convert(StagingSubject from, NodeId & to)
     184              : {
     185            0 :     switch (from.authMode)
     186              :     {
     187            0 :     case StagingAuthMode::kPase:
     188            0 :         VerifyOrReturnError((from.nodeId & ~kMaskPAKEKeyId) == 0, CHIP_ERROR_INVALID_ARGUMENT);
     189            0 :         to = NodeIdFromPAKEKeyId(static_cast<PasscodeId>(from.nodeId));
     190            0 :         break;
     191            0 :     case StagingAuthMode::kCase:
     192            0 :         to = from.nodeId;
     193            0 :         break;
     194            0 :     case StagingAuthMode::kGroup:
     195            0 :         VerifyOrReturnError((from.nodeId & ~kMaskGroupId) == 0, CHIP_ERROR_INVALID_ARGUMENT);
     196            0 :         to = NodeIdFromGroupId(static_cast<GroupId>(from.nodeId));
     197            0 :         break;
     198            0 :     default:
     199            0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     200              :     }
     201            0 :     return CHIP_NO_ERROR;
     202              : }
     203              : 
     204            0 : CHIP_ERROR Convert(const Target & from, StagingTarget & to)
     205              : {
     206            0 :     if ((from.flags & Target::kCluster) != 0)
     207              :     {
     208            0 :         to.cluster.SetNonNull(from.cluster);
     209              :     }
     210              :     else
     211              :     {
     212            0 :         to.cluster.SetNull();
     213              :     }
     214            0 :     if ((from.flags & Target::kEndpoint) != 0)
     215              :     {
     216            0 :         to.endpoint.SetNonNull(from.endpoint);
     217              :     }
     218              :     else
     219              :     {
     220            0 :         to.endpoint.SetNull();
     221              :     }
     222            0 :     if ((from.flags & Target::kDeviceType) != 0)
     223              :     {
     224            0 :         to.deviceType.SetNonNull(from.deviceType);
     225              :     }
     226              :     else
     227              :     {
     228            0 :         to.deviceType.SetNull();
     229              :     }
     230            0 :     return CHIP_NO_ERROR;
     231              : }
     232              : 
     233            0 : CHIP_ERROR Convert(const StagingTarget & from, Target & to)
     234              : {
     235            0 :     to.flags = 0;
     236            0 :     if (!from.cluster.IsNull())
     237              :     {
     238            0 :         to.flags |= Target::kCluster;
     239            0 :         to.cluster = from.cluster.Value();
     240              :     }
     241            0 :     if (!from.endpoint.IsNull())
     242              :     {
     243            0 :         to.flags |= Target::kEndpoint;
     244            0 :         to.endpoint = from.endpoint.Value();
     245              :     }
     246            0 :     if (!from.deviceType.IsNull())
     247              :     {
     248            0 :         to.flags |= Target::kDeviceType;
     249            0 :         to.deviceType = from.deviceType.Value();
     250              :     }
     251            0 :     return CHIP_NO_ERROR;
     252              : }
     253              : 
     254              : } // namespace
     255              : 
     256              : namespace chip {
     257              : namespace app {
     258              : 
     259            0 : CHIP_ERROR AclStorage::DecodableEntry::Decode(TLV::TLVReader & reader)
     260              : {
     261            0 :     ReturnErrorOnFailure(mStagingEntry.Decode(reader));
     262            0 :     ReturnErrorOnFailure(Unstage());
     263            0 :     return CHIP_NO_ERROR;
     264              : }
     265              : 
     266            0 : CHIP_ERROR AclStorage::DecodableEntry::Unstage()
     267              : {
     268            0 :     ReturnErrorOnFailure(GetAccessControl().PrepareEntry(mEntry));
     269              : 
     270            0 :     ReturnErrorOnFailure(mEntry.SetFabricIndex(mStagingEntry.fabricIndex));
     271              : 
     272              :     {
     273              :         Privilege privilege;
     274            0 :         ReturnErrorOnFailure(Convert(mStagingEntry.privilege, privilege));
     275            0 :         ReturnErrorOnFailure(mEntry.SetPrivilege(privilege));
     276              :     }
     277              : 
     278              :     {
     279              :         AuthMode authMode;
     280            0 :         ReturnErrorOnFailure(Convert(mStagingEntry.authMode, authMode));
     281            0 :         ReturnErrorOnFailure(mEntry.SetAuthMode(authMode));
     282              :     }
     283              : 
     284            0 :     if (mStagingEntry.auxiliaryType.HasValue())
     285              :     {
     286              :         AuxiliaryType auxiliaryType;
     287            0 :         ReturnErrorOnFailure(Convert(mStagingEntry.auxiliaryType.Value(), auxiliaryType));
     288            0 :         ReturnErrorOnFailure(mEntry.SetAuxiliaryType(auxiliaryType));
     289              :     }
     290              : 
     291            0 :     if (!mStagingEntry.subjects.IsNull())
     292              :     {
     293            0 :         auto iterator = mStagingEntry.subjects.Value().begin();
     294            0 :         while (iterator.Next())
     295              :         {
     296            0 :             StagingSubject tmp = { .nodeId = iterator.GetValue(), .authMode = mStagingEntry.authMode };
     297              :             NodeId subject;
     298            0 :             ReturnErrorOnFailure(Convert(tmp, subject));
     299            0 :             ReturnErrorOnFailure(mEntry.AddSubject(nullptr, subject));
     300              :         }
     301            0 :         ReturnErrorOnFailure(iterator.GetStatus());
     302              :     }
     303              : 
     304            0 :     if (!mStagingEntry.targets.IsNull())
     305              :     {
     306            0 :         auto iterator = mStagingEntry.targets.Value().begin();
     307            0 :         while (iterator.Next())
     308              :         {
     309            0 :             Target target;
     310            0 :             ReturnErrorOnFailure(Convert(iterator.GetValue(), target));
     311            0 :             ReturnErrorOnFailure(mEntry.AddTarget(nullptr, target));
     312              :         }
     313            0 :         ReturnErrorOnFailure(iterator.GetStatus());
     314              :     }
     315              : 
     316            0 :     return CHIP_NO_ERROR;
     317              : }
     318              : 
     319            0 : CHIP_ERROR AclStorage::EncodableEntry::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex fabric) const
     320              : {
     321            0 :     ReturnErrorOnFailure(Stage());
     322            0 :     ReturnErrorOnFailure(mStagingEntry.EncodeForRead(writer, tag, fabric));
     323            0 :     return CHIP_NO_ERROR;
     324              : }
     325              : 
     326            0 : CHIP_ERROR AclStorage::EncodableEntry::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
     327              : {
     328            0 :     ReturnErrorOnFailure(Stage());
     329            0 :     ReturnErrorOnFailure(mStagingEntry.EncodeForWrite(writer, tag));
     330            0 :     return CHIP_NO_ERROR;
     331              : }
     332              : 
     333            0 : CHIP_ERROR AclStorage::EncodableEntry::Stage() const
     334              : {
     335            0 :     ReturnErrorOnFailure(mEntry.GetFabricIndex(mStagingEntry.fabricIndex));
     336              : 
     337              :     {
     338              :         Privilege privilege;
     339            0 :         ReturnErrorOnFailure(mEntry.GetPrivilege(privilege));
     340            0 :         ReturnErrorOnFailure(Convert(privilege, mStagingEntry.privilege));
     341              :     }
     342              : 
     343              :     {
     344              :         AuthMode authMode;
     345            0 :         ReturnErrorOnFailure(mEntry.GetAuthMode(authMode));
     346            0 :         ReturnErrorOnFailure(Convert(authMode, mStagingEntry.authMode));
     347              :     }
     348              : 
     349              :     {
     350              :         AuxiliaryType auxiliaryType;
     351            0 :         CHIP_ERROR err = mEntry.GetAuxiliaryType(auxiliaryType);
     352            0 :         if (err == CHIP_NO_ERROR)
     353              :         {
     354              :             StagingAuxiliaryType stagingAuxiliaryType;
     355            0 :             ReturnErrorOnFailure(Convert(auxiliaryType, stagingAuxiliaryType));
     356            0 :             mStagingEntry.auxiliaryType.SetValue(stagingAuxiliaryType);
     357              :         }
     358            0 :         else if (err != CHIP_ERROR_NOT_IMPLEMENTED)
     359              :         {
     360              :             // CHIP_ERROR_NOT_IMPLEMENTED is okay since this field is optional, and doesn't
     361              :             // need to be set in all cases (the implementation will be up to the delegate).
     362              :             // Any other sort of error is unexepcted so we return it here.
     363            0 :             return err;
     364              :         }
     365              :     }
     366              : 
     367              :     {
     368              :         size_t count;
     369            0 :         ReturnErrorOnFailure(mEntry.GetSubjectCount(count));
     370            0 :         if (count > 0)
     371              :         {
     372            0 :             for (size_t i = 0; i < count; ++i)
     373              :             {
     374              :                 NodeId subject;
     375            0 :                 ReturnErrorOnFailure(mEntry.GetSubject(i, subject));
     376              :                 StagingSubject tmp;
     377            0 :                 ReturnErrorOnFailure(Convert(subject, tmp));
     378            0 :                 mStagingSubjects[i] = tmp.nodeId;
     379              :             }
     380            0 :             mStagingEntry.subjects.SetNonNull(mStagingSubjects, count);
     381              :         }
     382              :         else
     383              :         {
     384            0 :             mStagingEntry.subjects.SetNull();
     385              :         }
     386              :     }
     387              : 
     388              :     {
     389              :         size_t count;
     390            0 :         ReturnErrorOnFailure(mEntry.GetTargetCount(count));
     391            0 :         if (count > 0)
     392              :         {
     393            0 :             for (size_t i = 0; i < count; ++i)
     394              :             {
     395            0 :                 Target target;
     396            0 :                 ReturnErrorOnFailure(mEntry.GetTarget(i, target));
     397            0 :                 ReturnErrorOnFailure(Convert(target, mStagingTargets[i]));
     398              :             }
     399            0 :             mStagingEntry.targets.SetNonNull(mStagingTargets, count);
     400              :         }
     401              :         else
     402              :         {
     403            0 :             mStagingEntry.targets.SetNull();
     404              :         }
     405              :     }
     406              : 
     407            0 :     return CHIP_NO_ERROR;
     408              : }
     409              : 
     410              : } // namespace app
     411              : } // namespace chip
        

Generated by: LCOV version 2.0-1