This repository has been archived by the owner on May 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprove_of_ownership.py
169 lines (137 loc) · 5.77 KB
/
prove_of_ownership.py
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
"""Module for proving ownership of phone numbers using various 2FA APIs."""
import logging
import requests
from twilio.rest import Client
from twilio.base.exceptions import TwilioRestException
from config import (
TWILIO_ACCOUNT_SID,
TWILIO_AUTH_TOKEN,
TWILIO_PHONE_NUMBER,
CUSTOM_VERIFICATION_API_URL,
CUSTOM_VERIFICATION_API_KEY,
)
logger = logging.getLogger(__name__)
class ProveOfOwnership:
"""
A class for proving ownership of a phone number using various 2FA APIs.
Attributes:
api_key (str): API key for the custom 2FA service.
api_url (str): URL endpoint for the custom 2FA service.
twilio_account_sid (str): Twilio account SID.
twilio_auth_token (str): Twilio authentication token.
twilio_phone_number (str): Twilio phone number used for sending SMS.
Methods:
send_verification_code(phone_number): Sends a verification code to the
given phone number.
verify_code(phone_number, code): Verifies the provided code against the
sent verification code.
"""
def __init__(self):
"""Initialize the ProveOfOwnership."""
self.api_key = CUSTOM_VERIFICATION_API_KEY
self.api_url = CUSTOM_VERIFICATION_API_URL
self.twilio_account_sid = TWILIO_ACCOUNT_SID
self.twilio_auth_token = TWILIO_AUTH_TOKEN
self.twilio_phone_number = TWILIO_PHONE_NUMBER
self.twilio_client = None
if (
self.twilio_account_sid
and self.twilio_auth_token
and self.twilio_phone_number
):
self.twilio_client = Client(self.twilio_account_sid, self.twilio_auth_token)
def send_verification_code(self, phone_number):
"""
Sends a verification code to the given phone number.
Args:
phone_number (str): The phone number to send the verification code to.
Returns:
bool: True if the code is sent successfully, False otherwise.
"""
if self.twilio_client is not None:
try:
verification = self.twilio_client.verify.v2.services(
self.twilio_account_sid
).verifications.create(to=phone_number, channel="sms")
logger.info("Verification code sent successfully via Twilio!")
return True
except TwilioRestException as e:
logger.error("Failed to verify code via Twilio: %s", e)
return False
except Exception as e:
logger.error(
"Unexpected error occurred while verifying code via Twilio:"
)
raise e
elif self.api_key and self.api_url:
try:
response = requests.post(
self.api_url,
headers={"Authorization": f"Bearer {self.api_key}"},
json={"phone_number": phone_number},
timeout=10,
)
response.raise_for_status()
logger.info("Verification code sent successfully!")
return True
except requests.exceptions.RequestException as e:
logger.error("Failed to verify code: %s", e)
return False
except Exception as e:
logger.error(
"Unexpected error occurred while verifying code via API:",
)
raise
else:
raise RuntimeError("No valid 2FA service available.")
def verify_code(self, phone_number, code):
"""
Verifies the provided code against the sent verification code.
Args:
phone_number (str): The phone number that received the verification code.
code (str): The code to be verified.
Returns:
bool: True if the provided code matches the verification code, False otherwise.
"""
if self.twilio_client is not None:
try:
verification_check = self.twilio_client.verify.v2.services(
self.twilio_account_sid
).verification_checks.create(to=phone_number, code=code)
if verification_check.status == "approved":
logger.info("Verification successful via Twilio!")
return True
logger.error("Verification failed via Twilio. Incorrect code.")
return False
except TwilioRestException as e:
logger.error("Failed to verify code via Twilio: %s", e)
return False
except Exception as e:
logger.error(
"Unexpected error occurred while verifying code via Twilio:"
)
raise e
elif self.api_key and self.api_url:
try:
verification_check = requests.post(
f"{self.api_url}",
headers={"Authorization": f"Bearer {self.api_key}"},
json={"phone_number": phone_number, "code": code},
timeout=10,
)
verification_check.raise_for_status()
if verification_check.status_code == 200:
logger.info("Verification successful!")
return True
logger.error("Verification failed. Incorrect code.")
return False
except requests.exceptions.RequestException as e:
logger.error("Failed to verify code: %s", e)
return False
except Exception as e:
logger.error(
"Unexpected error occurred while verifying code via API:",
)
raise
else:
raise RuntimeError("No valid 2FA service available.")