]> git.ipfire.org Git - ipfire.org.git/blame - src/backend/zeiterfassung.py
CSS: Add CSS for file listings
[ipfire.org.git] / src / backend / zeiterfassung.py
CommitLineData
2c361abc
MT
1#!/usr/bin/python
2
3import hashlib
4import hmac
5import json
6import tornado.httpclient
7import tornado.gen
11347e46 8import urllib.parse
2c361abc 9
11347e46 10from .misc import Object
2c361abc
MT
11
12class ZeiterfassungClient(Object):
13 algorithm = "Zeiterfassung-HMAC-SHA512"
14
15 def init(self):
16 self.url = self.settings.get("zeiterfassung_url")
17
18 # API credentials
19 self.api_key = self.settings.get("zeiterfassung_api_key")
20 self.api_secret = self.settings.get("zeiterfassung_api_secret")
21
22 # Check if all configuration values are set
23 if not all((self.url, self.api_key, self.api_secret)):
24 raise RuntimeError("%s is not configured" % self.__class__.__name__)
25
26 # Create HTTPClient
27 self.http_client = tornado.httpclient.AsyncHTTPClient(
28 defaults = {
29 "User-Agent" : "IPFireWebApp",
30 }
31 )
32
33 def _make_signature(self, method, path, body):
34 # Empty since we only support POST
35 canonical_query = ""
36
37 # Put everything together
38 string_to_sign = "\n".join((
39 method, path, canonical_query,
40 )).encode("utf-8") + body
41
42 # Compute HMAC
43 h = hmac.new(self.api_secret.encode("utf-8"), string_to_sign, hashlib.sha512)
44
45 return h.hexdigest()
46
47 @tornado.gen.coroutine
48 def send_request(self, path, **kwargs):
11347e46 49 url = urllib.parse.urljoin(self.url, path)
2c361abc
MT
50
51 # Query arguments are all keyword arguments
52 arguments = kwargs
53
54 request = tornado.httpclient.HTTPRequest(url, method="POST")
11347e46 55 request.body = urllib.parse.urlencode(arguments)
2c361abc
MT
56
57 # Compose the signature
58 signature = self._make_signature("POST", path, request.body)
59
60 # Add authorization header
61 request.headers["Authorization"] = " ".join(
62 (self.algorithm, self.api_key, signature)
63 )
64
65 # Send the request
66 response = yield self.http_client.fetch(request)
67
68 # Decode the JSON response
69 d = json.loads(response.body.decode())
70
71 raise tornado.gen.Return(d)