'''Radius server support

Copyright 2006 AG Projects
'''

__all__ = ['RadiusClient', 'TimeoutError', 'PacketError', 'ParseError',
           'RadiusAttributeError', 'RadiusValueError']

import struct
import pyrad.client
import pyrad.dictionary
from configuration import readSettings, ConfigSection
from datatypes import StringList
from utilities import abort


class RadiusConfig(ConfigSection):
    _dataTypes = {'dictionaries': StringList}
    secret = ''
    server = 'localhost'
    authport = 1812
    acctport = 1813
    dictionaries = []
    retries = 2
    timeout = 3

## We use this to overwrite some of the settings above on a local basis if needed
readSettings('Radius', RadiusConfig)

## Exceptions

TimeoutError = pyrad.client.Timeout
ParseError = pyrad.dictionary.ParseError
from pyrad.packet import PacketError

class RadiusAttributeError(AttributeError): pass
class RadiusValueError(ValueError): pass

## Classes

class RadiusClient(pyrad.client.Client):
    def __init__(self):
        server = RadiusConfig.server
        authport = RadiusConfig.authport
        acctport = RadiusConfig.acctport
        secret = RadiusConfig.secret
        try:
            raddict = pyrad.dictionary.Dictionary(*RadiusConfig.dictionaries)
        except Exception, e:
            abort("cannot read radius dictionaries: %s" % str(e))
        pyrad.client.Client.__init__(self, server, authport, acctport, secret, raddict)
        self.retries = RadiusConfig.retries
        self.timeout = RadiusConfig.timeout

    def do_accounting(self, **attrs):
        try:
            p = self.CreateAcctPacket(**attrs)
        except KeyError, why:
            raise RadiusAttributeError, why
        except struct.error, why:
            raise RadiusValueError, why
        return self.SendPacket(p)

