bool Permissions::check_remote_datareader(
        const PermissionsHandle& remote_handle,
        const uint32_t domain_id,
        const ReaderProxyData& subscription_data,
        bool& relay_only,
        SecurityException& exception)
{
    bool returned_value = false;
    const AccessPermissionsHandle& rah = AccessPermissionsHandle::narrow(remote_handle);
    const char* topic_name = subscription_data.topicName().c_str();

    relay_only = false;

    if (rah.nil())
    {
        exception = _SecurityException_("Bad precondition");
        EMERGENCY_SECURITY_LOGGING("Permissions", exception.what());
        return false;
    }

    const EndpointSecurityAttributes* attributes = nullptr;

    if ((attributes = is_topic_in_sec_attributes(topic_name, rah->governance_topic_rules_))
            != nullptr)
    {
        if (!attributes->is_read_protected)
        {
            return true;
        }
    }
    else
    {
        exception = _SecurityException_(
            "Not found topic access rule for topic " + subscription_data.topicName().to_string());
        EMERGENCY_SECURITY_LOGGING("Permissions", exception.what());
        return false;
    }

    for (auto rule : rah->grant.rules)
    {
        if (is_domain_in_set(domain_id, rule.domains))
        {
            const std::vector<std::string>& partitions = subscription_data.m_qos.m_partition.getNames();
            if (is_topic_in_criterias(topic_name, rule.subscribes))
            {
                returned_value = check_rule(topic_name, rule, partitions, rule.subscribes, exception);
                break;
            }

            if (is_topic_in_criterias(topic_name, rule.relays))
            {
                returned_value = check_rule(topic_name, rule, partitions, rule.relays, exception);
                if (returned_value)
                {
                    relay_only = true;
                }

                break;
            }
        }
    }

    if (!returned_value)
    {
        if (strlen(exception.what()) == 0)
        {
            exception = _SecurityException_(topic_name + std::string(" topic not found in allow rule."));
        }
        EMERGENCY_SECURITY_LOGGING("Permissions", exception.what());
    }

    return returned_value;
}
bool Permissions::check_remote_datareader(
        const PermissionsHandle& remote_handle,
        const uint32_t domain_id,
        const ReaderProxyData& subscription_data,
        bool& relay_only,
        SecurityException& exception)
{
    bool returned_value = false;
    const AccessPermissionsHandle& rah = AccessPermissionsHandle::narrow(remote_handle);
    const char* topic_name = subscription_data.topicName().c_str();

    relay_only = false;

    if (rah.nil())
    {
        exception = _SecurityException_("Bad precondition");
        EMERGENCY_SECURITY_LOGGING("Permissions", exception.what());
        return false;
    }

    const EndpointSecurityAttributes* attributes = nullptr;

    if ((attributes = is_topic_in_sec_attributes(topic_name, rah->governance_topic_rules_))
            != nullptr)
    {
        if (!attributes->is_read_protected)
        {
            return true;
        }
    }
    else
    {
        exception = _SecurityException_(
            "Not found topic access rule for topic " + subscription_data.topicName().to_string());
        EMERGENCY_SECURITY_LOGGING("Permissions", exception.what());
        return false;
    }

    for (auto rule : rah->grant.rules)
    {
        if (is_domain_in_set(domain_id, rule.domains))
        {
            const std::vector<std::string>& partitions = subscription_data.m_qos.m_partition.getNames();
            if (is_topic_in_criterias(topic_name, rule.subscribes))
            {
                returned_value = check_rule(topic_name, rule, partitions, rule.subscribes, exception);
                break;
            }

            if (is_topic_in_criterias(topic_name, rule.relays))
            {
                returned_value = check_rule(topic_name, rule, partitions, rule.relays, exception);
                if (returned_value)
                {
                    relay_only = true;
                }

                break;
            }
        }
    }

    if (!returned_value)
    {
        if (strlen(exception.what()) == 0)
        {
            exception = _SecurityException_(topic_name + std::string(" topic not found in allow rule."));
        }
        EMERGENCY_SECURITY_LOGGING("Permissions", exception.what());
    }

    return returned_value;
}