"""
Authorization module that allow users listed in
/etc/cobbler/users.conf to be permitted to access resources, with
the further restriction that cobbler objects can be edited to only
allow certain users/groups to access those specific objects.

Copyright 2008, Liquidnet Holdings, Inc
Joseph Boyer Jr.<jboyer@liquidnet.com>

Base on the code written by: 
Copyright 2008, Red Hat, Inc
Michael DeHaan <mdehaan@redhat.com>

This software may be freely redistributed under the terms of the GNU
general public license.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
"""

import distutils.sysconfig
import ConfigParser
import sys
import os
from cobbler.utils import _

plib = distutils.sysconfig.get_python_lib()
mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)

import cexceptions
import utils

CONFIG_FILE='/etc/cobbler/users.conf'

def register():
    """
    The mandatory cobbler module registration hook.
    """
    return "authz"

def __parse_config():
    if not os.path.exists(CONFIG_FILE):
        raise CX(_("ERROR: missing /etc/cobbler/users.conf"))
    config = ConfigParser.ConfigParser()
    config.optionxform=str
    config.read(CONFIG_FILE)
    alldata = {}
    sections = config.sections()
    for g in sections:
       alldata[str(g)] = {}
       opts = config.options(g)
       for o in opts:
           alldata[g][o] = 1
    return alldata 

def __is_user_allowed(obj, user, user_groups):
    if obj.owners == []:
        # no ownership restrictions, cleared
        return 1
    for allowed in obj.owners:
        if user == allowed:
           # user match
           return 1
        # else look for a group match
        for group in user_groups:
           if group == allowed and user in user_groups[group]:
              return 1
    return 0

def authorize(api_handle,user,resource,arg1=None,arg2=None):
    """
    Validate a user against a resource.
    All users in the file are permitted by this module.
    """

    # Group Def for System/Sync only access /etc/cobbler/users.conf
    s_access = "Stagers"

    # everybody can get read-only access to everything
    # if they pass authorization, they don't have to be in users.conf
    if resource is not None:
       for x in [ "get", "read", "/cobbler/web" ]:
          if resource.startswith(x):
             return 1

    user_groups = __parse_config()

    # classify the type of operation
    modify_operation = False
    for criteria in ["save","remove","modify","write","edit"]:
        if resource.find(criteria) != -1:
           modify_operation = True

    ###########################################################################
    ## Allow admins access to everything. 
    ## Only allow Grp Def: s_access to added Systems and Sync
    ## Everyone else has read-only access to list and denied access to add
    ###########################################################################
    found_user = False
    for g in user_groups:
        for x in user_groups[g]:
           if x == user:
               found_user = True
               if g == "admins" or g == "admin":
                   return 1
               elif resource.find("system") != -1 and g == s_access:
                 return 1
               elif resource.find("sync") != -1 and g == s_access:
                 return 1
    return 0
