diff --git a/requirements.txt b/requirements.txt index dae0e3e..9a5d853 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,4 @@ django < 1.6 +importlib +git+git://repos.entrouvert.org/authentic + diff --git a/scripts/univcloud-geo2idp.py b/scripts/univcloud-geo2idp.py new file mode 100755 index 0000000..ce3dcf8 --- /dev/null +++ b/scripts/univcloud-geo2idp.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +''' +output a merge of idp + geo informations from discojuice +''' + +import os +os.environ['DJANGO_SETTINGS_MODULE'] = 'univcloud.settings' + +from authentic2.saml.common import get_idp_list_sorted +import sys +import json +import math +import urllib + +def geo2idp(filename): + idps = {} + try: + f = open(filename) + except IOError, e: + print >> sys.stderr, e + return {} + try: + idp_list = json.load(f) + except ValueError, e: + f.close() + print >> sys.stderr, 'reading %s: %s' % (filename, e) + return {} + f.close() + if not idp_list: + return {} + if not isinstance(idp_list, list): + print >> sys.stderr, '%s does not contain a list' % filename + return {} + for idp in idp_list: + try: + idps[idp['entityID']] = idp + except Exception, e: + print >> sys.stderr, 'bad geo information in %s (%s)' % (filename, idp) + return idps + +geo_idps = {} +for geofile in sys.argv[1:]: + geo_idps.update(geo2idp(geofile)) + +n = 0 +for idp in get_idp_list_sorted(): + n += 1 + entity_id = idp['entity_id'] + name = idp['name'] + geo = geo_idps.get(entity_id, {}).get('geo', { 'lat': 47.0 + 2.0*math.sin(n), 'lon': 2.5 + 3.0*math.cos(n) }) + href = '/sso?' + urllib.urlencode([('entity_id', entity_id)]) + li = u'
  • %s
  • ' % \ + (href, geo['lat'], geo['lon'], entity_id, name, name) + print li.encode('utf-8') + diff --git a/scripts/univcloud-update-map.sh b/scripts/univcloud-update-map.sh new file mode 100755 index 0000000..61e4eca --- /dev/null +++ b/scripts/univcloud-update-map.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +GEOURLS="https://static.discojuice.org/feeds/renater http://isos.univnautes.entrouvert.com/univnautes.geo" +GEODIR="/var/tmp/univcloud-geo/" +VIRTUAL_ENV="/home/thomas/univcloud/venv/" +PYTHONPATH="/home/thomas/univcloud/" + +if [ -r /etc/univcloud.conf ] +then + . /etc/univcloud.conf +fi + +mkdir -p $GEODIR + +# virtualenv activation +export VIRTUAL_ENV +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH +export PYTHONPATH + +# lock to avoid concurrent updates +LOCK=/var/tmp/univcloud-update-map_in-progress.lock +if [ -r $LOCK ] +then + PID=`cat $LOCK` + ps waux | grep $PID | grep univcloud | grep -vq grep && exit +fi +unlock() { + rm -f $LOCK + exit +} +trap unlock INT TERM EXIT +echo $$ > $LOCK + +n=1 +for url in $GEOURLS +do + GEOFILE=$GEODIR/$n + wget -q --no-check-certificate -O $GEOFILE $url + if [ $? -eq 0 ] + then + GEOFILES=$GEOFILES" "$GEOFILE + n=$(($n+1)) + else + echo "cannot download $url" + fi +done + +if [ -r $GEOLOCAL ] +then + GEOFILES=$GEOFILES" "$GEOLOCAL +fi + +# create indexhtml +python univcloud-geo2idp.py $GEOFILES + +exit 0 diff --git a/scripts/univcloud-update-metadata.sh b/scripts/univcloud-update-metadata.sh new file mode 100755 index 0000000..3cbfbd4 --- /dev/null +++ b/scripts/univcloud-update-metadata.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +MD=/var/tmp/univcloud-metadata +MDURL="https://services-federation.renater.fr/metadata/renater-test-metadata.xml" +MDCA= +MDCRT= +VIRTUAL_ENV="/home/thomas/univcloud/venv" +MANAGE="/home/thomas/univcloud/manage.py" + +if [ -r /etc/univcloud.conf ] +then + . /etc/univcloud.conf +fi + + +# lock to avoid concurrent updates +LOCK=/var/tmp/univcloud-update-metadata_in-progress.lock +if [ -r $LOCK ] +then + PID=`cat $LOCK` + ps waux | grep $PID | grep univcloud | grep -vq grep && exit +fi +unlock() { + rm -f $LOCK + exit +} +trap unlock INT TERM EXIT +echo $$ > $LOCK + + +# clean +rm -f $MD + +# +# 1. Download throught HTTPS +# + +FETCH=$MD.fetch.$$ + +if [ -r "$MDCA" ] +then + echo "downloading IdPs metadata from $MDURL (ca=$MDCA)" + wget --quiet --timeout=300 --ca-certificate=$MDCA -O $FETCH $MDURL + RET=$? +else + echo "downloading IdPs metadata from $MDURL (no-check-certificate)" + wget --quiet --timeout=300 --no-check-certificate -O $FETCH $MDURL + RET=$? +fi + +if [ $RET -ne 0 ] +then + rm -f $FETCH + echo "error while downloading IdPs metadata (wget)" + unset MD + unset MDCRT +else + mv -f $FETCH $MD +fi + +# +# 2. Check metadatas +# + +if [ -n "$MD" -a -r "$MDCRT" ] +then + xmlsec1 --verify --pubkey-cert-pem $MDCRT $MD + if [ $? -ne 0 ] + then + echo "error while checking signature of IdPs metadata (xmlsec1)" + unset MD + fi +elif [ -n "$MD" ] +then + echo "WARNING: do not check signature of IdPs metadata" +fi + +# +# 3. Insert metadata in univcloud database +# + +# virtualenv activation +export VIRTUAL_ENV +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +if [ -n "$MD" ] +then + python $MANAGE sync-metadata --source="federation" --idp --verbosity=1 $MD +fi + +exit 0 + diff --git a/univcloud/settings.py b/univcloud/settings.py index daf2671..26dc207 100644 --- a/univcloud/settings.py +++ b/univcloud/settings.py @@ -28,11 +28,11 @@ ALLOWED_HOSTS = [] # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # In a Windows environment this must be set to your system time zone. -TIME_ZONE = 'America/Chicago' +TIME_ZONE = 'Europe/Paris' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'fr-fr' SITE_ID = 1 @@ -119,6 +119,10 @@ INSTALLED_APPS = ( 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', + 'authentic2.idp', + 'authentic2.attribute_aggregator', + 'authentic2.saml', + 'authentic2.authsaml2', 'univcloud.profile', ) @@ -155,6 +159,67 @@ LOGIN_REDIRECT_URL = '/' AUTH_PROFILE_MODULE = 'profile.UserProfile' +AUTH_FRONTENDS = ('authentic2.authsaml2.frontend.AuthSAML2Frontend',) +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'authentic2.authsaml2.backends.AuthSAML2PersistentBackend', + 'authentic2.authsaml2.backends.AuthSAML2TransientBackend') + +SAML_SIGNATURE_PUBLIC_KEY = '''-----BEGIN CERTIFICATE----- +MIIDIzCCAgugAwIBAgIJANUBoick1pDpMA0GCSqGSIb3DQEBBQUAMBUxEzARBgNV +BAoTCkVudHJvdXZlcnQwHhcNMTAxMjE0MTUzMzAyWhcNMTEwMTEzMTUzMzAyWjAV +MRMwEQYDVQQKEwpFbnRyb3V2ZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvxFkfPdndlGgQPDZgFGXbrNAc/79PULZBuNdWFHDD9P5hNhZn9Kqm4Cp +06Pe/A6u+g5wLnYvbZQcFCgfQAEzziJtb3J55OOlB7iMEI/T2AX2WzrUH8QT8NGh +ABONKU2Gg4XiyeXNhH5R7zdHlUwcWq3ZwNbtbY0TVc+n665EbrfV/59xihSqsoFr +kmBLH0CoepUXtAzA7WDYn8AzusIuMx3n8844pJwgxhTB7Gjuboptlz9Hri8JRdXi +VT9OS9Wt69ubcNoM6zuKASmtm48UuGnhj8v6XwvbjKZrL9kA+xf8ziazZfvvw/VG +Tm+IVFYB7d1x457jY5zjjXJvNysoowIDAQABo3YwdDAdBgNVHQ4EFgQUeF8ePnu0 +fcAK50iBQDgAhHkOu8kwRQYDVR0jBD4wPIAUeF8ePnu0fcAK50iBQDgAhHkOu8mh +GaQXMBUxEzARBgNVBAoTCkVudHJvdXZlcnSCCQDVAaInJNaQ6TAMBgNVHRMEBTAD +AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAy8l3GhUtpPHx0FxzbRHVaaUSgMwYKGPhE +IdGhqekKUJIx8et4xpEMFBl5XQjBNq/mp5vO3SPb2h2PVSks7xWnG3cvEkqJSOeo +fEEhkqnM45b2MH1S5uxp4i8UilPG6kmQiXU2rEUBdRk9xnRWos7epVivTSIv1Ncp +lG6l41SXp6YgIb2ToT+rOKdIGIQuGDlzeR88fDxWEU0vEujZv/v1PE1YOV0xKjTT +JumlBc6IViKhJeo1wiBBrVRIIkKKevHKQzteK8pWm9CYWculxT26TZ4VWzGbo06j +o2zbumirrLLqnt1gmBDvDvlOwC/zAAyL4chbz66eQHTiIYZZvYgy +-----END CERTIFICATE-----''' + +SAML_SIGNATURE_PRIVATE_KEY = '''-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvxFkfPdndlGgQPDZgFGXbrNAc/79PULZBuNdWFHDD9P5hNhZ +n9Kqm4Cp06Pe/A6u+g5wLnYvbZQcFCgfQAEzziJtb3J55OOlB7iMEI/T2AX2WzrU +H8QT8NGhABONKU2Gg4XiyeXNhH5R7zdHlUwcWq3ZwNbtbY0TVc+n665EbrfV/59x +ihSqsoFrkmBLH0CoepUXtAzA7WDYn8AzusIuMx3n8844pJwgxhTB7Gjuboptlz9H +ri8JRdXiVT9OS9Wt69ubcNoM6zuKASmtm48UuGnhj8v6XwvbjKZrL9kA+xf8ziaz +Zfvvw/VGTm+IVFYB7d1x457jY5zjjXJvNysoowIDAQABAoIBAQCj8t2iKXya10HG +V6Saaeih8aftoLBV38VwFqqjPU0+iKqDpk2JSXBhjI6s7uFIsaTNJpR2Ga1qvns1 +hJQEDMQSLhJvXfBgSkHylRWCpJentr4E3D7mnw5pRsd61Ev9U+uHcdv/WHP4K5hM +xsdiwXNXD/RYd1Q1+6bKrCuvnNJVmWe0/RV+r3T8Ni5xdMVFbRWt/VEoE620XX6c +a9TQPiA5i/LRVyie+js7Yv+hVjGOlArtuLs6ECQsivfPrqKLOBRWcofKdcf+4N2e +3cieUqwzC15C31vcMliD9Hax9c1iuTt9Q3Xzo20fOSazAnQ5YBEExyTtrFBwbfQu +ku6hp81pAoGBAN6bc6iJtk5ipYpsaY4ZlbqdjjG9KEXB6G1MExPU7SHXOhOF0cDH +/pgMsv9hF2my863MowsOj3OryVhdQhwA6RrV263LRh+JU8NyHV71BwAIfI0BuVfj +6r24KudwtUcvMr9pJIrJyMAMaw5ZyNoX7YqFpS6fcisSJYdSBSoxzrzVAoGBANu6 +xVeMqGavA/EHSOQP3ipDZ3mnWbkDUDxpNhgJG8Q6lZiwKwLoSceJ8z0PNY3VetGA +RbqtqBGfR2mcxHyzeqVBpLnXZC4vs/Vy7lrzTiHDRZk2SG5EkHMSKFA53jN6S/nJ +JWpYZC8lG8w4OHaUfDHFWbptxdGYCgY4//sjeiuXAoGBANuhurJ99R5PnA8AOgEW +4zD1hLc0b4ir8fvshCIcAj9SUB20+afgayRv2ye3Dted1WkUL4WYPxccVhLWKITi +rRtqB03o8m3pG3kJnUr0LIzu0px5J/o8iH3ZOJOTE3iBa+uI/KHmxygc2H+XPGFa +HGeAxuJCNO2kAN0Losbnz5dlAoGAVsCn94gGWPxSjxA0PC7zpTYVnZdwOjbPr/pO +LDE0cEY9GBq98JjrwEd77KibmVMm+Z4uaaT0jXiYhl8pyJ5IFwUS13juCbo1z/u/ +ldMoDvZ8/R/MexTA/1204u/mBecMJiO/jPw3GdIJ5phv2omHe1MSuSNsDfN8Sbap +gmsgaiMCgYB/nrTk89Fp7050VKCNnIt1mHAcO9cBwDV8qrJ5O3rIVmrg1T6vn0aY +wRiVcNacaP+BivkrMjr4BlsUM6yH4MOBsNhLURiiCL+tLJV7U0DWlCse/doWij4U +TKX6tp6oI+7MIJE6ySZ0cBqOiydAkBePZhu57j6ToBkTa0dbHjn1WA== +-----END RSA PRIVATE KEY-----''' + +LOCAL_METADATA_CACHE_TIMEOUT = 600 +SAML_METADATA_ROOT = 'metadata' +# Can be none, sp, idp or both +SAML_METADATA_AUTOLOAD = 'none' + + + try: from local_settings import * except ImportError: