/*
 * QEMU access control list authorization driver
 *
 * Copyright (c) 2018 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "authz/list.h"
#include "trace.h"
#include "qom/object_interfaces.h"
#include "qapi/qapi-visit-authz.h"

static bool qauthz_list_is_allowed(QAuthZ *authz,
                                   const char *identity,
                                   Error **errp)
{
    QAuthZList *lauthz = QAUTHZ_LIST(authz);
    QAuthZListRuleList *rules = lauthz->rules;

    while (rules) {
        QAuthZListRule *rule = rules->value;
        QAuthZListFormat format = rule->has_format ? rule->format :
            QAUTHZ_LIST_FORMAT_EXACT;

        trace_qauthz_list_check_rule(authz, rule->match, identity,
                                     format, rule->policy);
        switch (format) {
        case QAUTHZ_LIST_FORMAT_EXACT:
            if (g_str_equal(rule->match, identity)) {
                return rule->policy == QAUTHZ_LIST_POLICY_ALLOW;
            }
            break;
        case QAUTHZ_LIST_FORMAT_GLOB:
            if (g_pattern_match_simple(rule->match, identity)) {
                return rule->policy == QAUTHZ_LIST_POLICY_ALLOW;
            }
            break;
        default:
            g_warn_if_reached();
            return false;
        }
        rules = rules->next;
    }

    trace_qauthz_list_default_policy(authz, identity, lauthz->policy);
    return lauthz->policy == QAUTHZ_LIST_POLICY_ALLOW;
}


static void
qauthz_list_prop_set_policy(Object *obj,
                            int value,
                            Error **errp G_GNUC_UNUSED)
{
    QAuthZList *lauthz = QAUTHZ_LIST(obj);

    lauthz->policy = value;
}


static int
qauthz_list_prop_get_policy(Object *obj,
                            Error **errp G_GNUC_UNUSED)
{
    QAuthZList *lauthz = QAUTHZ_LIST(obj);

    return lauthz->policy;
}


static void
qauthz_list_prop_get_rules(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
{
    QAuthZList *lauthz = QAUTHZ_LIST(obj);

    visit_type_QAuthZListRuleList(v, name, &lauthz->rules, errp);
}

static void
qauthz_list_prop_set_rules(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
{
    QAuthZList *lauthz = QAUTHZ_LIST(obj);
    QAuthZListRuleList *oldrules;

    oldrules = lauthz->rules;
    visit_type_QAuthZListRuleList(v, name, &lauthz->rules, errp);

    qapi_free_QAuthZListRuleList(oldrules);
}


static void
qauthz_list_finalize(Object *obj)
{
    QAuthZList *lauthz = QAUTHZ_LIST(obj);

    qapi_free_QAuthZListRuleList(lauthz->rules);
}


static void
qauthz_list_class_init(ObjectClass *oc, void *data)
{
    QAuthZClass *authz = QAUTHZ_CLASS(oc);

    object_class_property_add_enum(oc, "policy",
                                   "QAuthZListPolicy",
                                   &QAuthZListPolicy_lookup,
                                   qauthz_list_prop_get_policy,
                                   qauthz_list_prop_set_policy,
                                   NULL);

    object_class_property_add(oc, "rules", "QAuthZListRule",
                              qauthz_list_prop_get_rules,
                              qauthz_list_prop_set_rules,
                              NULL, NULL, NULL);

    authz->is_allowed = qauthz_list_is_allowed;
}


QAuthZList *qauthz_list_new(const char *id,
                            QAuthZListPolicy policy,
                            Error **errp)
{
    return QAUTHZ_LIST(
        object_new_with_props(TYPE_QAUTHZ_LIST,
                              object_get_objects_root(),
                              id, errp,
                              "policy", QAuthZListPolicy_str(policy),
                              NULL));
}

ssize_t qauthz_list_append_rule(QAuthZList *auth,
                                const char *match,
                                QAuthZListPolicy policy,
                                QAuthZListFormat format,
                                Error **errp)
{
    QAuthZListRule *rule;
    QAuthZListRuleList *rules, *tmp;
    size_t i = 0;

    rule = g_new0(QAuthZListRule, 1);
    rule->policy = policy;
    rule->match = g_strdup(match);
    rule->format = format;
    rule->has_format = true;

    tmp = g_new0(QAuthZListRuleList, 1);
    tmp->value = rule;

    rules = auth->rules;
    if (rules) {
        while (rules->next) {
            i++;
            rules = rules->next;
        }
        rules->next = tmp;
        return i + 1;
    } else {
        auth->rules = tmp;
        return 0;
    }
}


ssize_t qauthz_list_insert_rule(QAuthZList *auth,
                                const char *match,
                                QAuthZListPolicy policy,
                                QAuthZListFormat format,
                                size_t index,
                                Error **errp)
{
    QAuthZListRule *rule;
    QAuthZListRuleList *rules, *tmp;
    size_t i = 0;

    rule = g_new0(QAuthZListRule, 1);
    rule->policy = policy;
    rule->match = g_strdup(match);
    rule->format = format;
    rule->has_format = true;

    tmp = g_new0(QAuthZListRuleList, 1);
    tmp->value = rule;

    rules = auth->rules;
    if (rules && index > 0) {
        while (rules->next && i < (index - 1)) {
            i++;
            rules = rules->next;
        }
        tmp->next = rules->next;
        rules->next = tmp;
        return i + 1;
    } else {
        tmp->next = auth->rules;
        auth->rules = tmp;
        return 0;
    }
}


ssize_t qauthz_list_delete_rule(QAuthZList *auth, const char *match)
{
    QAuthZListRule *rule;
    QAuthZListRuleList *rules, *prev;
    size_t i = 0;

    prev = NULL;
    rules = auth->rules;
    while (rules) {
        rule = rules->value;
        if (g_str_equal(rule->match, match)) {
            if (prev) {
                prev->next = rules->next;
            } else {
                auth->rules = rules->next;
            }
            rules->next = NULL;
            qapi_free_QAuthZListRuleList(rules);
            return i;
        }
        prev = rules;
        rules = rules->next;
        i++;
    }

    return -1;
}


static const TypeInfo qauthz_list_info = {
    .parent = TYPE_QAUTHZ,
    .name = TYPE_QAUTHZ_LIST,
    .instance_size = sizeof(QAuthZList),
    .instance_finalize = qauthz_list_finalize,
    .class_size = sizeof(QAuthZListClass),
    .class_init = qauthz_list_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};


static void
qauthz_list_register_types(void)
{
    type_register_static(&qauthz_list_info);
}


type_init(qauthz_list_register_types);
