b7496724e752b7c07bfbdcf92ba8570bb8bade20
[myslice.git] / activity / __init__.py
1 #
2 # Activity monitor
3 #
4 # Client is authenticated with an API key and a secret
5 # The API key is a 64 chars string (digits and letters) that is passed to the request
6 # The secret is a 64 chars string that is used to sign the request
7 # The generated signature is a SHA256 hes digest
8
9 import urllib, urllib2
10 import threading
11 import hmac
12 import hashlib
13 import base64
14 import time
15 import datetime
16 from myslice.configengine import ConfigEngine
17 from myslice.settings import logger
18
19
20 config = ConfigEngine()
21 if config.activity and config.activity.apikey :
22     apikey = config.activity.apikey
23 else :
24     # apikey will be necessary
25     apikey = None
26
27 if config.activity and config.activity.secret :
28     secret = config.activity.secret
29 else :
30     # secret will be necessary
31     secret = None
32
33 if config.activity and config.activity.server :
34     server = config.activity.server
35 else :
36     # default log server
37     server = "http://athos.ipv6.lip6.fr/activity/push/log"
38
39 def logWrite(request, action, message, objects = None):
40     
41     if not apikey :
42         logger.info("===============>> activity: no apikey")
43         return
44     if not secret :
45         logger.info("===============>> activity: no secret")
46         return
47     
48     timestamp = time.mktime(datetime.datetime.today().timetuple())
49     ip = getClientIp(request)
50     log = {
51         "timestamp" : timestamp,
52         "client_ip" : ip,
53         "host"      : request.get_host(),
54         "referrer"  : request.META.get('HTTP_REFERER'),
55         "user"      : request.user,
56         "action"    : action,
57         "message"   : message,
58         "apikey"    : apikey,
59         "signature" : sign(secret, "%s%s%s%s" % (timestamp, ip, request.user, action)),
60         "slice"     : None,
61         "resource"  : None,
62         "resource_type"     : None,
63         "facility"      : None,
64         "testbed"       : None,
65     }
66     
67     if objects is not None:
68         for o in objects :
69             if (o in log) :
70                 log[o] = objects[o]
71     
72     try :
73         result = urllib2.urlopen(server, urllib.urlencode(log))
74         logger.info("===============>> activity: {} <{}> {}".format(action, request.user,message))
75         content = result.read()
76     except urllib2.URLError as e:
77         logger.error("===============>> activity: connection to {} impossible, could not log action".format(server))
78         logger.error(e.strerror)
79
80 def log(request, action, message, objects = None):
81     # Create a new thread in Daemon mode to send the log entry
82     t = threading.Thread(target=logWrite, args=(request, action, message, objects))
83     t.setDaemon(True)
84     t.start()
85
86 def getClientIp(request):
87     try :
88         x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
89         ip = x_forwarded_for.split(',')[0]
90     except:
91         ip = request.META.get('REMOTE_ADDR')
92     return ip
93
94 #
95 # sign the request with the secret key
96 def sign(secret, message):
97     return hmac.new(secret, msg=message, digestmod=hashlib.sha256).hexdigest()