Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow runtime init of some Server members (2/2) #16070

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions src/access/AccessControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,37 +161,53 @@ namespace Access {

AccessControl::Entry::Delegate AccessControl::Entry::mDefaultDelegate;
AccessControl::EntryIterator::Delegate AccessControl::EntryIterator::mDefaultDelegate;
AccessControl::Delegate AccessControl::mDefaultDelegate;

CHIP_ERROR AccessControl::Init()
CHIP_ERROR AccessControl::Init(AccessControl::Delegate * delegate)
{
VerifyOrReturnError(!IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

ChipLogProgress(DataManagement, "AccessControl: initializing");
return mDelegate.Init();

// delegate can never be null. This was already checked
CHIP_ERROR retval = delegate->Init();
if (retval == CHIP_NO_ERROR)
tcarmelveilleux marked this conversation as resolved.
Show resolved Hide resolved
{
mDelegate = delegate;
}

return retval;
}

CHIP_ERROR AccessControl::Finish()
{
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
ChipLogProgress(DataManagement, "AccessControl: finishing");
return mDelegate.Finish();
CHIP_ERROR retval = mDelegate->Finish();
tcarmelveilleux marked this conversation as resolved.
Show resolved Hide resolved
mDelegate = nullptr;
return retval;
}

CHIP_ERROR AccessControl::Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath,
Privilege requestPrivilege)
{
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);

#if CHIP_PROGRESS_LOGGING
{
char buf[6 * kCharsPerCatForLogging];
constexpr size_t kMaxCatsToLog = 6;
char catLogBuf[kMaxCatsToLog * kCharsPerCatForLogging];
ChipLogProgress(DataManagement,
"AccessControl: checking f=%u a=%c s=0x" ChipLogFormatX64 " t=%s c=" ChipLogFormatMEI " e=%" PRIu16 " p=%c",
subjectDescriptor.fabricIndex, GetAuthModeStringForLogging(subjectDescriptor.authMode),
ChipLogValueX64(subjectDescriptor.subject),
GetCatStringForLogging(buf, sizeof(buf), subjectDescriptor.cats), ChipLogValueMEI(requestPath.cluster),
requestPath.endpoint, GetPrivilegeStringForLogging(requestPrivilege));
GetCatStringForLogging(catLogBuf, sizeof(catLogBuf), subjectDescriptor.cats),
ChipLogValueMEI(requestPath.cluster), requestPath.endpoint, GetPrivilegeStringForLogging(requestPrivilege));
}
#endif

// TODO(#13867): this will go away
if (mDelegate.TemporaryCheckOverride())
if (mDelegate->TemporaryCheckOverride())
{
ChipLogProgress(DataManagement, "AccessControl: temporary check override (this will go away)");
return CHIP_NO_ERROR;
Expand Down
57 changes: 42 additions & 15 deletions src/access/AccessControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "RequestPath.h"
#include "SubjectDescriptor.h"

#include "lib/support/CodeUtils.h"
#include <lib/core/CHIPCore.h>

namespace chip {
Expand Down Expand Up @@ -353,30 +354,46 @@ class AccessControl

AccessControl() = default;

AccessControl(Delegate & delegate) : mDelegate(delegate) {}

AccessControl(const AccessControl &) = delete;
AccessControl & operator=(const AccessControl &) = delete;

~AccessControl() { mDelegate.Release(); }
~AccessControl()
{
// Never-initialized AccessControl instances will not have the delegate set.
if (IsInitialized())
{
mDelegate->Release();
}
}

/**
* Initialize the access control module. Must be called before first use.
*
* @retval various errors, probably fatal.
* @param delegate - The delegate to use for acces control
*
* @return CHIP_NO_ERROR on success, CHIP_ERROR_INCORRECT_STATE if called more than once,
* CHIP_ERROR_INVALID_ARGUMENT if delegate is null, or other fatal error.
*/
CHIP_ERROR Init();
CHIP_ERROR Init(AccessControl::Delegate * delegate);

/**
* Deinitialize the access control module. Must be called when finished.
*/
CHIP_ERROR Finish();

// Capabilities
CHIP_ERROR GetMaxEntryCount(size_t & value) const { return mDelegate.GetMaxEntryCount(value); }
CHIP_ERROR GetMaxEntryCount(size_t & value) const
{
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
return mDelegate->GetMaxEntryCount(value);
}

// Actualities
CHIP_ERROR GetEntryCount(size_t & value) const { return mDelegate.GetEntryCount(value); }
CHIP_ERROR GetEntryCount(size_t & value) const
{
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
return mDelegate->GetEntryCount(value);
}

/**
* Prepares an entry.
Expand All @@ -385,7 +402,11 @@ class AccessControl
*
* @param [in] entry Entry to prepare.
*/
CHIP_ERROR PrepareEntry(Entry & entry) { return mDelegate.PrepareEntry(entry); }
CHIP_ERROR PrepareEntry(Entry & entry)
{
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
return mDelegate->PrepareEntry(entry);
}

/**
* Creates an entry in the access control list.
Expand All @@ -397,7 +418,8 @@ class AccessControl
CHIP_ERROR CreateEntry(size_t * index, const Entry & entry, FabricIndex * fabricIndex = nullptr)
{
ReturnErrorCodeIf(!IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT);
return mDelegate.CreateEntry(index, entry, fabricIndex);
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
return mDelegate->CreateEntry(index, entry, fabricIndex);
}

/**
Expand All @@ -409,7 +431,8 @@ class AccessControl
*/
CHIP_ERROR ReadEntry(size_t index, Entry & entry, const FabricIndex * fabricIndex = nullptr) const
{
return mDelegate.ReadEntry(index, entry, fabricIndex);
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
return mDelegate->ReadEntry(index, entry, fabricIndex);
}

/**
Expand All @@ -422,7 +445,8 @@ class AccessControl
CHIP_ERROR UpdateEntry(size_t index, const Entry & entry, const FabricIndex * fabricIndex = nullptr)
{
ReturnErrorCodeIf(!IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT);
return mDelegate.UpdateEntry(index, entry, fabricIndex);
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
return mDelegate->UpdateEntry(index, entry, fabricIndex);
}

/**
Expand All @@ -433,7 +457,8 @@ class AccessControl
*/
CHIP_ERROR DeleteEntry(size_t index, const FabricIndex * fabricIndex = nullptr)
{
return mDelegate.DeleteEntry(index, fabricIndex);
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
return mDelegate->DeleteEntry(index, fabricIndex);
}

/**
Expand All @@ -444,7 +469,8 @@ class AccessControl
*/
CHIP_ERROR Entries(EntryIterator & iterator, const FabricIndex * fabricIndex = nullptr) const
{
return mDelegate.Entries(iterator, fabricIndex);
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
return mDelegate->Entries(iterator, fabricIndex);
}

/**
Expand All @@ -458,10 +484,11 @@ class AccessControl
CHIP_ERROR Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath, Privilege requestPrivilege);

private:
bool IsInitialized() const { return (mDelegate != nullptr); }

bool IsValid(const Entry & entry);

static Delegate mDefaultDelegate;
Delegate & mDelegate = mDefaultDelegate;
Delegate * mDelegate = nullptr;
};

/**
Expand Down
4 changes: 2 additions & 2 deletions src/access/examples/ExampleAccessControlDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1310,11 +1310,11 @@ namespace chip {
namespace Access {
namespace Examples {

AccessControl::Delegate & GetAccessControlDelegate(PersistentStorageDelegate * storageDelegate)
AccessControl::Delegate * GetAccessControlDelegate(PersistentStorageDelegate * storageDelegate)
{
static AccessControlDelegate accessControlDelegate;
accessControlDelegate.SetStorageDelegate(storageDelegate);
return accessControlDelegate;
return &accessControlDelegate;
}

} // namespace Examples
Expand Down
4 changes: 2 additions & 2 deletions src/access/examples/ExampleAccessControlDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ namespace Examples {
* not manage lifecycle considerations.
*
* @param storageDelegate Storage instance to access persisted ACL data.
* @return a reference to the AccessControl::Delegate singleton.
* @return a pointer to the AccessControl::Delegate singleton.
*/
AccessControl::Delegate & GetAccessControlDelegate(PersistentStorageDelegate * storageDelegate);
AccessControl::Delegate * GetAccessControlDelegate(PersistentStorageDelegate * storageDelegate);

} // namespace Examples
} // namespace Access
Expand Down
4 changes: 2 additions & 2 deletions src/access/examples/PermissiveAccessControlDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ namespace chip {
namespace Access {
namespace Examples {

AccessControl::Delegate & GetPermissiveAccessControlDelegate()
AccessControl::Delegate * GetPermissiveAccessControlDelegate()
{
static AccessControlDelegate accessControlDelegate;
return accessControlDelegate;
return &accessControlDelegate;
}

} // namespace Examples
Expand Down
2 changes: 1 addition & 1 deletion src/access/examples/PermissiveAccessControlDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace chip {
namespace Access {
namespace Examples {

AccessControl::Delegate & GetPermissiveAccessControlDelegate();
AccessControl::Delegate * GetPermissiveAccessControlDelegate();

} // namespace Examples
} // namespace Access
Expand Down
5 changes: 3 additions & 2 deletions src/access/tests/TestAccessControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ using Entry = AccessControl::Entry;
using EntryIterator = AccessControl::EntryIterator;
using Target = Entry::Target;

AccessControl accessControl(Examples::GetAccessControlDelegate(nullptr));
AccessControl accessControl;

constexpr ClusterId kOnOffCluster = 0x0000'0006;
constexpr ClusterId kLevelControlCluster = 0x0000'0008;
Expand Down Expand Up @@ -2133,8 +2133,9 @@ void TestUpdateEntry(nlTestSuite * inSuite, void * inContext)

int Setup(void * inContext)
{
AccessControl::Delegate * delegate = Examples::GetAccessControlDelegate(nullptr);
SetAccessControl(accessControl);
GetAccessControl().Init();
VerifyOrDie(GetAccessControl().Init(delegate) == CHIP_NO_ERROR);
return SUCCESS;
}

Expand Down
9 changes: 7 additions & 2 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,14 @@ Server::Server() :
.devicePool = &mDevicePool,
.dnsResolver = nullptr,
}),
mGroupsProvider(mDeviceStorage), mAccessControl(Access::Examples::GetAccessControlDelegate(&mDeviceStorage))
mGroupsProvider(mDeviceStorage)
{}

CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint16_t unsecureServicePort,
Inet::InterfaceId interfaceId)
{
Access::AccessControl::Delegate * accessDelegate = nullptr;

mSecuredServicePort = secureServicePort;
mUnsecuredServicePort = unsecureServicePort;
mInterfaceId = interfaceId;
Expand Down Expand Up @@ -145,7 +147,10 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint
SetGroupDataProvider(&mGroupsProvider);

// Access control must be initialized after mDeviceStorage.
err = mAccessControl.Init();
accessDelegate = Access::Examples::GetAccessControlDelegate(&mDeviceStorage);
VerifyOrExit(accessDelegate != nullptr, ChipLogError(AppServer, "Invalid access delegate found."));

err = mAccessControl.Init(accessDelegate);
SuccessOrExit(err);
Access::SetAccessControl(mAccessControl);

Expand Down
6 changes: 3 additions & 3 deletions src/app/tests/AppTestContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

namespace {

chip::Access::AccessControl permissiveAccessControl(chip::Access::Examples::GetPermissiveAccessControlDelegate());
chip::Access::AccessControl gPermissiveAccessControl;

} // namespace

Expand All @@ -36,8 +36,8 @@ CHIP_ERROR AppContext::Init()
ReturnErrorOnFailure(Super::Init());
ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->Init(&GetExchangeManager()));

Access::SetAccessControl(permissiveAccessControl);
ReturnErrorOnFailure(Access::GetAccessControl().Init());
Access::SetAccessControl(gPermissiveAccessControl);
ReturnErrorOnFailure(Access::GetAccessControl().Init(chip::Access::Examples::GetPermissiveAccessControlDelegate()));

return CHIP_NO_ERROR;
}
Expand Down