/*
 * 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"
#include "qemu/module.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);
