/*
 * QEMU authorization framework base class
 *
 * 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/base.h"
#include "authz/trace.h"

bool qauthz_is_allowed(QAuthZ *authz,
                       const char *identity,
                       Error **errp)
{
    QAuthZClass *cls = QAUTHZ_GET_CLASS(authz);
    bool allowed;

    allowed = cls->is_allowed(authz, identity, errp);
    trace_qauthz_is_allowed(authz, identity, allowed);

    return allowed;
}


bool qauthz_is_allowed_by_id(const char *authzid,
                             const char *identity,
                             Error **errp)
{
    QAuthZ *authz;
    Object *obj;
    Object *container;

    container = object_get_objects_root();
    obj = object_resolve_path_component(container,
                                        authzid);
    if (!obj) {
        error_setg(errp, "Cannot find QAuthZ object ID %s",
                   authzid);
        return false;
    }

    if (!object_dynamic_cast(obj, TYPE_QAUTHZ)) {
        error_setg(errp, "Object '%s' is not a QAuthZ subclass",
                   authzid);
        return false;
    }

    authz = QAUTHZ(obj);

    return qauthz_is_allowed(authz, identity, errp);
}


static const TypeInfo authz_info = {
    .parent = TYPE_OBJECT,
    .name = TYPE_QAUTHZ,
    .instance_size = sizeof(QAuthZ),
    .class_size = sizeof(QAuthZClass),
    .abstract = true,
};

static void qauthz_register_types(void)
{
    type_register_static(&authz_info);
}

type_init(qauthz_register_types)

