~ren/magentasso-py

ref: bb9d1cc841e486f26ee4e69845aa1ba84ca83dfb magentasso-py/magentasso/response.py -rw-r--r-- 2.1 KiB
bb9d1cc8 — Lauren Jenkinson Initial code commit 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import base64
import hmac
import json

from urllib.parse import urlencode


class MagentaResponse:
    def __init__(self, client_id, client_secret, nonce, user_data, scope_data):
        self.client_id = client_id

        self.client_secret = client_secret
        if not isinstance(client_secret, bytes):
            self.client_secret = base64.b32decode(client_secret.upper())

        self.nonce = nonce
        self.user_data = user_data
        self.scope_data = scope_data

    def sign(self):
        data = {
            "client_id": self.client_id,
            "nonce": self.nonce,
            "user_data": self.user_data,
            "scope_data": self.scope_data,
        }

        payload = json.dumps(data).encode("utf-8")
        payload = base64.urlsafe_b64encode(payload)
        signature = hmac.digest(self.client_secret, payload, "sha256")
        signature = base64.urlsafe_b64encode(signature)

        return (payload, signature)

    def callback_query(self):
        payload, signature = self.sign()
        params = {
            "payload": payload,
            "signature": signature,
        }

        return urlencode(params)

    @classmethod
    def verify(cls, payload, signature, client_secret):
        if not isinstance(client_secret, bytes):
            client_secret = base64.b32decode(client_secret.upper())

        if not isinstance(signature, bytes):
            signature = signature.encode("utf-8")

        if not isinstance(payload, bytes):
            payload = payload.encode("utf-8")

        signature_check = hmac.digest(client_secret, payload, "sha256")
        signature = base64.urlsafe_b64decode(signature)

        if signature != signature_check:
            raise ValueError("mismatching signatures")

        payload = base64.urlsafe_b64decode(payload)
        payload = json.loads(payload.decode("utf-8"))

        output = cls(
            payload["client_id"],
            client_secret,
            payload["nonce"],
            payload["user_data"],
            payload["scope_data"],
        )

        return output

    def __repr__(self):
        return "MagentaResponse(client_id=%r nonce=%r)" % (self.client_id, self.nonce,)