]>
Commit | Line | Data |
---|---|---|
2c361abc MT |
1 | #!/usr/bin/python |
2 | ||
3 | import hashlib | |
4 | import hmac | |
5 | import json | |
6 | import tornado.httpclient | |
11347e46 | 7 | import urllib.parse |
2c361abc | 8 | |
11347e46 | 9 | from .misc import Object |
2c361abc MT |
10 | |
11 | class ZeiterfassungClient(Object): | |
12 | algorithm = "Zeiterfassung-HMAC-SHA512" | |
13 | ||
14 | def init(self): | |
15 | self.url = self.settings.get("zeiterfassung_url") | |
16 | ||
17 | # API credentials | |
18 | self.api_key = self.settings.get("zeiterfassung_api_key") | |
19 | self.api_secret = self.settings.get("zeiterfassung_api_secret") | |
20 | ||
21 | # Check if all configuration values are set | |
22 | if not all((self.url, self.api_key, self.api_secret)): | |
23 | raise RuntimeError("%s is not configured" % self.__class__.__name__) | |
24 | ||
2c361abc MT |
25 | def _make_signature(self, method, path, body): |
26 | # Empty since we only support POST | |
27 | canonical_query = "" | |
28 | ||
29 | # Put everything together | |
30 | string_to_sign = "\n".join(( | |
31 | method, path, canonical_query, | |
32 | )).encode("utf-8") + body | |
33 | ||
34 | # Compute HMAC | |
35 | h = hmac.new(self.api_secret.encode("utf-8"), string_to_sign, hashlib.sha512) | |
36 | ||
37 | return h.hexdigest() | |
38 | ||
9fdf4fb7 | 39 | async def send_request(self, path, **kwargs): |
11347e46 | 40 | url = urllib.parse.urljoin(self.url, path) |
2c361abc MT |
41 | |
42 | # Query arguments are all keyword arguments | |
43 | arguments = kwargs | |
44 | ||
45 | request = tornado.httpclient.HTTPRequest(url, method="POST") | |
11347e46 | 46 | request.body = urllib.parse.urlencode(arguments) |
2c361abc MT |
47 | |
48 | # Compose the signature | |
49 | signature = self._make_signature("POST", path, request.body) | |
50 | ||
51 | # Add authorization header | |
52 | request.headers["Authorization"] = " ".join( | |
53 | (self.algorithm, self.api_key, signature) | |
54 | ) | |
55 | ||
56 | # Send the request | |
9fdf4fb7 | 57 | response = await self.backend.http_client.fetch(request) |
2c361abc MT |
58 | |
59 | # Decode the JSON response | |
9fdf4fb7 | 60 | return json.loads(response.body.decode()) |