Skip to content

Commit 031ac58

Browse files
author
brentru
committed
remove the buttons, limits the amount of keyz we can store. make the user press the screen instead
1 parent c6f7578 commit 031ac58

1 file changed

Lines changed: 38 additions & 63 deletions

File tree

PyPortal_TOTP_Friend/code.py

Lines changed: 38 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
# PyPortal TOTP Authenticator
12
import time
23

3-
import board
4-
import busio
5-
from digitalio import DigitalInOut
6-
74
import adafruit_hashlib as hashlib
5+
import adafruit_imageload
86
import adafruit_touchscreen
7+
import board
8+
import busio
99
import displayio
1010
import neopixel
1111
import terminalio
@@ -18,6 +18,7 @@
1818
from adafruit_esp32spi import adafruit_esp32spi
1919
from adafruit_ntp import NTP
2020
from adafruit_pyportal import PyPortal
21+
from digitalio import DigitalInOut
2122

2223
# Background/Images
2324
BACKGROUND = 0x059ACE
@@ -33,7 +34,6 @@
3334
print("WiFi secrets are kept in secrets.py, please add them there!")
3435
raise
3536

36-
3737
# Initialize PyPortal Display
3838
display = board.DISPLAY
3939

@@ -47,7 +47,6 @@
4747
),
4848
size=(WIDTH, HEIGHT))
4949

50-
5150
# Create a SHA1 Object
5251
SHA1 = hashlib.sha1
5352

@@ -60,7 +59,6 @@
6059
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
6160
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
6261

63-
6462
# HMAC implementation, as hashlib/hmac wouldn't fit
6563
# From https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
6664
def HMAC(k, m):
@@ -116,7 +114,6 @@ def int_to_bytestring(i, padding=8):
116114

117115
# HMAC -> OTP generator, pretty much same as
118116
# https://github.com/pyotp/pyotp/blob/master/src/pyotp/otp.py
119-
120117
def generate_otp(int_input, secret_key, digits=6):
121118
if int_input < 0:
122119
raise ValueError('input must be positive integer')
@@ -132,7 +129,6 @@ def generate_otp(int_input, secret_key, digits=6):
132129
str_code = str(code % 10 ** digits)
133130
while len(str_code) < digits:
134131
str_code = '0' + str_code
135-
136132
return str_code
137133

138134

@@ -163,43 +159,33 @@ def generate_otp(int_input, secret_key, digits=6):
163159

164160
splash.append(background)
165161

166-
167162
key_group = displayio.Group(scale=5)
168163
# We'll use a default text placeholder for this label
169164
label_key = Label(font, text="000 000")
170165
label_key.x = (display.width // 2) // 13
171-
label_key.y = 15
166+
label_key.y = 17
172167
key_group.append(label_key)
173168

174169
label_title = Label(font, max_glyphs=14)
175-
label_title.x = (display.width // 2) // 10
170+
label_title.text = "loading.."
171+
label_title.x = (display.width // 2) // 13
176172
label_title.y = 5
177173
key_group.append(label_title)
178174

179175
splash.append(key_group)
180176

181-
# Create a label to monitor the status
182-
label_status = Label(font, max_glyphs=45)
183-
label_status.x = (display.width // 2) - 50
184-
label_status.y = 120
185-
splash.append(label_status)
186-
187177
# Show the group
188178
display.show(splash)
189179

190-
191180
print("Connecting to AP...")
192-
label_status.text = "Connecting to AP..."
193181
while not esp.is_connected:
194182
try:
195183
esp.connect_AP(secrets['ssid'], secrets['password'])
196184
except RuntimeError as e:
197185
print("could not connect to AP, retrying: ", e)
198-
label_status.text("Retrying...")
199186
continue
200187

201188
print("Connected to SSID: ", secrets['ssid'])
202-
label_status.text = "Connected! Fetching NTP..."
203189

204190
# Initialize the NTP object
205191
ntp = NTP(esp)
@@ -220,57 +206,46 @@ def generate_otp(int_input, secret_key, digits=6):
220206
mono_time = int(time.monotonic())
221207
print("Monotonic time", mono_time)
222208

223-
# Clear the status label
224-
label_status.text = ""
225209

226-
# Add buttons to the interface
227-
# TODO: Generate them like in https://learn.adafruit.com/pyportal-philips-hue-lighting-controller/code-walkthrough
228-
# TODO: Make these dynamically based on what is store in secrets.py
229-
# TODO: Add icons to buttons instead of text
210+
def display_otp(unix_time, name, secret):
211+
"""Updates text objects to display the OTP and name.
230212
231-
assert len(secrets['totp_keys']) < 8, "This code can only render 8 keys at a time"
213+
:param int unix_time: Current unix time
214+
:param str name: OTP name
215+
:param str secret: OTP Secret
216+
"""
217+
otp = generate_otp(unix_time // 30, secret)
218+
print(name + " OTP output: ", otp)
219+
# display the key's name
220+
label_title.text = name
221+
# format and display the OTP
222+
label_key.text = "{} {}".format(str(otp)[0:3],str(otp)[3:6])
232223

233-
buttons = []
224+
def get_unix_time():
225+
"""Calculate current time based on NTP + monotonic
234226
235-
# generate buttons
236-
btn_x = 20
237-
for i in secrets['totp_keys']:
238-
print(i)
239-
button = Button(name=i[0], x=btn_x, y=130,
240-
width=60, height=60,
241-
label=i[0], label_font=font, label_color=0x0,
242-
fill_color=None, outline_color=None)
243-
buttons.append(button)
244-
btn_x+=60
245-
246-
# append buttons to splash group
247-
for b in buttons:
248-
splash.append(b.group)
227+
"""
228+
unix_time = t - mono_time + int(time.monotonic())
229+
return unix_time
249230

231+
# how long to stay on if not in always_on mode
232+
countdown = ON_SECONDS
233+
cur_otp = 0
234+
max_otp = len(secrets['totp_keys'])
250235

236+
display_otp(get_unix_time(), secrets['totp_keys'][cur_otp][0],
237+
secrets['totp_keys'][cur_otp][1])
251238

252-
countdown = ON_SECONDS # how long to stay on if not in always_on mode
253239
while ALWAYS_ON or (countdown > 0):
254-
# Calculate current time based on NTP + monotonic
255-
unix_time = t - mono_time + int(time.monotonic())
256240
p = ts.touch_point
257241
if p:
258-
for i, b in enumerate(buttons):
259-
if b.contains(p):
260-
b.selected = True
261-
for name, secret in secrets['totp_keys']:
262-
if b.name == name:
263-
# generate OTP
264-
#print('Background color: ', background_color)
265-
otp = generate_otp(unix_time // 30, secret)
266-
print('{} selected: '.format(name))
267-
print(name + " OTP output: ", otp)
268-
# display the key's name
269-
label_title.text = name
270-
# format and display the OTP
271-
label_key.text = "{} {}".format(str(otp)[0:3],str(otp)[3:6])
272-
else:
273-
b.selected = False
242+
if cur_otp < max_otp:
243+
display_otp(get_unix_time(), secrets['totp_keys'][cur_otp][0],
244+
secrets['totp_keys'][cur_otp][1])
245+
cur_otp+=1
246+
else:
247+
# reset the current otp display
248+
cur_otp = 0
274249
# We'll update every 1/4 second, we can hash very fast so its no biggie!
275250
countdown -= 0.25
276251
time.sleep(0.25)

0 commit comments

Comments
 (0)