#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
#
# derniere_connexion.py
# -----------------
#
# Copyright (C) 2013-2015 Raphaël-David Lasseri <lasseri@crans.org>,
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file 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 General Public License for more details.
#
# 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., 59 Temple Street #330, Boston, MA 02111-1307, USA.

import re
import sys
import os
import datetime
from time import mktime
from time import strptime
from lc_ldap import shortcuts

# Requete ldap pour récupérer tout les adhérents en mode read-write
db = shortcuts.lc_ldap_admin()

# Expression régulière sur les logs de connexion pour l'intranet et pour le CAS
# Pour le CAS on prends comme entrée cat ~/cas.log | grep -B 2 -A 2 "ACTION: AUTHENTICATION_SUCCESS"| grep 'WHEN\|WHO'|sed 'N;s/\n/ /'
COMPILE_REGEX = lambda x:re.compile(x)
COMPILED_REGEX = map(COMPILE_REGEX, [
                  r'^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}).*(?:'r'dovecot.*Login: user=<|'r'sshd.*Accepted.*for 'r')([^ >]+).*$',
                  r'^(.*) LOGIN INFO User logged in : (.*)',
                  r'WHO: \[username: (.*)\] WHEN: (.*) (?:CEST|CET) (.*)',
                 ])


def parse_logs(logfile):
    """ 
    Parse les logs sur l'entrée standard et rempli un dictionnaire
    ayant pour clef l'uid de l adherent

    """
    parsed_log = {}
    for line in logfile:
        m0 = COMPILED_REGEX[0].match(line)
        m1 = COMPILED_REGEX[1].match(line)
        m2 = COMPILED_REGEX[2].match(line)
        if m0:
            parsed_log[m0.group(2)]=int(mktime(strptime(m0.group(1),"%Y-%m-%dT%H:%M:%S")))
        if m1:
            parsed_log[m1.group(2)]=int(mktime(strptime(m1.group(1),"%d/%b/%Y:%H:%M:%S")))
        if m2:
            parsed_log[m2.group(1)]=int(mktime(strptime(m2.group(2)+m2.group(3),"%a %b %d %H:%M:%S%Y")))
    return parsed_log        


def update_connexion(dico):
    """ 
    Fonction qui met a jour la base ldap.
    Si la date présente dans ldap est inférieure à celle des logs
    parsés sur le serveur ou ce script est executé on met à jour 
    l'attribut avec la nouvelle valeur
    """
    for adh in db.search(u'(&(uid=*)(aid=*))',mode='rw',sizelimit=60000):
        with adh:
            uid = adh.get(u'uid',None)[0].value
            last_connexion = adh.get(u'derniereConnexion',None)
            if uid in dico:
                date_log_int = dico[u'%s'%uid]
                date_log=datetime.datetime.fromtimestamp(date_log_int)
                if last_connexion:
                    date_ldap=datetime.datetime.fromtimestamp(last_connexion[0].value)
                    if date_log > date_ldap:
                        last_connexion.pop()
                        last_connexion.append(date_log_int)    
                else: last_connexion.append(date_log_int)
                try:
                    adh.save()
                except EnvironmentError as err:
                    print "Cannot update %r. EnvironmentError(%r)" % (adh, err)
                    print "Maybe you should fix your damn cron ?"



if __name__ == "__main__":
    parsed_log=parse_logs(sys.stdin)
    update_connexion(parsed_log)



