satcfdi.portal.utils.verify_token()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 12
nop 2
dl 0
loc 18
ccs 10
cts 10
cp 1
crap 1
rs 9.8
c 0
b 0
f 0
1 1
import base64
2 1
import random
3 1
import string
4 1
from urllib.parse import urlparse, urlunparse
5
6 1
from bs4 import BeautifulSoup
7 1
from requests import Response
8
9 1
from ..models import Signer, Certificate
10
11
12 1
def generate_token(signer: Signer, code: str) -> bytes:
13 1
    rfc = signer.rfc
14 1
    num_serie = signer.certificate_number
15
16 1
    co = code + "|" + rfc + "|" + num_serie
17
18 1
    signature = signer.sign_sha1(data=co.encode())
19
20 1
    return base64.b64encode(
21
        base64.b64encode(co.encode()) + b"#" + base64.b64encode(signature.encode())
22
    )
23
24
25 1
def verify_token(certificate: Certificate, token: bytes) -> str:
26 1
    decoded_token = base64.b64decode(token)
27 1
    code, signature = decoded_token.split(b"#", maxsplit=2)
28
29 1
    code = base64.b64decode(code)
30 1
    signature = base64.b64decode(signature)
31
32 1
    assert certificate.verify_sha1(
33
        data=code,
34
        signature=base64.b64decode(signature)
35
    )
36
37 1
    code, rfc, num_serie = code.decode().split("|", maxsplit=3)
38
39 1
    assert rfc == certificate.rfc
40 1
    assert num_serie == certificate.certificate_number
41
42 1
    return code
43
44
45 1
def action_url(action: str | None, url: str):
46 1
    if not action:
47 1
        return url
48
49 1
    if action.startswith('/'):
50 1
        parts = urlparse(url)
51 1
        return urlunparse((parts.scheme, parts.netloc, action, None, None, None))
52
53 1
    return action
54
55
56 1
def get_form(res: Response, id=None):
57
    html = BeautifulSoup(res.text, 'html.parser')
58
    if id:
59
        form = html.find(id=id)
60
    else:
61
        form = html.select('form')[0]
62
63
    data = {
64
        i.attrs['name']: i.attrs.get('value')
65
        for i in form.findChildren('input')
66
        if 'name' in i.attrs
67
    }
68
69
    assert form.attrs['method'].upper() == "POST"
70
    return action_url(form.attrs.get('action'), res.url), data
71
72
73 1
def request_ref_headers(url):
74
    parts = urlparse(url)
75
    return {
76
        'origin': urlunparse((parts.scheme, parts.netloc, '', '', '', '')),
77
        'referer': url
78
    }
79
80
81 1
def request_verification_token(res: Response):
82
    html = BeautifulSoup(res.text, 'html.parser')
83
    return html.find(name='input', attrs={'name': '__RequestVerificationToken'}).attrs['value']
84
85
86 1
def random_ajax_id():
87
    return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(5))
88