from django.contrib.auth.models import SiteProfileNotAvailable
from authentic2.authsaml2.models import SAML2TransientUser
import subprocess
import syslog

#
# Django auth backend
#

class PfBackend:
    def authenticate(self, username=None, password=None):
        pfuser, privileges = pf_authenticate_user(username, password)
        if not pfuser:
            syslog.openlog("idpauth", syslog.LOG_PID)
            # FIXME: add details:
            # does not exists, bad password, expired account... ?
            syslog.syslog(syslog.LOG_LOCAL4 | syslog.LOG_INFO ,
                "FAIL: bad user/pass for %s" % username)
            return None
        if not 'univnautes-idp' in privileges:
            syslog.openlog("idpauth", syslog.LOG_PID)
            syslog.syslog(syslog.LOG_LOCAL4 | syslog.LOG_INFO ,
                "FAIL: user %s do not have IdP privilege" % username)
            return None
        return TransientUser(pfuser, privileges)

    def get_user(self, user_id=None):
        pfuser, privileges = pf_get_user(user_id)
        if not pfuser or not 'univnautes-idp' in privileges:
            return None
        return TransientUser(pfuser, privileges)


class TransientUser(SAML2TransientUser):
    '''mimics a django user'''

    is_active = True
    is_staff = False
    univnautes_privilegess = tuple()

    def __init__(self, pfuser, privileges):
        self.id = pfuser['username']
        self.displayname = pfuser['displayname'].decode('latin1')
        self.univnautes_privileges = privileges
        if privileges and 'univnautes-idp-admin' in privileges:
            self.is_staff = True

    def __unicode__(self):
        return u'%s (%s)' % (self.displayname, self.username)

    def get_profile(self):
        raise SiteProfileNotAvailable

    def get_username(self):
        return self.id
    username = property(get_username)

#
# get user from pfSense, via PHP script ../univnautes/bin/pf_auth
#

def pf_authenticate_user(username, password):
    params = ['username=%s' % username, 'password=%s' % password]
    return pf_auth(params)

def pf_get_user(username):
    params = ['username=%s' % username]
    return pf_auth(params)

def pf_auth(params):
    cmd = ['/usr/local/univnautes/bin/pf_auth', ] + params
    try:
        p = subprocess.Popen(cmd, close_fds=True,
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)
    except OSError, e:
        syslog.openlog("idpauth", syslog.LOG_PID)
        syslog.syslog(syslog.LOG_LOCAL4 | syslog.LOG_INFO , "ERROR: OSError %s" % e)
        return None, None
    stdout, stderr = p.communicate()
    if p.returncode != 0:
        return None, None
    user, privileges = eval(stdout)
    return user, privileges

