/*
 * QEMU simple 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.1 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/simple.h"
#include "trace.h"
#include "qemu/module.h"
#include "qom/object_interfaces.h"

static bool qauthz_simple_is_allowed(QAuthZ *authz,
                                     const char *identity,
                                     Error **errp)
{
    QAuthZSimple *sauthz = QAUTHZ_SIMPLE(authz);

    trace_qauthz_simple_is_allowed(authz, sauthz->identity, identity);
    return g_str_equal(identity, sauthz->identity);
}

static void
qauthz_simple_prop_set_identity(Object *obj,
                                const char *value,
                                Error **errp G_GNUC_UNUSED)
{
    QAuthZSimple *sauthz = QAUTHZ_SIMPLE(obj);

    g_free(sauthz->identity);
    sauthz->identity = g_strdup(value);
}


static char *
qauthz_simple_prop_get_identity(Object *obj,
                                Error **errp G_GNUC_UNUSED)
{
    QAuthZSimple *sauthz = QAUTHZ_SIMPLE(obj);

    return g_strdup(sauthz->identity);
}


static void
qauthz_simple_finalize(Object *obj)
{
    QAuthZSimple *sauthz = QAUTHZ_SIMPLE(obj);

    g_free(sauthz->identity);
}


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

    authz->is_allowed = qauthz_simple_is_allowed;

    object_class_property_add_str(oc, "identity",
                                  qauthz_simple_prop_get_identity,
                                  qauthz_simple_prop_set_identity);
}


QAuthZSimple *qauthz_simple_new(const char *id,
                                const char *identity,
                                Error **errp)
{
    return QAUTHZ_SIMPLE(
        object_new_with_props(TYPE_QAUTHZ_SIMPLE,
                              object_get_objects_root(),
                              id, errp,
                              "identity", identity,
                              NULL));
}


static const TypeInfo qauthz_simple_info = {
    .parent = TYPE_QAUTHZ,
    .name = TYPE_QAUTHZ_SIMPLE,
    .instance_size = sizeof(QAuthZSimple),
    .instance_finalize = qauthz_simple_finalize,
    .class_init = qauthz_simple_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};


static void
qauthz_simple_register_types(void)
{
    type_register_static(&qauthz_simple_info);
}


type_init(qauthz_simple_register_types);
