/*
    GDAM - Geoff & Dave's Audio Mixer
    Copyright (C) 1999    Dave Benson, Geoff Matters.

    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, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA

    Contact:
        daveb@ffem.org <Dave Benson>
        geoff@ugcs.caltech.edu <Geoff Matters>
*/
#ifndef __GDAM_ACL_H_
#define __GDAM_ACL_H_

#include "gdampermissions.h"
#include <glib.h>
typedef struct _GdamAclRule GdamAclRule;
typedef struct _GdamAcl GdamAcl;

/*
 * ACL stands for `Access Control List'.
 *
 * It refers to an authority model that scans a list
 * of rules for how to grant access until the first one matches.
 * The rule is evaluated to determine whether access is granted or
 * denied.
 */

/*=====================================================================*
 *                             GdamAclRule                             *
 *                                                                     *
 * A single grant/deny/ignore rule.                                    *
 *=====================================================================*/
struct _GdamAclRule {
	/* Returns:
	 *     -1      if the user is forbidden by this rule.
	 *      0      if the user is not affected by this rule.
	 *     +1      if the user is granted permission by this rule.
	 */
        int (*check_permissions)(GdamPermissions  *permissions,
	                         gpointer          acl_data);
	
	void (*destroy_acl_data)(gpointer          acl_data);

	gpointer                 acl_data;
};

GdamAclRule*       gdam_acl_rule_deny_user(int uid);
GdamAclRule*       gdam_acl_rule_grant_user(int uid);

struct _GdamAcl {
	/* If no rules match, should we grant or deny permission. */
	unsigned		default_grant : 1;

	GSList*			first_rule;
	GSList*			last_rule;
};

GdamAcl           *gdam_acl_new              (gboolean         default_grant);
gboolean           gdam_acl_is_granted       (GdamAcl         *acl,
                                              GdamPermissions* user_perms);
/* Insert a rule so it is the first checked. */
void               gdam_acl_prepend_rule     (GdamAcl         *acl,
                                              GdamAclRule     *acl_rule);

/* Insert a rule so it is the last checked. */
void               gdam_acl_append_rule      (GdamAcl         *acl,
                                              GdamAclRule     *acl_rule);

void               gdam_acl_destroy          (GdamAcl         *to_kill);

#endif
