LCOV - code coverage report
Current view: top level - app/server - AclStorage.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 0 175 0.0 %
Date: 2024-02-15 08:20:41 Functions: 0 13 0.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 StagingTarget    = Clusters::AccessControl::Structs::AccessControlTargetStruct::Type;
      31             : using Target           = AccessControl::Entry::Target;
      32             : 
      33             : namespace {
      34             : 
      35             : struct StagingSubject
      36             : {
      37             :     NodeId nodeId;
      38             :     StagingAuthMode authMode;
      39             : };
      40             : 
      41           0 : CHIP_ERROR Convert(AuthMode from, StagingAuthMode & to)
      42             : {
      43           0 :     switch (from)
      44             :     {
      45           0 :     case AuthMode::kPase:
      46           0 :         to = StagingAuthMode::kPase;
      47           0 :         break;
      48           0 :     case AuthMode::kCase:
      49           0 :         to = StagingAuthMode::kCase;
      50           0 :         break;
      51           0 :     case AuthMode::kGroup:
      52           0 :         to = StagingAuthMode::kGroup;
      53           0 :         break;
      54           0 :     default:
      55           0 :         return CHIP_ERROR_INVALID_ARGUMENT;
      56             :     }
      57           0 :     return CHIP_NO_ERROR;
      58             : }
      59             : 
      60           0 : CHIP_ERROR Convert(StagingAuthMode from, AuthMode & to)
      61             : {
      62           0 :     switch (from)
      63             :     {
      64           0 :     case StagingAuthMode::kPase:
      65           0 :         to = AuthMode::kPase;
      66           0 :         break;
      67           0 :     case StagingAuthMode::kCase:
      68           0 :         to = AuthMode::kCase;
      69           0 :         break;
      70           0 :     case StagingAuthMode::kGroup:
      71           0 :         to = AuthMode::kGroup;
      72           0 :         break;
      73           0 :     default:
      74           0 :         return CHIP_ERROR_INVALID_ARGUMENT;
      75             :     }
      76           0 :     return CHIP_NO_ERROR;
      77             : }
      78             : 
      79           0 : CHIP_ERROR Convert(Privilege from, StagingPrivilege & to)
      80             : {
      81           0 :     switch (from)
      82             :     {
      83           0 :     case Privilege::kView:
      84           0 :         to = StagingPrivilege::kView;
      85           0 :         break;
      86           0 :     case Privilege::kProxyView:
      87           0 :         to = StagingPrivilege::kProxyView;
      88           0 :         break;
      89           0 :     case Privilege::kOperate:
      90           0 :         to = StagingPrivilege::kOperate;
      91           0 :         break;
      92           0 :     case Privilege::kManage:
      93           0 :         to = StagingPrivilege::kManage;
      94           0 :         break;
      95           0 :     case Privilege::kAdminister:
      96           0 :         to = StagingPrivilege::kAdminister;
      97           0 :         break;
      98           0 :     default:
      99           0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     100             :     }
     101           0 :     return CHIP_NO_ERROR;
     102             : }
     103             : 
     104           0 : CHIP_ERROR Convert(StagingPrivilege from, Privilege & to)
     105             : {
     106           0 :     switch (from)
     107             :     {
     108           0 :     case StagingPrivilege::kView:
     109           0 :         to = Privilege::kView;
     110           0 :         break;
     111           0 :     case StagingPrivilege::kProxyView:
     112           0 :         to = Privilege::kProxyView;
     113           0 :         break;
     114           0 :     case StagingPrivilege::kOperate:
     115           0 :         to = Privilege::kOperate;
     116           0 :         break;
     117           0 :     case StagingPrivilege::kManage:
     118           0 :         to = Privilege::kManage;
     119           0 :         break;
     120           0 :     case StagingPrivilege::kAdminister:
     121           0 :         to = Privilege::kAdminister;
     122           0 :         break;
     123           0 :     default:
     124           0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     125             :     }
     126           0 :     return CHIP_NO_ERROR;
     127             : }
     128             : 
     129           0 : CHIP_ERROR Convert(NodeId from, StagingSubject & to)
     130             : {
     131           0 :     if (IsOperationalNodeId(from) || IsCASEAuthTag(from))
     132             :     {
     133           0 :         to = { .nodeId = from, .authMode = StagingAuthMode::kCase };
     134             :     }
     135           0 :     else if (IsGroupId(from))
     136             :     {
     137           0 :         to = { .nodeId = GroupIdFromNodeId(from), .authMode = StagingAuthMode::kGroup };
     138             :     }
     139           0 :     else if (IsPAKEKeyId(from))
     140             :     {
     141           0 :         to = { .nodeId = PAKEKeyIdFromNodeId(from), .authMode = StagingAuthMode::kPase };
     142             :     }
     143             :     else
     144             :     {
     145           0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     146             :     }
     147           0 :     return CHIP_NO_ERROR;
     148             : }
     149             : 
     150           0 : CHIP_ERROR Convert(StagingSubject from, NodeId & to)
     151             : {
     152           0 :     switch (from.authMode)
     153             :     {
     154           0 :     case StagingAuthMode::kPase:
     155           0 :         ReturnErrorCodeIf((from.nodeId & ~kMaskPAKEKeyId) != 0, CHIP_ERROR_INVALID_ARGUMENT);
     156           0 :         to = NodeIdFromPAKEKeyId(static_cast<PasscodeId>(from.nodeId));
     157           0 :         break;
     158           0 :     case StagingAuthMode::kCase:
     159           0 :         to = from.nodeId;
     160           0 :         break;
     161           0 :     case StagingAuthMode::kGroup:
     162           0 :         ReturnErrorCodeIf((from.nodeId & ~kMaskGroupId) != 0, CHIP_ERROR_INVALID_ARGUMENT);
     163           0 :         to = NodeIdFromGroupId(static_cast<GroupId>(from.nodeId));
     164           0 :         break;
     165           0 :     default:
     166           0 :         return CHIP_ERROR_INVALID_ARGUMENT;
     167             :     }
     168           0 :     return CHIP_NO_ERROR;
     169             : }
     170             : 
     171           0 : CHIP_ERROR Convert(const Target & from, StagingTarget & to)
     172             : {
     173           0 :     if ((from.flags & Target::kCluster) != 0)
     174             :     {
     175           0 :         to.cluster.SetNonNull(from.cluster);
     176             :     }
     177             :     else
     178             :     {
     179           0 :         to.cluster.SetNull();
     180             :     }
     181           0 :     if ((from.flags & Target::kEndpoint) != 0)
     182             :     {
     183           0 :         to.endpoint.SetNonNull(from.endpoint);
     184             :     }
     185             :     else
     186             :     {
     187           0 :         to.endpoint.SetNull();
     188             :     }
     189           0 :     if ((from.flags & Target::kDeviceType) != 0)
     190             :     {
     191           0 :         to.deviceType.SetNonNull(from.deviceType);
     192             :     }
     193             :     else
     194             :     {
     195           0 :         to.deviceType.SetNull();
     196             :     }
     197           0 :     return CHIP_NO_ERROR;
     198             : }
     199             : 
     200           0 : CHIP_ERROR Convert(const StagingTarget & from, Target & to)
     201             : {
     202           0 :     to.flags = 0;
     203           0 :     if (!from.cluster.IsNull())
     204             :     {
     205           0 :         to.flags |= Target::kCluster;
     206           0 :         to.cluster = from.cluster.Value();
     207             :     }
     208           0 :     if (!from.endpoint.IsNull())
     209             :     {
     210           0 :         to.flags |= Target::kEndpoint;
     211           0 :         to.endpoint = from.endpoint.Value();
     212             :     }
     213           0 :     if (!from.deviceType.IsNull())
     214             :     {
     215           0 :         to.flags |= Target::kDeviceType;
     216           0 :         to.deviceType = from.deviceType.Value();
     217             :     }
     218           0 :     return CHIP_NO_ERROR;
     219             : }
     220             : 
     221             : } // namespace
     222             : 
     223             : namespace chip {
     224             : namespace app {
     225             : 
     226           0 : CHIP_ERROR AclStorage::DecodableEntry::Decode(TLV::TLVReader & reader)
     227             : {
     228           0 :     ReturnErrorOnFailure(mStagingEntry.Decode(reader));
     229           0 :     ReturnErrorOnFailure(Unstage());
     230           0 :     return CHIP_NO_ERROR;
     231             : }
     232             : 
     233           0 : CHIP_ERROR AclStorage::DecodableEntry::Unstage()
     234             : {
     235           0 :     ReturnErrorOnFailure(GetAccessControl().PrepareEntry(mEntry));
     236             : 
     237           0 :     ReturnErrorOnFailure(mEntry.SetFabricIndex(mStagingEntry.fabricIndex));
     238             : 
     239             :     {
     240             :         Privilege privilege;
     241           0 :         ReturnErrorOnFailure(Convert(mStagingEntry.privilege, privilege));
     242           0 :         ReturnErrorOnFailure(mEntry.SetPrivilege(privilege));
     243             :     }
     244             : 
     245             :     {
     246             :         AuthMode authMode;
     247           0 :         ReturnErrorOnFailure(Convert(mStagingEntry.authMode, authMode));
     248           0 :         ReturnErrorOnFailure(mEntry.SetAuthMode(authMode));
     249             :     }
     250             : 
     251           0 :     if (!mStagingEntry.subjects.IsNull())
     252             :     {
     253           0 :         auto iterator = mStagingEntry.subjects.Value().begin();
     254           0 :         while (iterator.Next())
     255             :         {
     256           0 :             StagingSubject tmp = { .nodeId = iterator.GetValue(), .authMode = mStagingEntry.authMode };
     257             :             NodeId subject;
     258           0 :             ReturnErrorOnFailure(Convert(tmp, subject));
     259           0 :             ReturnErrorOnFailure(mEntry.AddSubject(nullptr, subject));
     260             :         }
     261           0 :         ReturnErrorOnFailure(iterator.GetStatus());
     262           0 :     }
     263             : 
     264           0 :     if (!mStagingEntry.targets.IsNull())
     265             :     {
     266           0 :         auto iterator = mStagingEntry.targets.Value().begin();
     267           0 :         while (iterator.Next())
     268             :         {
     269           0 :             Target target;
     270           0 :             ReturnErrorOnFailure(Convert(iterator.GetValue(), target));
     271           0 :             ReturnErrorOnFailure(mEntry.AddTarget(nullptr, target));
     272             :         }
     273           0 :         ReturnErrorOnFailure(iterator.GetStatus());
     274           0 :     }
     275             : 
     276           0 :     return CHIP_NO_ERROR;
     277             : }
     278             : 
     279           0 : CHIP_ERROR AclStorage::EncodableEntry::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex fabric) const
     280             : {
     281           0 :     ReturnErrorOnFailure(Stage());
     282           0 :     ReturnErrorOnFailure(mStagingEntry.EncodeForRead(writer, tag, fabric));
     283           0 :     return CHIP_NO_ERROR;
     284             : }
     285             : 
     286           0 : CHIP_ERROR AclStorage::EncodableEntry::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
     287             : {
     288           0 :     ReturnErrorOnFailure(Stage());
     289           0 :     ReturnErrorOnFailure(mStagingEntry.EncodeForWrite(writer, tag));
     290           0 :     return CHIP_NO_ERROR;
     291             : }
     292             : 
     293           0 : CHIP_ERROR AclStorage::EncodableEntry::Stage() const
     294             : {
     295           0 :     ReturnErrorOnFailure(mEntry.GetFabricIndex(mStagingEntry.fabricIndex));
     296             : 
     297             :     {
     298             :         Privilege privilege;
     299           0 :         ReturnErrorOnFailure(mEntry.GetPrivilege(privilege));
     300           0 :         ReturnErrorOnFailure(Convert(privilege, mStagingEntry.privilege));
     301             :     }
     302             : 
     303             :     {
     304             :         AuthMode authMode;
     305           0 :         ReturnErrorOnFailure(mEntry.GetAuthMode(authMode));
     306           0 :         ReturnErrorOnFailure(Convert(authMode, mStagingEntry.authMode));
     307             :     }
     308             : 
     309             :     {
     310             :         size_t count;
     311           0 :         ReturnErrorOnFailure(mEntry.GetSubjectCount(count));
     312           0 :         if (count > 0)
     313             :         {
     314           0 :             for (size_t i = 0; i < count; ++i)
     315             :             {
     316             :                 NodeId subject;
     317           0 :                 ReturnErrorOnFailure(mEntry.GetSubject(i, subject));
     318             :                 StagingSubject tmp;
     319           0 :                 ReturnErrorOnFailure(Convert(subject, tmp));
     320           0 :                 mStagingSubjects[i] = tmp.nodeId;
     321             :             }
     322           0 :             mStagingEntry.subjects.SetNonNull(mStagingSubjects, count);
     323             :         }
     324             :         else
     325             :         {
     326           0 :             mStagingEntry.subjects.SetNull();
     327             :         }
     328             :     }
     329             : 
     330             :     {
     331             :         size_t count;
     332           0 :         ReturnErrorOnFailure(mEntry.GetTargetCount(count));
     333           0 :         if (count > 0)
     334             :         {
     335           0 :             for (size_t i = 0; i < count; ++i)
     336             :             {
     337           0 :                 Target target;
     338           0 :                 ReturnErrorOnFailure(mEntry.GetTarget(i, target));
     339           0 :                 ReturnErrorOnFailure(Convert(target, mStagingTargets[i]));
     340             :             }
     341           0 :             mStagingEntry.targets.SetNonNull(mStagingTargets, count);
     342             :         }
     343             :         else
     344             :         {
     345           0 :             mStagingEntry.targets.SetNull();
     346             :         }
     347             :     }
     348             : 
     349           0 :     return CHIP_NO_ERROR;
     350             : }
     351             : 
     352             : } // namespace app
     353             : } // namespace chip

Generated by: LCOV version 1.14