#!/usr/bin/python
#
# LEG20112005
#
# au_au -> wn,pwd -> login valid/invalid, auth_error
# au_w2u -> Wikiname -> uid

import PAM
from pwd import getpwall

global password, username
password = ""

def au_pam_conv(auth, query_list, userData):
    global password, username
    resp = []

    for i in range(len(query_list)):
        query, type = query_list[i]
        if type == PAM.PAM_PROMPT_ECHO_ON:
            resp.append((username, 0))
        elif type == PAM.PAM_PROMPT_ECHO_OFF:
            resp.append((password, 0))
        elif type == PAM.PAM_PROMPT_ERROR_MSG or type == PAM.PAM_PROMPT_TEXT_INFO:
            resp.append(('', 0))
        else:
            return None
            
    return resp

 
def au_imap_au(uid, pwd):
    '''uid .. userid of the user in the underlying auth-mechanism
       pwd .. password.
       Returns:
           False .. authentication failed
           True  .. secrets are valid
    '''
    import imaplib
    try:
        I = imaplib.IMAP4_SSL('imap.magma.com.ni')
        try:
            response = I.login(uid, pwd)[0] == 'OK'
            I.logout()
            return response
        except I.IMAP4.error, e:
            # print e
            # handle error however you like
            I.logout()
            return False
    except:
        # Quit silently on any catastrofee
        return False

def au_pam_au(uid, pwd):
    '''uid .. userid of the user in the underlying auth-mechanism
       pwd .. password.
       Returns:
           False .. no user found
           False .. authentication mechanism returned error
           False .. authentication failed
           True  .. secrets are valid
    '''
    global password, username

    auth = PAM.pam()
    auth.start('other')
    auth.set_item(PAM.PAM_CONV, au_pam_conv)
    
    auth.set_item(PAM.PAM_USER, uid)

    username = uid
    password = pwd

    auth.authenticate()


def au_getpw_w2u(wikiuser):
    '''convert a Wiki Username into the corresponding unix user id.
       Esentially we look up "Wiki User" in the gecos field.
       This will be very slow, if the unix database is large, since
       the gecos field ist not directly searchable.
    '''

    # guess full common name from wikiname
    # eg. "AndrewBaumann" -> "Andrew Baumann"
    cut = 0
    for c in range(1, len(wikiuser)):
        if wikiuser[c].isupper():
            cut = c
    wiki_user = wikiuser[:cut] + " " + wikiuser[cut:]

    users = getpwall()
    for i in range(len(users)):
        pwentry = users[i]
        gecos = pwentry[4]
        if wiki_user == gecos.split(',')[0]:
	    return pwentry[0]
    return ""

def au_au(wikiuser, pwd):
    return au_imap_au(au_getpw_w2u(wikiuser), pwd)
