/*
 * QEMU access control list file 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/listfile.h"
#include "trace.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/sockets.h"
#include "qemu/filemonitor.h"
#include "qom/object_interfaces.h"
#include "qapi/qapi-visit-authz.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qobject-input-visitor.h"


static bool
qauthz_list_file_is_allowed(QAuthZ *authz,
                            const char *identity,
                            Error **errp)
{
    QAuthZListFile *fauthz = QAUTHZ_LIST_FILE(authz);
    if (fauthz->list) {
        return qauthz_is_allowed(fauthz->list, identity, errp);
    }

    return false;
}


static QAuthZ *
qauthz_list_file_load(QAuthZListFile *fauthz, Error **errp)
{
    GError *err = NULL;
    gchar *content = NULL;
    gsize len;
    QObject *obj = NULL;
    QDict *pdict;
    Visitor *v = NULL;
    QAuthZ *ret = NULL;

    trace_qauthz_list_file_load(fauthz, fauthz->filename);
    if (!g_file_get_contents(fauthz->filename, &content, &len, &err)) {
        error_setg(errp, "Unable to read '%s': %s",
                   fauthz->filename, err->message);
        goto cleanup;
    }

    obj = qobject_from_json(content, errp);
    if (!obj) {
        goto cleanup;
    }

    pdict = qobject_to(QDict, obj);
    if (!pdict) {
        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "obj", "dict");
        goto cleanup;
    }

    v = qobject_input_visitor_new(obj);

    ret = (QAuthZ *)user_creatable_add_type(TYPE_QAUTHZ_LIST,
                                            NULL, pdict, v, errp);

 cleanup:
    visit_free(v);
    qobject_unref(obj);
    if (err) {
        g_error_free(err);
    }
    g_free(content);
    return ret;
}


static void
qauthz_list_file_event(int64_t wd G_GNUC_UNUSED,
                       QFileMonitorEvent ev G_GNUC_UNUSED,
                       const char *name G_GNUC_UNUSED,
                       void *opaque)
{
    QAuthZListFile *fauthz = opaque;
    Error *err = NULL;

    if (ev != QFILE_MONITOR_EVENT_MODIFIED &&
        ev != QFILE_MONITOR_EVENT_CREATED) {
        return;
    }

    object_unref(OBJECT(fauthz->list));
    fauthz->list = qauthz_list_file_load(fauthz, &err);
    trace_qauthz_list_file_refresh(fauthz,
                                   fauthz->filename, fauthz->list ? 1 : 0);
    if (!fauthz->list) {
        error_report_err(err);
    }
}

static void
qauthz_list_file_complete(UserCreatable *uc, Error **errp)
{
    QAuthZListFile *fauthz = QAUTHZ_LIST_FILE(uc);
    gchar *dir = NULL, *file = NULL;

    fauthz->list = qauthz_list_file_load(fauthz, errp);

    if (!fauthz->refresh) {
        return;
    }

    fauthz->file_monitor = qemu_file_monitor_new(errp);
    if (!fauthz->file_monitor) {
        return;
    }

    dir = g_path_get_dirname(fauthz->filename);
    if (g_str_equal(dir, ".")) {
        error_setg(errp, "Filename must be an absolute path");
        goto cleanup;
    }
    file = g_path_get_basename(fauthz->filename);
    if (g_str_equal(file, ".")) {
        error_setg(errp, "Path has no trailing filename component");
        goto cleanup;
    }

    fauthz->file_watch = qemu_file_monitor_add_watch(
        fauthz->file_monitor, dir, file,
        qauthz_list_file_event, fauthz, errp);
    if (fauthz->file_watch < 0) {
        goto cleanup;
    }

 cleanup:
    g_free(file);
    g_free(dir);
}


static void
qauthz_list_file_prop_set_filename(Object *obj,
                                   const char *value,
                                   Error **errp G_GNUC_UNUSED)
{
    QAuthZListFile *fauthz = QAUTHZ_LIST_FILE(obj);

    g_free(fauthz->filename);
    fauthz->filename = g_strdup(value);
}


static char *
qauthz_list_file_prop_get_filename(Object *obj,
                                   Error **errp G_GNUC_UNUSED)
{
    QAuthZListFile *fauthz = QAUTHZ_LIST_FILE(obj);

    return g_strdup(fauthz->filename);
}


static void
qauthz_list_file_prop_set_refresh(Object *obj,
                                  bool value,
                                  Error **errp G_GNUC_UNUSED)
{
    QAuthZListFile *fauthz = QAUTHZ_LIST_FILE(obj);

    fauthz->refresh = value;
}


static bool
qauthz_list_file_prop_get_refresh(Object *obj,
                                  Error **errp G_GNUC_UNUSED)
{
    QAuthZListFile *fauthz = QAUTHZ_LIST_FILE(obj);

    return fauthz->refresh;
}


static void
qauthz_list_file_finalize(Object *obj)
{
    QAuthZListFile *fauthz = QAUTHZ_LIST_FILE(obj);

    object_unref(OBJECT(fauthz->list));
    g_free(fauthz->filename);
    qemu_file_monitor_free(fauthz->file_monitor);
}


static void
qauthz_list_file_class_init(ObjectClass *oc, void *data)
{
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    QAuthZClass *authz = QAUTHZ_CLASS(oc);

    ucc->complete = qauthz_list_file_complete;

    object_class_property_add_str(oc, "filename",
                                  qauthz_list_file_prop_get_filename,
                                  qauthz_list_file_prop_set_filename,
                                  NULL);
    object_class_property_add_bool(oc, "refresh",
                                   qauthz_list_file_prop_get_refresh,
                                   qauthz_list_file_prop_set_refresh,
                                   NULL);

    authz->is_allowed = qauthz_list_file_is_allowed;
}


static void
qauthz_list_file_init(Object *obj)
{
    QAuthZListFile *authz = QAUTHZ_LIST_FILE(obj);

    authz->file_watch = -1;
#ifdef CONFIG_INOTIFY1
    authz->refresh = true;
#endif
}


QAuthZListFile *qauthz_list_file_new(const char *id,
                                     const char *filename,
                                     bool refresh,
                                     Error **errp)
{
    return QAUTHZ_LIST_FILE(
        object_new_with_props(TYPE_QAUTHZ_LIST_FILE,
                              object_get_objects_root(),
                              id, errp,
                              "filename", filename,
                              "refresh", refresh ? "yes" : "no",
                              NULL));
}


static const TypeInfo qauthz_list_file_info = {
    .parent = TYPE_QAUTHZ,
    .name = TYPE_QAUTHZ_LIST_FILE,
    .instance_init = qauthz_list_file_init,
    .instance_size = sizeof(QAuthZListFile),
    .instance_finalize = qauthz_list_file_finalize,
    .class_size = sizeof(QAuthZListFileClass),
    .class_init = qauthz_list_file_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};


static void
qauthz_list_file_register_types(void)
{
    type_register_static(&qauthz_list_file_info);
}


type_init(qauthz_list_file_register_types);
