/*
 * 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.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/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 "qobject/qjson.h"
#include "qobject/qobject.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, "File '%s' must contain a JSON object",
                   fauthz->filename);
        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;

    if (!fauthz->filename) {
        error_setg(errp, "filename not provided");
        return;
    }

    fauthz->list = qauthz_list_file_load(fauthz, errp);
    if (!fauthz->list) {
        return;
    }

    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);
    object_class_property_add_bool(oc, "refresh",
                                   qauthz_list_file_prop_get_refresh,
                                   qauthz_list_file_prop_set_refresh);

    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_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);
