# -*- coding: utf-8 -*-
###########################################################################
# Eole NG - 2007
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  cf /root/LicenceEole.txt
# eole@ac-dijon.fr
#
# config.py
#
# fichier de configuration pour la librairie SSO Eole
#
###########################################################################

import locale, os, socket

SSO_PATH = os.path.dirname(__file__)

# REGLAGES DE LOCALE
# encoding = locale.getpreferredencoding() -> ne fonctionne pas toujours si le service est démarré au boot
encoding = 'UTF-8'
LC_ALL = 'fr_FR.UTF-8'

# VARIABLES A RENSEIGNER SI CREOLE NON DISPONIBLE
##################################################

# adresse réseau du serveur (ne pas utiliser localhost ou 127.0.0.1)
SERVER_IP_ADDR = ""
AUTH_SERVER_ADDR = ""
# adresse/port du serveur ldap utilisé pour l'authentification
# si non renseigné, utilisation de SERVER_IP_ADDR
LDAP_SERVER = [""]
LDAP_PORT = [389]
LDAP_BASE = ["o=gouv,c=fr"]
LDAP_READER = [""]
LDAP_MATCH_ATTRIBUTE = ["uid"]
LDAP_LABEL = ["Annuaire SSO"]
LDAP_INFOS = [""]
LDAP_LOGIN_OTP = ["inactifs"]
LDAP_READER_PASSFILE = [""]
# port de la page web d'authentification
EOLESSO_PORT = '8443'
# version du protocole CAS (1 ou 2)
CAS_VERSION = 2
# URL du serveur parent si déclaré
PARENT_URL = ''
# Nom d'entité du serveur pour le protocole SAMLv2 (calculé automatiquement si chaine vide)
IDP_IDENTITY = ""
# CERTIFICAT DU SERVEUR
CERTFILE = "/etc/ssl/certs/eole.crt"
KEYFILE = "/etc/ssl/certs/eole.key"
# certificat de l'autorité de certification (pour validation des clients en mode proxy)
# si valeur vide : utilisation de ca.crt dans le même répertoire que CERTFILE
CA_LOCATION = ""
# CSS de la page de login (fichier utilisé : /usr/share/sso/interface/<nom_css>.css)
# Autre possibilité : héritage automatique ajouter theme.css
# dans /usr/share/sso/interface/theme/style/
DEFAULT_CSS = "main"
RESPONSIVE = False
# Informations sur l'emplacement du serveur (éducation nationale)
RNE = ""
ETABLISSEMENT = ""
ACADEMIE = ""
# Gestion des proxys http pour l'envoi de certaines requêtes
# (mode CAS : déconnexion / envoi de PGT)
PROXY_SERVER = ""
PROXY_PORT = ""

# Gestion de l'avertissement internet explorer
ACTIVER_ENVOLE = False
ACTIVER_ENVOLE_INFOS = False
POSH_URL = ''

#CONSTANTES
############

# DUREE de validité d'une assertion SAML
STATEMENT_TIMEOUT = 600
# décalage autorisé pour la vérification des dates des messages SAML
TIME_ADJUST = -300

# définition du délai de timeout par défaut des connexions (en secondes)
SOCK_TIMEOUT = 5.0
# durée de vie d'un login ticket : 2 heures
SESSION_TIMER = 2 * 60 * 60
# durée de vie d'un ticket d'application : 5 minutes (utilisable une seule fois)
APP_TIMER = 300
# durée de vie d'un nombre magique permettant la communication entre un frontend et un backend
# ce timeout est reinitialise a chaque fois qu'une action est lancée
MAGIC_NUMBER_TIMEOUT =  60 * 5
# durée de vie des sessions expirées. Quand une session expire, on la garde dans un cache pour savoir
# si quand une session est non valide, si elle avait expirée ou si elle n'a jamais existée
EXPIRED_SESSION_TIMEOUT = 60 * 60 * 2
# active ou non l'envoi de requêtes de logout pour les clients CAS
SEND_CAS_LOGOUT = False
# active ou non la vérfication des urls d'application
# (si True, on ne répond pas à une application non référencée dans app_filters)
VERIFY_APP = False
# indique si un formulaire doit être affiché lors de l'envoi d'une demande de fédération
DISPLAY_FEDERATION = True
# Taille du pool de thread
THREAD_POOL_SIZE = 100
# attributs utilisateurs à ne pas conserver
IGNORED_ATTRS = ['userPassword', 'sambaLMPassword', 'sambaNTPassword']
# correspondance par défaut pour les attributs de détermination
# de la branche de recherche
SEARCH_BASE_ATTRS = {'rne':'ou','RNE':'ou','UAI':'ou','ENTPersonStructRattach':'ou'}
# contexte minimum accepté en mode fournisseur de service SAML
DEFAULT_MIN_CONTEXT = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
# gestion de l'authentification SecurID en mode IDP sur ce serveur
# Cette option nécessite l'installation de l'agent PAM linux fourni par RSA
# http://www.rsa.com/node.aspx?id=1177 (dernière version testée : 7.0)
USE_SECURID = False
# définition d'un fournisseur d'identité distant pour SecurID
# (laisser vide si USE_SECURID est activé)
# FIXME : cette option n'est pas encore fonctionelle. laisser à blanc
# Pour l'instant on ne peut s'authentifier en OTP que sur le serveur SSO
# ayant accès au serveur RSA (via PAM)
SECURID_PROVIDER = ""
# Détection des mot de passe OTP (taille longueur minimum/maximum/expression régulière)
OTPPASS_MINSIZE = 10
OTPPASS_MAXSIZE = 12
OTPPASS_REGX = "^[0-9]{10,12}$"
# délai maximum (secondes) laissé à l'utilisateur lorsqu'il doit saisir un 2ème passcode
OTP_TIMEOUT = 300
# indique si on doit rediriger sur une mire externe en cas de
# désynchronysation de la clé OTP
REDIRECT_DESYNC = True
OTP_PORTAL = ""

# active ou non les log de debug (fonctions utilisant @trace)
DEBUG_LOG = True

# Gestion des adresses ip secondaires dans le cas des conteneurs
ALTERNATE_IPS = {}
# containers dont l'adresse est considérée comme adresse du conteneur root
allowed_container_ips = ['web','mail','fichier']
containers_conf = {}

# RECUPERATION DES VARIABLES DEFINIES DANS CREOLE SI DISPONIBLE
################################################################
try:
    from creole.parsedico import parse_dico
    from creole.cert import cert_file, key_file
    from creole.config import containers_file
except:
    # pas d'utilisation de la librairie creole pour le paramétrage du serveur
    # Les valeurs doivent être renseignées dans ce fichier. On affiche un message d'avertissement.
    print "Configuration Creole non disponible, utilisation des valeurs de %s" % str(__file__)
else:
    # lecture de la configuration creole du serveur (config.eol)
    # Les valeurs trouvées sont prioritaires sur les valeurs
    # définies manuellement dans ce fichier
    dico = parse_dico()
    if dico.get('adresse_ip_eth0', ''):
        SERVER_IP_ADDR = dico['adresse_ip_eth0']
    # paramètres de proxy http
    if dico.get('activer_proxy_client', 'non') == 'oui':
        PROXY_SERVER = dico['proxy_client_adresse']
        PROXY_PORT = dico['proxy_client_port']
    # configuration du serveur ldap
    if dico.get('eolesso_ldap', ''):
        LDAP_SERVER = dico['eolesso_ldap']
        # l'annuaire local est dans un conteneur ?
        if dico.get('adresse_ip_annuaire', '127.0.0.1') != '127.0.0.1' \
        and 'localhost' in LDAP_SERVER:
            num = LDAP_SERVER.index('localhost')
            LDAP_SERVER[num] = dico['adresse_ip_annuaire']
    # FIXME 2.3 (hack Zéphir)
    #elif dico.get('serveur_ldap', ''):
    #    LDAP_SERVER = dico['serveur_ldap']
    # identifiant rne du serveur si disponible
    if dico.get('numero_etab', ''):
        RNE = dico['numero_etab']
    if dico.get('libelle_etab', ''):
        ETABLISSEMENT = dico['libelle_etab']
    if dico.get('nom_academie', ''):
        ACADEMIE = dico['nom_academie']
    if dico.get('eolesso_session_timeout', ''):
        SESSION_TIMER = int(dico['eolesso_session_timeout'])
    if dico.get('eolesso_base_ldap', ''):
        LDAP_BASE = dico['eolesso_base_ldap']
    if dico.get('eolesso_port_ldap', ''):
        LDAP_PORT = dico['eolesso_port_ldap']
    if dico.get('eolesso_ldap_label', ''):
        LDAP_LABEL = dico['eolesso_ldap_label']
    if dico.get('eolesso_ldap_infos', ''):
        LDAP_INFOS = dico['eolesso_ldap_infos']
    if dico.get('eolesso_ldap_reader', ''):
        LDAP_READER = dico['eolesso_ldap_reader']
    if dico.get('eolesso_ldap_reader_passfile', ''):
        LDAP_READER_PASSFILE = dico['eolesso_ldap_reader_passfile']
    if dico.get('eolesso_ldap_match_attribute', ''):
        LDAP_MATCH_ATTRIBUTE = dico['eolesso_ldap_match_attribute']
    if dico.get('eolesso_ldap_login_otp', ''):
        LDAP_LOGIN_OTP = dico['eolesso_ldap_login_otp']
    if dico.get('eolesso_adresse', ''):
        # FIXME 2.3 (full_cas)
        AUTH_SERVER_ADDR = dico['eolesso_adresse']
    if dico.get('eolesso_port', ''):
        EOLESSO_PORT = dico['eolesso_port']
    if dico.get('eolesso_adresse_parent', ''):
        PARENT_URL = 'https://%s:%s' % (dico['eolesso_adresse_parent'],
                                        dico['eolesso_port_parent'] or '8443')
    if dico.get('eolesso_key') and os.path.isfile(dico['eolesso_key']):
        KEYFILE = dico['eolesso_key']
    else:
        KEYFILE = ''
    if dico.get('eolesso_cert', '') and os.path.isfile(dico['eolesso_cert']):
        # si pas de clé définie, eolesso recherchera un fichier .key du même nom
        CERTFILE = dico['eolesso_cert']
    else:
        # utilisation des valeurs par défaut de creole.cert (la clé est forcée)
        CERTFILE = cert_file
        KEYFILE = key_file
    if dico.get('eolesso_css', ''):
        DEFAULT_CSS = dico['eolesso_css']
    if dico.get('eolesso_responsive', 'non') == 'oui':
        RESPONSIVE = True
    if dico.has_key('eolesso_ca_location') and os.path.exists(dico['eolesso_ca_location']):
        CA_LOCATION = dico['eolesso_ca_location']
    if dico.get('cas_send_logout', 'non') == 'oui':
        # FIXME 2.3 ?
        SEND_CAS_LOGOUT = True
    if dico.get('cas_verify_service', 'non') == 'oui':
        VERIFY_APP = True
    if dico.get('eolesso_pam_securid', 'non') == 'oui':
        USE_SECURID = True
    if dico.get('federation_transparente', 'non') == 'oui':
        DISPLAY_FEDERATION = False
    if dico.get('eolesso_entity_name', ''):
        IDP_IDENTITY = dico['eolesso_entity_name']
    if dico.get('eolesso_otppass_minsize', ''):
        OTPPASS_MINSIZE = int(dico['eolesso_otppass_minsize'])
    if dico.get('eolesso_otppass_maxsize', ''):
        OTPPASS_MAXSIZE = int(dico['eolesso_otppass_maxsize'])
    if dico.get('eolesso_otppass_regx', ''):
        OTPPASS_REGX = dico['eolesso_otppass_regx']
    if dico.get('eolesso_otp_desync', 'non') == 'oui':
        REDIRECT_DESYNC = False
    if dico.get('eolesso_otp_portal', ''):
        OTP_PORTAL = dico['eolesso_otp_portal']
    # avertissement internet explorer
    if dico.get('activer_envole', 'non') == 'oui':
        ACTIVER_ENVOLE = True
        if dico.get('activer_envole_infos', 'non') == 'oui':
            ACTIVER_ENVOLE_INFOS = True
    if dico.get('web_url', ''):
        POSH_URL = dico['web_url']
    if dico.get('sso_saml_time_adjust', ''):
        try:
            # délai en secondes, valeur entière (positive ou negative) obligatoire
            TIME_ADJUST = int(dico['sso_saml_time_adjust'])
        except:
            pass

    if os.path.isfile(containers_file):
        execfile(containers_file, {}, containers_conf)
        for varname, val in containers_conf.items():
            # pour tous les conteneurs autorisés à utiliser le mode proxy, on utilise
            # l'adresse du conteneur maître comme adresse alternative (pour validation des certificats)
            if varname.startswith('container_ip_') and varname.replace('container_ip_','') in allowed_container_ips:
                ALTERNATE_IPS[val] = SERVER_IP_ADDR

# adresse du serveur d'authentification (nom DNS)
if AUTH_SERVER_ADDR == "":
    AUTH_SERVER_ADDR = socket.getfqdn(SERVER_IP_ADDR)

# VALEURS CALCULEES
####################

# URL de la page web d'authentification
AUTH_FORM_URL = 'https://%s:%s' % (AUTH_SERVER_ADDR, EOLESSO_PORT)
# URL du serveur d'authentification
AUTH_SERVER='https://%s:%s/xmlrpc' % (AUTH_SERVER_ADDR, EOLESSO_PORT)
IDP_IDENTITY = IDP_IDENTITY or "urn:fi:%s:et-%s:1.0" % (ACADEMIE, ETABLISSEMENT or AUTH_SERVER_ADDR)
CA_LOCATION = CA_LOCATION or os.path.join(os.path.dirname(CERTFILE), 'ca.crt')
if "".join(LDAP_SERVER) == "":
    # si aucun serveur ldap spécifié, on utilise la même ip que le serveur d'authentification
    LDAP_SERVER = [SERVER_IP_ADDR]

# REPERTOIRES DES DONNEES
##########################

# répertoire des filtres d'application
FILTER_DIR = os.path.join(SSO_PATH, 'app_filters')
# répertoire des fichiers metadata pour les entités SAML
METADATA_DIR = os.path.join(SSO_PATH, 'metadata')
# répertoire des définitions de jeux d'attributs
ATTR_SET_DIR = os.path.join(SSO_PATH, 'attribute_sets')
# répertoire des correspondances d'utilisateurs securid
SECURID_USER_DIR = os.path.join(SSO_PATH, 'securid_users')
# répertoire des fichiers d'information pour les homonymes
HOMONYMES_DIR = os.path.join(SSO_PATH, 'interface', 'info_homonymes')
