<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2013 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 "AccessController.h"

#include "LocalDomainAccessController.h"
#include "joynr/LocalCapabilitiesDirectory.h"

#include "joynr/JsonSerializer.h"
#include "joynr/JoynrMessage.h"
#include "joynr/types/QtDiscoveryEntry.h"
#include "joynr/RequestStatus.h"
#include "joynr/Request.h"
#include "joynr/SubscriptionRequest.h"
#include "joynr/BroadcastSubscriptionRequest.h"
#include "joynr/system/RoutingTypes_QtAddress.h"
#include "joynr/joynrlogging.h"

#include <QByteArray>
#include <QScopedPointer>

#include <cassert>
#include "joynr/JsonSerializer.h"

namespace joynr
{

using namespace infrastructure;
using namespace infrastructure::DacTypes;
using namespace types;
using namespace joynr_logging;

Logger* AccessController::logger = Logging::getInstance()->getLogger("MSG", "AccessController");

//--------- InternalConsumerPermissionCallbacks --------------------------------

class AccessController::LdacConsumerPermissionCallback
        : public LocalDomainAccessController::IGetConsumerPermissionCallback
{

public:
    LdacConsumerPermissionCallback(
            AccessController& owningAccessController,
            const JoynrMessage& message,
            const QString& domain,
            const QString& interfaceName,
            QtTrustLevel::Enum trustlevel,
            std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback);

    // Callbacks made from the LocalDomainAccessController
    void consumerPermission(Permission::Enum permission);
    void operationNeeded();

private:
    AccessController& owningAccessController;
    JoynrMessage message;
    QString domain;
    QString interfaceName;
    QtTrustLevel::Enum trustlevel;
    std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback;

    bool convertToBool(QtPermission::Enum permission);
};

AccessController::LdacConsumerPermissionCallback::LdacConsumerPermissionCallback(
        AccessController& parent,
        const JoynrMessage& message,
        const QString& domain,
        const QString& interfaceName,
        QtTrustLevel::Enum trustlevel,
        std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback)
        : owningAccessController(parent),
          message(message),
          domain(domain),
          interfaceName(interfaceName),
          trustlevel(trustlevel),
          callback(callback)
{
}

void AccessController::LdacConsumerPermissionCallback::consumerPermission(
        Permission::Enum permission)
{
    bool hasPermission = convertToBool(QtPermission::createQt(permission));

    if (hasPermission == false) {
        LOG_ERROR(logger,
                  QString("Message %1 to domain %2, interface %3 failed ACL check")
                          .arg(QString::fromStdString(message.getHeaderMessageId()))
                          .arg(domain)
                          .arg(interfaceName));
    }
    callback->hasConsumerPermission(hasPermission);
}

void AccessController::LdacConsumerPermissionCallback::operationNeeded()
{

    QString operation;
    std::string messageType = message.getType();

    // Deserialize the message to get the operation
    QByteArray jsonRequest = QByteArray(message.getPayload().c_str());

    if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_REQUEST) {

        QScopedPointer<Request> request(JsonSerializer::deserializeQObject<Request>(jsonRequest));
        if (!request.isNull()) {
            operation = TypeUtil::toQt(request->getMethodName());
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REQUEST) {

        QScopedPointer<SubscriptionRequest> request(
                JsonSerializer::deserializeQObject<SubscriptionRequest>(jsonRequest));
        if (!request.isNull()) {
            operation = QString::fromStdString(request->getSubscribeToName());
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_BROADCAST_SUBSCRIPTION_REQUEST) {

        QScopedPointer<BroadcastSubscriptionRequest> request(
                JsonSerializer::deserializeQObject<BroadcastSubscriptionRequest>(jsonRequest));
        if (!request.isNull()) {
            operation = QString::fromStdString(request->getSubscribeToName());
        }
    }

    if (operation.isEmpty()) {
        LOG_ERROR(logger, "Could not deserialize request");
        callback->hasConsumerPermission(false);
        return;
    }

    // Get the permission for given operation
    QtPermission::Enum permission =
            owningAccessController.localDomainAccessController.getConsumerPermission(
                    message.getHeaderCreatorUserId(),
                    domain.toStdString(),
                    interfaceName.toStdString(),
                    operation.toStdString(),
                    QtTrustLevel::createStd(trustlevel));

    bool hasPermission = convertToBool(permission);

    if (hasPermission == false) {
        LOG_ERROR(logger,
                  QString("Message %1 to domain %2, interface/operation %3/%4 failed ACL check")
                          .arg(QString::fromStdString(message.getHeaderMessageId()))
                          .arg(domain)
                          .arg(interfaceName)
                          .arg(operation));
    }

    callback->hasConsumerPermission(hasPermission);
}

bool AccessController::LdacConsumerPermissionCallback::convertToBool(QtPermission::Enum permission)
{
    switch (permission) {
    case QtPermission::YES:
        return true;
    case QtPermission::ASK:
        Q_ASSERT_X(false,
                   "hasConsumerPermission",
                   "QtPermission.ASK user dialog not yet implemented.");<commit_msg>[C++] fixed AccessControllerTest<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2013 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 "AccessController.h"

#include "LocalDomainAccessController.h"
#include "joynr/LocalCapabilitiesDirectory.h"

#include "joynr/JsonSerializer.h"
#include "joynr/JoynrMessage.h"
#include "joynr/types/QtDiscoveryEntry.h"
#include "joynr/RequestStatus.h"
#include "joynr/Request.h"
#include "joynr/SubscriptionRequest.h"
#include "joynr/BroadcastSubscriptionRequest.h"
#include "joynr/system/RoutingTypes_QtAddress.h"
#include "joynr/joynrlogging.h"

#include <QByteArray>
#include <QScopedPointer>

#include <cassert>
#include "joynr/JsonSerializer.h"

namespace joynr
{

using namespace infrastructure;
using namespace infrastructure::DacTypes;
using namespace types;
using namespace joynr_logging;

Logger* AccessController::logger = Logging::getInstance()->getLogger("MSG", "AccessController");

//--------- InternalConsumerPermissionCallbacks --------------------------------

class AccessController::LdacConsumerPermissionCallback
        : public LocalDomainAccessController::IGetConsumerPermissionCallback
{

public:
    LdacConsumerPermissionCallback(
            AccessController& owningAccessController,
            const JoynrMessage& message,
            const QString& domain,
            const QString& interfaceName,
            QtTrustLevel::Enum trustlevel,
            std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback);

    // Callbacks made from the LocalDomainAccessController
    void consumerPermission(Permission::Enum permission);
    void operationNeeded();

private:
    AccessController& owningAccessController;
    JoynrMessage message;
    QString domain;
    QString interfaceName;
    QtTrustLevel::Enum trustlevel;
    std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback;

    bool convertToBool(QtPermission::Enum permission);
};

AccessController::LdacConsumerPermissionCallback::LdacConsumerPermissionCallback(
        AccessController& parent,
        const JoynrMessage& message,
        const QString& domain,
        const QString& interfaceName,
        QtTrustLevel::Enum trustlevel,
        std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback)
        : owningAccessController(parent),
          message(message),
          domain(domain),
          interfaceName(interfaceName),
          trustlevel(trustlevel),
          callback(callback)
{
}

void AccessController::LdacConsumerPermissionCallback::consumerPermission(
        Permission::Enum permission)
{
    bool hasPermission = convertToBool(QtPermission::createQt(permission));

    if (hasPermission == false) {
        LOG_ERROR(logger,
                  QString("Message %1 to domain %2, interface %3 failed ACL check")
                          .arg(QString::fromStdString(message.getHeaderMessageId()))
                          .arg(domain)
                          .arg(interfaceName));
    }
    callback->hasConsumerPermission(hasPermission);
}

void AccessController::LdacConsumerPermissionCallback::operationNeeded()
{

    std::string operation;
    std::string messageType = message.getType();

    if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_REQUEST) {

        std::unique_ptr<Request> request(
                JsonSerializer::deserialize<Request>(message.getPayload()));
        if (request) {
            operation = request->getMethodName();
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REQUEST) {

        std::unique_ptr<SubscriptionRequest> request(
                JsonSerializer::deserialize<SubscriptionRequest>(message.getPayload()));
        if (request) {
            operation = request->getSubscribeToName();
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_BROADCAST_SUBSCRIPTION_REQUEST) {

        std::unique_ptr<BroadcastSubscriptionRequest> request(
                JsonSerializer::deserialize<BroadcastSubscriptionRequest>(message.getPayload()));
        if (request) {
            operation = request->getSubscribeToName();
        }
    }

    if (operation.empty()) {
        LOG_ERROR(logger, "Could not deserialize request");
        callback->hasConsumerPermission(false);
        return;
    }

    // Get the permission for given operation
    QtPermission::Enum permission =
            owningAccessController.localDomainAccessController.getConsumerPermission(
                    message.getHeaderCreatorUserId(),
                    domain.toStdString(),
                    interfaceName.toStdString(),
                    operation,
                    QtTrustLevel::createStd(trustlevel));

    bool hasPermission = convertToBool(permission);

    if (hasPermission == false) {
        LOG_ERROR(logger,
                  QString("Message %1 to domain %2, interface/operation %3/%4 failed ACL check")
                          .arg(QString::fromStdString(message.getHeaderMessageId()))
                          .arg(domain)
                          .arg(interfaceName)
                          .arg(QString::fromStdString(operation)));
    }

    callback->hasConsumerPermission(hasPermission);
}

bool AccessController::LdacConsumerPermissionCallback::convertToBool(QtPermission::Enum permission)
{
    switch (permission) {
    case QtPermission::YES:
        return true;
    case QtPermission::ASK:
        Q_ASSERT_X(false,
                   "hasConsumerPermission",
                   "QtPermission.ASK user dialog not yet implemented.");
{'fraction_non_alphanumeric': 0.09968646997347054, 'fraction_numerical': 0.0030549079507999036, 'mean_word_length': 3.194200944032367, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2557896', 'n_tokens_mistral': 3154, 'n_tokens_neox': 3065, 'n_words': 684}