<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

#include "LocalDomainAccessController.h"

#include <atomic>
#include <cassert>
#include <tuple>
#include <regex>

#include "joynr/infrastructure/GlobalDomainAccessControllerProxy.h"
#include "joynr/infrastructure/GlobalDomainAccessControlListEditorProxy.h"
#include "joynr/infrastructure/GlobalDomainRoleControllerProxy.h"
#include "joynr/infrastructure/DacTypes/DomainRoleEntry.h"
#include "joynr/MulticastSubscriptionQos.h"

namespace joynr
{

using namespace infrastructure;
using namespace infrastructure::DacTypes;

INIT_LOGGER(LocalDomainAccessController);

// 10 years
std::chrono::milliseconds LocalDomainAccessController::broadcastSubscriptionValidity =
        std::chrono::hours(24) * 365 * 10;

//--- Declarations of nested classes -------------------------------------------

class LocalDomainAccessController::Initialiser
{
public:
    Initialiser(LocalDomainAccessController& parent,
                const std::string& domain,
                const std::string& interfaceName);

    // Called to indicate that some data has been initialised
    void update();

    // Called to abort the initialisation
    void abort();

private:
    std::atomic<std::uint8_t> counter;
    std::atomic<bool> aborted;
    LocalDomainAccessController& parent;
    std::string domain;
    std::string interfaceName;
};

class LocalDomainAccessController::DomainRoleEntryChangedBroadcastListener
        : public ISubscriptionListener<infrastructure::DacTypes::ChangeType::Enum,
                                       infrastructure::DacTypes::DomainRoleEntry>
{
public:
    explicit DomainRoleEntryChangedBroadcastListener(LocalDomainAccessController& parent);
    void onSubscribed(const std::string& subscriptionId) override;
    void onReceive(const infrastructure::DacTypes::ChangeType::Enum& changeType,
                   const infrastructure::DacTypes::DomainRoleEntry& changedDre) override;
    void onError(const exceptions::JoynrRuntimeException& error) override;

private:
    LocalDomainAccessController& parent;
};

class LocalDomainAccessController::MasterAccessControlEntryChangedBroadcastListener
        : public ISubscriptionListener<infrastructure::DacTypes::ChangeType::Enum,
                                       infrastructure::DacTypes::MasterAccessControlEntry>
{
public:
    explicit MasterAccessControlEntryChangedBroadcastListener(LocalDomainAccessController& parent);
    void onSubscribed(const std::string& subscriptionId) override;
    void onReceive(
            const infrastructure::DacTypes::ChangeType::Enum& changeType,
            const infrastructure::DacTypes::MasterAccessControlEntry& changedMasterAce) override;
    void onError(const exceptions::JoynrRuntimeException& error) override;

private:
    LocalDomainAccessController& parent;
};

class LocalDomainAccessController::MediatorAccessControlEntryChangedBroadcastListener
        : public ISubscriptionListener<infrastructure::DacTypes::ChangeType::Enum,
                                       infrastructure::DacTypes::MasterAccessControlEntry>
{
public:
    explicit MediatorAccessControlEntryChangedBroadcastListener(
            LocalDomainAccessController& parent);
    void onSubscribed(const std::string& subscriptionId) override;
    void onReceive(
            const infrastructure::DacTypes::ChangeType::Enum& changeType,
            const infrastructure::DacTypes::MasterAccessControlEntry& changedMediatorAce) override;
    void onError(const exceptions::JoynrRuntimeException& error) override;

private:
    LocalDomainAccessController& parent;
};

class LocalDomainAccessController::OwnerAccessControlEntryChangedBroadcastListener
        : public ISubscriptionListener<infrastructure::DacTypes::ChangeType::Enum,
                                       infrastructure::DacTypes::OwnerAccessControlEntry>
{
public:
    explicit OwnerAccessControlEntryChangedBroadcastListener(LocalDomainAccessController& parent);
    void onSubscribed(const std::string& subscriptionId) override;
    void onReceive(
            const infrastructure::DacTypes::ChangeType::Enum& changeType,
            const infrastructure::DacTypes::OwnerAccessControlEntry& changedOwnerAce) override;
    void onError(const exceptions::JoynrRuntimeException& error) override;

private:
    LocalDomainAccessController& parent;
};

//--- LocalDomainAccessController ----------------------------------------------

LocalDomainAccessController::LocalDomainAccessController(
        std::unique_ptr<LocalDomainAccessStore> localDomainAccessStore)
        : accessControlAlgorithm(),
          dreSubscriptions(),
          aceSubscriptions(),
          globalDomainAccessControllerProxy(),
          globalDomainAccessControlListEditorProxy(),
          globalDomainRoleControllerProxy(),
          localDomainAccessStore(std::move(localDomainAccessStore)),
          consumerPermissionRequests(),
          initStateMutex(),
          domainRoleEntryChangedBroadcastListener(
                  std::make_shared<DomainRoleEntryChangedBroadcastListener>(*this)),
          masterAccessControlEntryChangedBroadcastListener(
                  std::make_shared<MasterAccessControlEntryChangedBroadcastListener>(*this)),
          mediatorAccessControlEntryChangedBroadcastListener(
                  std::make_shared<MediatorAccessControlEntryChangedBroadcastListener>(*this)),
          ownerAccessControlEntryChangedBroadcastListener(
                  std::make_shared<OwnerAccessControlEntryChangedBroadcastListener>(*this))
{
    // Iterate over all domain/interfaces in LocalDomainAccessStore and create for each a
    // subscription
    auto uniqueDomainInterfaceCombinations =
            this->localDomainAccessStore->getUniqueDomainInterfaceCombinations();
    for (const auto& domainInterfacePair : uniqueDomainInterfaceCombinations) {
        initialised(domainInterfacePair.first, domainInterfacePair.second, true);
    }
}

void LocalDomainAccessController::init(
        std::unique_ptr<GlobalDomainAccessControllerProxy> globalDomainAccessControllerProxy)
{
    this->globalDomainAccessControllerProxy = std::move(globalDomainAccessControllerProxy);
}

void LocalDomainAccessController::init(std::shared_ptr<GlobalDomainAccessControlListEditorProxy>
                                               globalDomainAccessControlListEditorProxy)
{
    this->globalDomainAccessControlListEditorProxy =
            std::move(globalDomainAccessControlListEditorProxy);
}

void LocalDomainAccessController::init(
        std::shared_ptr<GlobalDomainRoleControllerProxy> globalDomainRoleControllerProxy)
{
    this->globalDomainRoleControllerProxy = std::move(globalDomainRoleControllerProxy);
}

bool LocalDomainAccessController::hasRole(const std::string& userId,
                                          const std::string& domain,
                                          Role::Enum role)
{
    JOYNR_LOG_TRACE(logger, "execute: entering hasRole");

    // See if the user has the given role<commit_msg>[C++] Iterate over persisted AccessStore after init method.<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

#include "LocalDomainAccessController.h"

#include <atomic>
#include <cassert>
#include <tuple>
#include <regex>

#include "joynr/infrastructure/GlobalDomainAccessControllerProxy.h"
#include "joynr/infrastructure/GlobalDomainAccessControlListEditorProxy.h"
#include "joynr/infrastructure/GlobalDomainRoleControllerProxy.h"
#include "joynr/infrastructure/DacTypes/DomainRoleEntry.h"
#include "joynr/MulticastSubscriptionQos.h"

namespace joynr
{

using namespace infrastructure;
using namespace infrastructure::DacTypes;

INIT_LOGGER(LocalDomainAccessController);

// 10 years
std::chrono::milliseconds LocalDomainAccessController::broadcastSubscriptionValidity =
        std::chrono::hours(24) * 365 * 10;

//--- Declarations of nested classes -------------------------------------------

class LocalDomainAccessController::Initialiser
{
public:
    Initialiser(LocalDomainAccessController& parent,
                const std::string& domain,
                const std::string& interfaceName);

    // Called to indicate that some data has been initialised
    void update();

    // Called to abort the initialisation
    void abort();

private:
    std::atomic<std::uint8_t> counter;
    std::atomic<bool> aborted;
    LocalDomainAccessController& parent;
    std::string domain;
    std::string interfaceName;
};

class LocalDomainAccessController::DomainRoleEntryChangedBroadcastListener
        : public ISubscriptionListener<infrastructure::DacTypes::ChangeType::Enum,
                                       infrastructure::DacTypes::DomainRoleEntry>
{
public:
    explicit DomainRoleEntryChangedBroadcastListener(LocalDomainAccessController& parent);
    void onSubscribed(const std::string& subscriptionId) override;
    void onReceive(const infrastructure::DacTypes::ChangeType::Enum& changeType,
                   const infrastructure::DacTypes::DomainRoleEntry& changedDre) override;
    void onError(const exceptions::JoynrRuntimeException& error) override;

private:
    LocalDomainAccessController& parent;
};

class LocalDomainAccessController::MasterAccessControlEntryChangedBroadcastListener
        : public ISubscriptionListener<infrastructure::DacTypes::ChangeType::Enum,
                                       infrastructure::DacTypes::MasterAccessControlEntry>
{
public:
    explicit MasterAccessControlEntryChangedBroadcastListener(LocalDomainAccessController& parent);
    void onSubscribed(const std::string& subscriptionId) override;
    void onReceive(
            const infrastructure::DacTypes::ChangeType::Enum& changeType,
            const infrastructure::DacTypes::MasterAccessControlEntry& changedMasterAce) override;
    void onError(const exceptions::JoynrRuntimeException& error) override;

private:
    LocalDomainAccessController& parent;
};

class LocalDomainAccessController::MediatorAccessControlEntryChangedBroadcastListener
        : public ISubscriptionListener<infrastructure::DacTypes::ChangeType::Enum,
                                       infrastructure::DacTypes::MasterAccessControlEntry>
{
public:
    explicit MediatorAccessControlEntryChangedBroadcastListener(
            LocalDomainAccessController& parent);
    void onSubscribed(const std::string& subscriptionId) override;
    void onReceive(
            const infrastructure::DacTypes::ChangeType::Enum& changeType,
            const infrastructure::DacTypes::MasterAccessControlEntry& changedMediatorAce) override;
    void onError(const exceptions::JoynrRuntimeException& error) override;

private:
    LocalDomainAccessController& parent;
};

class LocalDomainAccessController::OwnerAccessControlEntryChangedBroadcastListener
        : public ISubscriptionListener<infrastructure::DacTypes::ChangeType::Enum,
                                       infrastructure::DacTypes::OwnerAccessControlEntry>
{
public:
    explicit OwnerAccessControlEntryChangedBroadcastListener(LocalDomainAccessController& parent);
    void onSubscribed(const std::string& subscriptionId) override;
    void onReceive(
            const infrastructure::DacTypes::ChangeType::Enum& changeType,
            const infrastructure::DacTypes::OwnerAccessControlEntry& changedOwnerAce) override;
    void onError(const exceptions::JoynrRuntimeException& error) override;

private:
    LocalDomainAccessController& parent;
};

//--- LocalDomainAccessController ----------------------------------------------

LocalDomainAccessController::LocalDomainAccessController(
        std::unique_ptr<LocalDomainAccessStore> localDomainAccessStore)
        : accessControlAlgorithm(),
          dreSubscriptions(),
          aceSubscriptions(),
          globalDomainAccessControllerProxy(),
          globalDomainAccessControlListEditorProxy(),
          globalDomainRoleControllerProxy(),
          localDomainAccessStore(std::move(localDomainAccessStore)),
          consumerPermissionRequests(),
          initStateMutex(),
          domainRoleEntryChangedBroadcastListener(
                  std::make_shared<DomainRoleEntryChangedBroadcastListener>(*this)),
          masterAccessControlEntryChangedBroadcastListener(
                  std::make_shared<MasterAccessControlEntryChangedBroadcastListener>(*this)),
          mediatorAccessControlEntryChangedBroadcastListener(
                  std::make_shared<MediatorAccessControlEntryChangedBroadcastListener>(*this)),
          ownerAccessControlEntryChangedBroadcastListener(
                  std::make_shared<OwnerAccessControlEntryChangedBroadcastListener>(*this))
{
}

void LocalDomainAccessController::init(
        std::unique_ptr<GlobalDomainAccessControllerProxy> globalDomainAccessControllerProxy)
{
    this->globalDomainAccessControllerProxy = std::move(globalDomainAccessControllerProxy);

    // Iterate over all domain/interfaces in LocalDomainAccessStore and create for each a
    // subscription
    auto uniqueDomainInterfaceCombinations =
            localDomainAccessStore->getUniqueDomainInterfaceCombinations();
    const bool restoringFromFile = true;
    for (const auto& domainInterfacePair : uniqueDomainInterfaceCombinations) {
        initialised(domainInterfacePair.first, domainInterfacePair.second, restoringFromFile);
    }
}

void LocalDomainAccessController::init(std::shared_ptr<GlobalDomainAccessControlListEditorProxy>
                                               globalDomainAccessControlListEditorProxy)
{
    this->globalDomainAccessControlListEditorProxy =
            std::move(globalDomainAccessControlListEditorProxy);
}

void LocalDomainAccessController::init(
        std::shared_ptr<GlobalDomainRoleControllerProxy> globalDomainRoleControllerProxy)
{
    this->globalDomainRoleControllerProxy = std::move(globalDomainRoleControllerProxy);
}

bool LocalDomainAccessController::hasRole(const std::string& userId,
                                          const std::string& domain,
                                          Role::Enum role)
{
    JOYNR_LOG_TRACE(logger, "execute: entering hasRole");

    // See if the user has the given role
{'fraction_non_alphanumeric': 0.08916824073470983, 'fraction_numerical': 0.0023448186022275775, 'mean_word_length': 4.03740157480315, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4942661', 'n_tokens_mistral': 3646, 'n_tokens_neox': 3568, 'n_words': 758}