#! /usr/bin/env python
# -*- coding: utf-8 -*-

# 10/06/2014: cleon :  création
# Script permettant de générer la configuration EoleSSO

import urllib
import json
import hashlib
import os
import time
import sys


force=False
if len(sys.argv)==2 and sys.argv[1]=="--force":
    force=True

SSO_APPS_DIR="/usr/share/sso/app_filters"
SSO_APPS_FILE=SSO_APPS_DIR + "/econnect_apps.ini"
SSO_CONF_MD5="/tmp/econnect.sso"
LOCK_FILE="/tmp/econnect.lock"

ECONNECT_TOKEN_FILE="/root/.econnect.token"
ECONNECT_URL_FILE="/root/.econnect.url"

# Existe t'il un token ?
if not os.path.isfile(ECONNECT_TOKEN_FILE):
    print "econnect token non trouvé"
    sys.exit(2)

# URL de API (web_url)
# URL est stocké dans un fichier, afin de faciliter la migration sur 2.4
# ceci evite de modifier ce code pour récupérer la variable
# web_url dans le dico et jongler entre 2.3 et 2.4
if not os.path.isfile(ECONNECT_URL_FILE):
    print "econnect url token non trouvé"
    sys.exit(2)

f=open(ECONNECT_URL_FILE,'r')
API_URL=f.read().strip()
f.close()

# Une seule instance doit fonctionner
if os.path.isfile(LOCK_FILE) and (time.time()-os.path.getmtime(LOCK_FILE))<120:
    print "lock existe %s (%i seconds)" % (LOCK_FILE,time.time()-os.path.getmtime(LOCK_FILE))
    sys.exit(1)

# lock file
if os.path.isfile(LOCK_FILE):
    print "lock existe %s >2mn, force unlock" % LOCK_FILE
    os.unlink(LOCK_FILE)
file(LOCK_FILE, 'w').write(str(os.getpid()))

# Récupération du token d'authentification
f=open(ECONNECT_TOKEN_FILE,'r')
token=f.read().strip()
f.close()

# Récupréation de la configuration via l'API
url="https://%s/econnect/api/ressources/sso?token=%s" % (API_URL,token)
try:
    filehandle = urllib.urlopen(url)
    content=filehandle.read()
    filehandle.close()
except Exception as inst:
    print "Une erreur est survenue lors de la récupération SSO url=%s" % url
    print inst
    os.unlink(LOCK_FILE)
    sys.exit(3)

# Avant d'aller plus loin, vérifions si le json est OK
try:
    decoded=json.loads(content)
    json.dumps(decoded, sort_keys=True, indent=4)
except Exception as inst:
    print "Une erreur est survenue lors de la récupération SSO"
    print content
    os.unlink(LOCK_FILE)
    sys.exit(3)

# On va vérifier si la conf à changé
lastmd5=""
newmd5=hashlib.md5(content).hexdigest()
if os.path.isfile(SSO_CONF_MD5):
    f=open(SSO_CONF_MD5,'r')
    lastmd5=f.read()
    f.close()

# non => on ne fait rien si pas en mode force
if newmd5==lastmd5 and not force:
    os.unlink(LOCK_FILE)
    sys.exit(0)

# oui => on va mettre à jour la conf sso

# Ecriture du md5
f=open(SSO_CONF_MD5,'w')
f.write(newmd5)
f.close

# Fichier de configuration sso : econnect_apps.ini
fapps=open(SSO_APPS_FILE,'w')

print "%s" % (time.strftime('%c'))
print "Generation de configuration SSO"
count=0

# Pour chaque appli, on va écrire un econnect_<app>.ini
for app in decoded:
    print " -> %s" % app["name"]
    count=count+1

    # Si anciens fichiers sso existent on supprime
    if app["name"] != "econnect":

        lastSSO=SSO_APPS_DIR+"/%s.ini" % app["name"]
        if  os.path.isfile( lastSSO ):
            os.remove(lastSSO)

        lastSSO=SSO_APPS_DIR+"/%s_apps.ini" % app["name"]
        if  os.path.isfile( lastSSO ):
            os.remove(lastSSO)

    # ecriture du filtre
    fapps.write("[%s]\nbaseurl=%s\nscheme=%s\naddr=%s\ntypeaddr=%s\nfilter=econnect_%s\n\n" % (app["name"],app["baseurl"],app["scheme"],app["addr"],app["typeaddr"],app["name"] ) )
    ffilter=open(SSO_APPS_DIR+"/econnect_%s.ini" % app["name"], 'w' )
    ffilter.write(("%s\n" % app["filter"]).encode("UTF-8"))
    ffilter.close()

if count==0:
    print " -> Aucune ressource SSO activée ou configurée"


fapps.close()
os.unlink(LOCK_FILE)

print os.popen("/etc/init.d/eole-sso reload").read()
