Matter SDK Coverage Report
Current view: top level - app/server - DefaultTermsAndConditionsProvider.cpp (source / functions) Coverage Total Hit
Test: SHA:f84fe08d06f240e801b5d923f8a938a9938ca110 Lines: 68.4 % 114 78
Test Date: 2025-02-22 08:08:07 Functions: 69.2 % 13 9

            Line data    Source code
       1              : /*
       2              :  *  Copyright (c) 2024 Project CHIP Authors
       3              :  *  All rights reserved.
       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 "DefaultTermsAndConditionsProvider.h"
      19              : #include "TermsAndConditionsProvider.h"
      20              : 
      21              : #include <lib/core/CHIPError.h>
      22              : #include <lib/core/TLV.h>
      23              : #include <lib/core/TLVTypes.h>
      24              : #include <lib/support/CodeUtils.h>
      25              : #include <lib/support/DefaultStorageKeyAllocator.h>
      26              : #include <lib/support/SafeInt.h>
      27              : #include <protocols/Protocols.h>
      28              : #include <protocols/interaction_model/StatusCode.h>
      29              : 
      30              : namespace {
      31              : constexpr chip::TLV::Tag kSerializationVersionTag            = chip::TLV::ContextTag(1);
      32              : constexpr chip::TLV::Tag kAcceptedAcknowledgementsTag        = chip::TLV::ContextTag(2);
      33              : constexpr chip::TLV::Tag kAcceptedAcknowledgementsVersionTag = chip::TLV::ContextTag(3);
      34              : constexpr uint8_t kSerializationSchemaMinimumVersion         = 1;
      35              : constexpr uint8_t kSerializationSchemaCurrentVersion         = 1;
      36              : 
      37              : constexpr size_t kEstimatedTlvBufferSize = chip::TLV::EstimateStructOverhead(sizeof(uint8_t),  // SerializationVersion
      38              :                                                                              sizeof(uint16_t), // AcceptedAcknowledgements
      39              :                                                                              sizeof(uint16_t)  // AcceptedAcknowledgementsVersion
      40              :                                                                              ) *
      41              :     4; // Extra space for rollback compatibility
      42              : } // namespace
      43              : 
      44           10 : CHIP_ERROR chip::app::DefaultTermsAndConditionsStorageDelegate::Init(PersistentStorageDelegate * inPersistentStorageDelegate)
      45              : {
      46           10 :     VerifyOrReturnValue(nullptr != inPersistentStorageDelegate, CHIP_ERROR_INVALID_ARGUMENT);
      47              : 
      48           10 :     mStorageDelegate = inPersistentStorageDelegate;
      49              : 
      50           10 :     return CHIP_NO_ERROR;
      51              : }
      52              : 
      53            0 : CHIP_ERROR chip::app::DefaultTermsAndConditionsStorageDelegate::Delete()
      54              : {
      55            0 :     VerifyOrReturnValue(nullptr != mStorageDelegate, CHIP_ERROR_UNINITIALIZED);
      56              : 
      57            0 :     const chip::StorageKeyName kStorageKey = chip::DefaultStorageKeyAllocator::TermsAndConditionsAcceptance();
      58            0 :     ReturnErrorOnFailure(mStorageDelegate->SyncDeleteKeyValue(kStorageKey.KeyName()));
      59              : 
      60            0 :     return CHIP_NO_ERROR;
      61            0 : }
      62              : 
      63            9 : CHIP_ERROR chip::app::DefaultTermsAndConditionsStorageDelegate::Get(Optional<TermsAndConditions> & outTermsAndConditions)
      64              : {
      65            9 :     VerifyOrReturnValue(nullptr != mStorageDelegate, CHIP_ERROR_UNINITIALIZED);
      66              : 
      67            9 :     uint8_t serializationVersion     = 0;
      68            9 :     uint16_t acknowledgements        = 0;
      69            9 :     uint16_t acknowledgementsVersion = 0;
      70              : 
      71            9 :     chip::TLV::TLVReader tlvReader;
      72              :     chip::TLV::TLVType tlvContainer;
      73              : 
      74            9 :     uint8_t buffer[kEstimatedTlvBufferSize] = { 0 };
      75            9 :     uint16_t bufferSize                     = sizeof(buffer);
      76              : 
      77            9 :     const chip::StorageKeyName kStorageKey = chip::DefaultStorageKeyAllocator::TermsAndConditionsAcceptance();
      78              : 
      79            9 :     CHIP_ERROR err = mStorageDelegate->SyncGetKeyValue(kStorageKey.KeyName(), &buffer, bufferSize);
      80            9 :     VerifyOrReturnValue(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == err || CHIP_NO_ERROR == err, err);
      81              : 
      82            9 :     if (CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == err)
      83              :     {
      84            5 :         outTermsAndConditions.ClearValue();
      85            5 :         return CHIP_NO_ERROR;
      86              :     }
      87              : 
      88            4 :     tlvReader.Init(buffer, bufferSize);
      89            4 :     ReturnErrorOnFailure(tlvReader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()));
      90            4 :     ReturnErrorOnFailure(tlvReader.EnterContainer(tlvContainer));
      91            4 :     ReturnErrorOnFailure(tlvReader.Next(kSerializationVersionTag));
      92            4 :     ReturnErrorOnFailure(tlvReader.Get(serializationVersion));
      93              : 
      94            4 :     if (serializationVersion < kSerializationSchemaMinimumVersion)
      95              :     {
      96            0 :         ChipLogError(AppServer, "The terms and conditions datastore schema (%hhu) is newer than oldest compatible schema (%hhu)",
      97              :                      serializationVersion, kSerializationSchemaMinimumVersion);
      98            0 :         return CHIP_IM_GLOBAL_STATUS(ConstraintError);
      99              :     }
     100              : 
     101            4 :     if (serializationVersion != kSerializationSchemaCurrentVersion)
     102              :     {
     103            0 :         ChipLogDetail(AppServer, "The terms and conditions datastore schema (%hhu) differs from current schema (%hhu)",
     104              :                       serializationVersion, kSerializationSchemaCurrentVersion);
     105              :     }
     106              : 
     107            4 :     ReturnErrorOnFailure(tlvReader.Next(kAcceptedAcknowledgementsTag));
     108            4 :     ReturnErrorOnFailure(tlvReader.Get(acknowledgements));
     109            4 :     ReturnErrorOnFailure(tlvReader.Next(kAcceptedAcknowledgementsVersionTag));
     110            4 :     ReturnErrorOnFailure(tlvReader.Get(acknowledgementsVersion));
     111            4 :     ReturnErrorOnFailure(tlvReader.ExitContainer(tlvContainer));
     112              : 
     113            4 :     outTermsAndConditions = Optional<TermsAndConditions>(TermsAndConditions(acknowledgements, acknowledgementsVersion));
     114              : 
     115            4 :     return CHIP_NO_ERROR;
     116            9 : }
     117              : 
     118            2 : CHIP_ERROR chip::app::DefaultTermsAndConditionsStorageDelegate::Set(const TermsAndConditions & inTermsAndConditions)
     119              : {
     120            2 :     uint8_t buffer[kEstimatedTlvBufferSize] = { 0 };
     121            2 :     chip::TLV::TLVWriter tlvWriter;
     122              :     chip::TLV::TLVType tlvContainer;
     123              : 
     124            2 :     VerifyOrReturnValue(nullptr != mStorageDelegate, CHIP_ERROR_UNINITIALIZED);
     125              : 
     126            2 :     tlvWriter.Init(buffer);
     127            2 :     ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, tlvContainer));
     128            2 :     ReturnErrorOnFailure(tlvWriter.Put(kSerializationVersionTag, kSerializationSchemaCurrentVersion));
     129            2 :     ReturnErrorOnFailure(tlvWriter.Put(kAcceptedAcknowledgementsTag, inTermsAndConditions.GetValue()));
     130            2 :     ReturnErrorOnFailure(tlvWriter.Put(kAcceptedAcknowledgementsVersionTag, inTermsAndConditions.GetVersion()));
     131            2 :     ReturnErrorOnFailure(tlvWriter.EndContainer(tlvContainer));
     132            2 :     ReturnErrorOnFailure(tlvWriter.Finalize());
     133              : 
     134            2 :     const chip::StorageKeyName kStorageKey = chip::DefaultStorageKeyAllocator::TermsAndConditionsAcceptance();
     135            2 :     ReturnErrorOnFailure(
     136              :         mStorageDelegate->SyncSetKeyValue(kStorageKey.KeyName(), buffer, static_cast<uint16_t>(tlvWriter.GetLengthWritten())));
     137              : 
     138            2 :     return CHIP_NO_ERROR;
     139            2 : }
     140              : 
     141           13 : CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::Init(
     142              :     TermsAndConditionsStorageDelegate * inStorageDelegate,
     143              :     const chip::Optional<chip::app::TermsAndConditions> & inRequiredTermsAndConditions)
     144              : {
     145           13 :     VerifyOrReturnValue(nullptr != inStorageDelegate, CHIP_ERROR_INVALID_ARGUMENT);
     146              : 
     147           13 :     mTermsAndConditionsStorageDelegate = inStorageDelegate;
     148           13 :     mRequiredAcknowledgements          = inRequiredTermsAndConditions;
     149              : 
     150           13 :     return CHIP_NO_ERROR;
     151              : }
     152              : 
     153            2 : CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::CommitAcceptance()
     154              : {
     155            2 :     VerifyOrReturnValue(nullptr != mTermsAndConditionsStorageDelegate, CHIP_ERROR_UNINITIALIZED);
     156              : 
     157              :     // No terms and conditions to commit
     158            2 :     VerifyOrReturnValue(mTemporalAcceptance.HasValue(), CHIP_NO_ERROR);
     159              : 
     160            2 :     ReturnErrorOnFailure(mTermsAndConditionsStorageDelegate->Set(mTemporalAcceptance.Value()));
     161            2 :     ChipLogProgress(AppServer, "Terms and conditions have been committed");
     162            2 :     mTemporalAcceptance.ClearValue();
     163              : 
     164            2 :     return CHIP_NO_ERROR;
     165              : }
     166              : 
     167           14 : CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::GetAcceptance(Optional<TermsAndConditions> & outTermsAndConditions) const
     168              : {
     169           14 :     VerifyOrReturnValue(nullptr != mTermsAndConditionsStorageDelegate, CHIP_ERROR_UNINITIALIZED);
     170              : 
     171              :     // Return the in-memory acceptance state
     172           14 :     if (mTemporalAcceptance.HasValue())
     173              :     {
     174            3 :         outTermsAndConditions = mTemporalAcceptance;
     175            3 :         return CHIP_NO_ERROR;
     176              :     }
     177              : 
     178              :     // Otherwise, try to get the persisted acceptance state
     179           11 :     CHIP_ERROR err = mTermsAndConditionsStorageDelegate->Get(outTermsAndConditions);
     180           11 :     VerifyOrReturnValue(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == err || CHIP_NO_ERROR == err, err);
     181              : 
     182           11 :     if (CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == err)
     183              :     {
     184            0 :         ChipLogError(AppServer, "No terms and conditions have been accepted");
     185            0 :         outTermsAndConditions.ClearValue();
     186            0 :         return CHIP_NO_ERROR;
     187              :     }
     188              : 
     189           11 :     return CHIP_NO_ERROR;
     190              : }
     191              : 
     192            0 : CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::GetAcknowledgementsRequired(bool & outAcknowledgementsRequired) const
     193              : {
     194            0 :     Optional<TermsAndConditions> requiredTermsAndConditionsMaybe;
     195            0 :     ReturnErrorOnFailure(GetRequirements(requiredTermsAndConditionsMaybe));
     196              : 
     197            0 :     if (!requiredTermsAndConditionsMaybe.HasValue())
     198              :     {
     199            0 :         outAcknowledgementsRequired = false;
     200            0 :         return CHIP_NO_ERROR;
     201              :     }
     202              : 
     203            0 :     Optional<TermsAndConditions> acceptedTermsAndConditionsMaybe;
     204            0 :     ReturnErrorOnFailure(GetAcceptance(acceptedTermsAndConditionsMaybe));
     205              : 
     206            0 :     if (!acceptedTermsAndConditionsMaybe.HasValue())
     207              :     {
     208            0 :         outAcknowledgementsRequired = true;
     209            0 :         return CHIP_NO_ERROR;
     210              :     }
     211              : 
     212            0 :     TermsAndConditions requiredTermsAndConditions = requiredTermsAndConditionsMaybe.Value();
     213            0 :     TermsAndConditions acceptedTermsAndConditions = acceptedTermsAndConditionsMaybe.Value();
     214              : 
     215            0 :     bool requiredTermsAndConditionsAreAccepted = requiredTermsAndConditions.Validate(acceptedTermsAndConditions);
     216            0 :     outAcknowledgementsRequired                = !requiredTermsAndConditionsAreAccepted;
     217            0 :     return CHIP_NO_ERROR;
     218              : }
     219              : 
     220            4 : CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::GetRequirements(Optional<TermsAndConditions> & outTermsAndConditions) const
     221              : {
     222            4 :     outTermsAndConditions = mRequiredAcknowledgements;
     223            4 :     return CHIP_NO_ERROR;
     224              : }
     225              : 
     226              : CHIP_ERROR
     227            0 : chip::app::DefaultTermsAndConditionsProvider::GetUpdateAcceptanceDeadline(Optional<uint32_t> & outUpdateAcceptanceDeadline) const
     228              : {
     229              :     // No-op stub implementation. This feature is not implemented in this default implementation.
     230            0 :     outUpdateAcceptanceDeadline = Optional<uint32_t>();
     231            0 :     return CHIP_NO_ERROR;
     232              : }
     233              : 
     234            0 : CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::ResetAcceptance()
     235              : {
     236            0 :     VerifyOrReturnValue(nullptr != mTermsAndConditionsStorageDelegate, CHIP_ERROR_UNINITIALIZED);
     237              : 
     238            0 :     (void) mTermsAndConditionsStorageDelegate->Delete();
     239            0 :     ReturnErrorOnFailure(RevertAcceptance());
     240            0 :     return CHIP_NO_ERROR;
     241              : }
     242              : 
     243            6 : CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::RevertAcceptance()
     244              : {
     245            6 :     mTemporalAcceptance.ClearValue();
     246            6 :     return CHIP_NO_ERROR;
     247              : }
     248              : 
     249            7 : CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::SetAcceptance(const Optional<TermsAndConditions> & inTermsAndConditions)
     250              : {
     251            7 :     mTemporalAcceptance = inTermsAndConditions;
     252            7 :     return CHIP_NO_ERROR;
     253              : }
        

Generated by: LCOV version 2.0-1