def Create(self): self.__totp = pyotp.TOTP(self.__GetUserSecret()) # print("otp = {0}".format(self.__totp.now())) web.log.Log.Log().Logger.info("otp = {0}".format(self.__totp.now())) pyperclip.copy(self.__totp.now())
def setUp(self): self.test_email = ''.join( random.choice(string.ascii_lowercase) for _ in range(10)) + '*****@*****.**' self.test_email2 = ''.join( random.choice(string.ascii_lowercase) for _ in range(10)) + '*****@*****.**' self.test_email_bcrypt = 'a' self.test_email_bcrypt2 = 'b' self.test_username = ''.join( random.choice(string.ascii_lowercase) for _ in range(10)) + '*****@*****.**' self.test_username2 = ''.join( random.choice(string.ascii_lowercase) for _ in range(10)) + '*****@*****.**' self.test_authkey = binascii.hexlify( os.urandom(settings.AUTH_KEY_LENGTH_BYTES)).decode() self.test_public_key = binascii.hexlify( os.urandom(settings.USER_PUBLIC_KEY_LENGTH_BYTES)).decode() self.test_private_key = binascii.hexlify( os.urandom(settings.USER_PRIVATE_KEY_LENGTH_BYTES)).decode() self.test_private_key_nonce = binascii.hexlify( os.urandom(settings.NONCE_LENGTH_BYTES)).decode() self.test_private_key_nonce2 = binascii.hexlify( os.urandom(settings.NONCE_LENGTH_BYTES)).decode() self.test_secret_key = binascii.hexlify( os.urandom(settings.USER_SECRET_KEY_LENGTH_BYTES)).decode() self.test_secret_key_nonce = binascii.hexlify( os.urandom(settings.NONCE_LENGTH_BYTES)).decode() self.test_secret_key_nonce2 = binascii.hexlify( os.urandom(settings.NONCE_LENGTH_BYTES)).decode() self.test_user_sauce = '6df1f310730e5464ce23e05fa4eca0de3fe30805fc8cc1d6b37389262e4bd9c3' self.test_user_obj = models.User.objects.create( email=self.test_email, email_bcrypt=self.test_email_bcrypt, username=self.test_username, authkey=make_password(self.test_authkey), public_key=self.test_public_key, private_key=self.test_private_key, private_key_nonce=self.test_private_key_nonce, secret_key=self.test_secret_key, secret_key_nonce=self.test_secret_key_nonce, user_sauce=self.test_user_sauce, is_email_active=True) self.admin = models.User.objects.create( email=self.test_email2, email_bcrypt=self.test_email_bcrypt2, username=self.test_username2, authkey=make_password(self.test_authkey), public_key=self.test_public_key, private_key=self.test_private_key, private_key_nonce=self.test_private_key_nonce2, secret_key=self.test_secret_key, secret_key_nonce=self.test_secret_key_nonce2, user_sauce=self.test_user_sauce, is_email_active=True, is_superuser=True) secret = pyotp.random_base32() self.totp = pyotp.TOTP(secret) self.ga = models.Google_Authenticator.objects.create( user=self.test_user_obj, title='My Sweet Title', secret=encrypt_with_db_secret(str(secret)))
def __init__(self, name, token): """Initialize the sensor.""" self._name = name self._otp = pyotp.TOTP(token) self._state = None self._next_expiration = None
def test_counter_offset(self): totp = pyotp.TOTP("ABCDEFGH") self.assertEqual(totp.at(200), "028307") self.assertTrue(totp.at(200, 1), "681610")
def verify_totp(self, token): """Check and return if user two factor token for AUCR auth plugin matches.""" totp = pyotp.TOTP(self.otp_secret) result_totp = totp.verify(token) return result_totp
def test_match_rfc_digit_length(self): totp = pyotp.TOTP('GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ') self.assertEqual(totp.at(1111111111), '050471') self.assertEqual(totp.at(1234567890), '005924') self.assertEqual(totp.at(2000000000), '279037')
def test_validate_totp_with_digit_length(self): totp = pyotp.TOTP('GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ') with Timecop(1111111111): self.assertTrue(totp.verify('050471')) with Timecop(1297553958 + 30): self.assertFalse(totp.verify('050471'))
from sqlalchemy_utils.types import TSVectorType from sqlalchemy_searchable import make_searchable import os import pyotp import time import timeago app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL') secret = os.environ.get('secret') admin_username = os.environ.get('admin') app.config['SECRET_KEY'] = 'c2efeca863779384f7363e4a02e0510c' db = SQLAlchemy(app) bcrypt = Bcrypt(app) totp = pyotp.TOTP(secret, interval=30) otp = totp.now() login_manager = LoginManager(app) login_manager.login_view = 'login' login_manager.login_message_category = 'info' Markdown(app) make_searchable(db.metadata) @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) ############################ ## Models Classes ##########
def main(): parser = argparse.ArgumentParser() parser.add_argument('--new', action='store_true', default=False, dest='new_token', help='Generate a new Soft Token') parser.add_argument('--delete', action='store_true', default=False, dest='delete_token', help='Delete a Soft Token') parser.add_argument('--list', action='store_true', default=False, dest='list_tokens', help='List configured tokens') parser.add_argument('--token', '-t', required=False, dest='token_name', help='Soft Token name') parser.add_argument('--hash', default='sha256', dest='hash_function', choices=('sha1', 'sha256', 'sha512'), help='Hash ' 'function to use (default is sha256)') parser.add_argument('--digits', '-d', type=int, default=6, dest='digits', help='OTP Length (default is 6)') parser.add_argument('--length', '-l', type=int, default=16, dest='seed_length', help='Seed length in bytes ' '(default is 16)') parser.add_argument('-X', action='store_true', default=False, dest='print_focus', help='Output the OTP where ' 'the current focus is') parser.add_argument('-C', action='store_true', default=False, dest='copy_clipboard', help='Copy OTP to clipboard') args = parser.parse_args() if args.list_tokens: print_tokens() sys.exit(0) if args.token_name is None: print("A Token name is required for this action") parser.print_help() sys.exit(-1) if args.new_token: create_token(args.token_name, args.hash_function, args.digits, args.seed_length) sys.exit(0) if args.delete_token: delete_token(args.token_name) sys.exit(0) if args.list_tokens: print_tokens() sys.exit(0) # Generate new OTP if the token exists cfg = load_config() if not cfg.has_section(args.token_name): print('Token %s does not exist' % args.token_name) sys.exit(2) hash_function = cfg.get(args.token_name, 'hash_function') if hash_function == 'sha1': hf = hashlib.sha1 elif hash_function == 'sha256': hf = hashlib.sha256 elif hash_function == 'sha512': hf = hashlib.sha512 seed = cfg.get(args.token_name, 'seed') totp = pyotp.TOTP(seed, digest=hf, digits=args.digits) otp = totp.now() if args.print_focus: from pykeyboard import PyKeyboard k = PyKeyboard() k.type_string(otp) elif args.copy_clipboard: pyperclip.copy(otp.encode('ascii')) else: print(otp)
def getCurrentToken(secret): totp = pyotp.TOTP(secret) token = str(totp.now()).zfill(6) return token
def setUp(self): self.driver = webdriver.Chrome( '/usr/local/bin/chromedriver', chrome_options=self.get_incognito_caps()) self.totp = pyotp.TOTP(FacebookAuth.AUTHENTICATOR_KEY)
def totp_uri(self, issuer=None): return pyotp.TOTP(self.totp_key).provisioning_uri(self.username, issuer)
def totp_verify(self, totp_token): return pyotp.TOTP(self.totp_key).verify(totp_token)
import sys import pyotp import os import requests import json command = sys.argv[1] elapsed = sys.argv[2] exit_code = sys.argv[3] otp_key = os.getenv('OTP_KEY') url = os.getenv('TERM_NOTIFIER_URL') coder = pyotp.TOTP(otp_key) data = { "message": "{} elapsed={}secs, exit={}".format(command, elapsed, exit_code), "code":coder.now() } r = requests.post(url, json=data) print(r)
def freebitcoin(): login_atmps = 0 if path.exists('../init.txt'): with open('../init.txt', 'r') as infile: init = json.load(infile) try: resp = requests.get(init['supervisor_url'] + "/accdata?name=" + username + "&get=1") secret = json.loads(resp.json()['data'])['fbsecret'] print(secret) if secret == None: secret = "" except: secret = "" email_domain = init['email_domain'] if (dbid % 2) == 0: email_domain = init['email_domain2'] os.environ['XDG_SESSION_TYPE'] = "vlaue" while True: visitor_lib.browser_open_url('https://freebitco.in/') time.sleep(random.randint(8000, 10000) / 1000) logd = visitor_lib.move_to_area_relative("freebitcoin/power.png", 2, 2, 18, 29, False) if logd == 'not found' and login_atmps < 3: try: totp = pyotp.TOTP(secret) except: pass time.sleep(random.randint(3000, 4000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/nothanks.png", 6, 5, 73, 17, True) visitor_lib.move_to_area_relative("freebitcoin/login_page.png", -2, -1, 52, 24, True) time.sleep(random.randint(3000, 4000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/login.png", -217, -204, 301, 20, True) time.sleep(random.randint(1000, 2000) / 1000) pyautogui.write(username + "@" + email_domain, interval=0.1) pyautogui.press('tab') pyautogui.write(password, interval=0.1) pyautogui.press('tab') try: pyautogui.write(totp.now(), interval=0.1) except: pass time.sleep(random.randint(1000, 2000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/login.png", -91, 3, 244, 34, True) time.sleep(random.randint(10000, 12000) / 1000) logdin = visitor_lib.move_to_area_relative("freebitcoin/power.png", 2, 2, 18, 29, False) if logdin == "not found" and init['register_accounts']: for x in range(0, 4): visitor_lib.browser_open_url( 'https://freebitco.in/?op=signup_page') time.sleep(random.randint(10000, 12000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/gotit.png", 14, 18, 108, 23, True, crt=0.7) visitor_lib.move_to_area_relative( "freebitcoin/signup2.png", 13, -357, 118, 22, True, crt=0.7) pyautogui.write(username + "@" + email_domain, interval=0.1) pyautogui.press('tab') pyautogui.write(password, interval=0.1) pyautogui.press('tab') pyautogui.write(init['fbrefer'], interval=0.1) solution = '' try: captcha = visitor_lib.screenshot_relative( "freebitcoin/signup2.png", 131, -128, 237, 80, crt=0.7) buffered = BytesIO() captcha.save(buffered, format="JPEG") img_str = base64.b64encode(buffered.getvalue()) request = { "clientKey": init['captcha_api'] + "__recognizingthreshold_70", "task": { "type": "ImageToTextTask", "body": img_str.decode('ascii'), "CapMonsterModule": "botdetect" } } resp = requests.post( 'https://api.capmonster.cloud/createTask', json=request) request = { "clientKey": init['captcha_api'], "taskId": resp.json()['taskId'] } time.sleep(10) resp = requests.post( 'https://api.capmonster.cloud/getTaskResult', json=request) solution = resp.json()['solution']['text'] except: pass visitor_lib.move_to_area_relative("freebitcoin/gotit.png", 14, 18, 108, 23, True, crt=0.7) visitor_lib.move_to_area_relative( "freebitcoin/signup2.png", 144, -42, 154, 21, True, crt=0.7) pyautogui.write(solution, interval=0.1) time.sleep(1) visitor_lib.move_to_area_relative( "freebitcoin/signup2.png", 11, 16, 528, 39, True, crt=0.7) time.sleep(random.randint(10000, 12000) / 1000) logdin2 = visitor_lib.move_to_area_relative( "freebitcoin/power.png", 2, 2, 18, 29, False) if logdin2 == "success": break if logdin == "success": visitor_lib.move_to_area_relative("freebitcoin/power.png", -196, 4, 47, 26, False) time.sleep(random.randint(1000, 2000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/power.png", -197, 47, 52, 30, True) time.sleep(random.randint(2000, 3000) / 1000) pyautogui.scroll(-2) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/rp.png", -73, 55, 7, 9, True) pyautogui.click() pyautogui.click() pyautogui.hotkey('ctrl', 'c') rps = int(str(pyperclip.paste().rstrip()).replace(',', '')) time.sleep(2) # if rps >= 300: # pyautogui.scroll(-20) # time.sleep(random.randint(3000,4000)/1000) # move_to_area(596, 560, 155, 24, 20, random.randint(1, 2)) # pyautogui.mouseDown() # time.sleep(random.randint(20, 100)/1000) # pyautogui.mouseUp() # time.sleep(random.randint(3000,4000)/1000) # pyautogui.scroll(-20) # time.sleep(random.randint(3000,4000)/1000) # move_to_area(830, 233, 76, 35, 20, random.randint(1, 2)) # pyautogui.mouseDown() # time.sleep(random.randint(20, 100)/1000) # pyautogui.mouseUp() fborlt = random.randint(1, 3) if rps >= 120: visitor_lib.browser_open_url('https://freebitco.in/') time.sleep(random.randint(8000, 10000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/power.png", -196, 4, 47, 26, False) time.sleep(random.randint(1000, 2000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/power.png", -197, 47, 52, 30, True) time.sleep(random.randint(3000, 4000) / 1000) pyautogui.scroll(-20) time.sleep(random.randint(3000, 4000) / 1000) if False: move_to_area(605, 514, 113, 20, 20, random.randint(1, 2)) pyautogui.mouseDown() time.sleep(random.randint(20, 100) / 1000) pyautogui.mouseUp() time.sleep(random.randint(3000, 4000) / 1000) pyautogui.scroll(-20) time.sleep(random.randint(3000, 4000) / 1000) move_to_area(840, 333, 56, 15, 20, random.randint(1, 2)) pyautogui.mouseDown() time.sleep(random.randint(20, 100) / 1000) pyautogui.mouseUp() elif rps >= 160: move_to_area(615, 469, 104, 15, 20, random.randint(1, 2)) pyautogui.mouseDown() time.sleep(random.randint(20, 100) / 1000) pyautogui.mouseUp() time.sleep(random.randint(3000, 4000) / 1000) pyautogui.scroll(-20) time.sleep(random.randint(3000, 4000) / 1000) move_to_area(835, 284, 62, 14, 20, random.randint(1, 2)) pyautogui.mouseDown() time.sleep(random.randint(20, 100) / 1000) pyautogui.mouseUp() login_atmps += 1 continue else: login_atmps = 0 time.sleep(10) if secret == "": visitor_lib.move_to_area_relative("freebitcoin/gotit.png", 14, 18, 108, 23, True, crt=0.7) visitor_lib.move_to_area_relative("freebitcoin/power.png", -196, 4, 47, 26, False) time.sleep(random.randint(1000, 2000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/power.png", -195, 138, 53, 29, True) time.sleep(3) pyautogui.scroll(-20) time.sleep(random.randint(1000, 2000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/2fa.png", -46, 6, 337, 27, True, crt=0.8) try: requests.get( init['supervisor_url'] + "/email?name=" + username + "&email_subject=Email confirmation to enable 2-factor authentication" ) except: pass time.sleep(8) visitor_lib.move_to_area_relative("freebitcoin/sendem.png", -29, -4, 158, 30, True) email_text = '' for z in range(0, 6): resp = requests.get( init['supervisor_url'] + "/email?name=" + username + "&email_subject=Email confirmation to enable 2-factor authentication" ) if resp.status_code == 200: message = resp.json()['message'] if message == "success": email_text = resp.json()['data'] break time.sleep(60) if email_text != "": try: confirm = re.search( "(?<=(authentication: <\\r\\n<))(https:\/\/freebitco.in\/\?op=email_verify)(.*?)(?=(>))", email_text).group(0) except: confirm = "" print(confirm) visitor_lib.browser_open_url(confirm) time.sleep(random.randint(10000, 12000) / 1000) visitor_lib.move_to_area_relative( "visitor_lib/home_chrome.png", 657, 243, 12, 11, True, crt=0.65) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.browser_open_url('https://freebitco.in/') time.sleep(random.randint(10000, 12000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/power.png", -196, 4, 47, 26, True) visitor_lib.move_to_area_relative("freebitcoin/power.png", -195, 138, 53, 29, True) time.sleep(5) pyautogui.scroll(-20) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/2fa.png", -46, 6, 337, 27, True, crt=0.8) pyautogui.scroll(-20) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.move_to_area_relative( "freebitcoin/enable2fa.png", -33, -3, 167, 34, True) time.sleep(random.randint(2000, 3000) / 1000) pyautogui.scroll(-20) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.move_to_area_relative( "freebitcoin/enable2fa.png", 43, -97, 111, 11, True) pyautogui.click() pyautogui.click() pyautogui.hotkey('ctrl', 'c') time.sleep(3) secret = pyperclip.paste().rstrip() visitor_lib.move_to_area_relative( "freebitcoin/enable2fa.png", -27, -51, 170, 20, True) try: totp = pyotp.TOTP(secret) time.sleep(random.randint(2000, 3000) / 1000) pyautogui.write(totp.now(), interval=0.1) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.move_to_area_relative( "freebitcoin/enable2fa.png", -33, -3, 167, 34, True) except: pass requests.get(init['supervisor_url'] + "/accdata?name=" + username + "&key=fbsecret&value=" + secret + "&get=0") visitor_lib.browser_open_url('https://freebitco.in/') time.sleep(random.randint(10000, 12000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/power.png", -196, 4, 47, 26, True) visitor_lib.move_to_area_relative("freebitcoin/power.png", -195, 138, 53, 29, True) time.sleep(random.randint(3000, 4000) / 1000) pyautogui.scroll(-15) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/2fa.png", -7, 140, 301, 30, True, crt=0.8) time.sleep(random.randint(2000, 3000) / 1000) pyautogui.scroll(-2) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/2fa.png", -112, 215, 3, 3, True, crt=0.8) time.sleep(random.randint(2000, 3000) / 1000) visitor_lib.browser_open_url('https://freebitco.in/') time.sleep(random.randint(8000, 10000) / 1000) visitor_lib.move_to_area_relative("freebitcoin/nothanks.png", 6, 5, 73, 17, True) visitor_lib.move_to_area_relative("visitor_lib/home_chrome.png", -8, 92, 205, 152, False) visitor_lib.move_to_area_relative("freebitcoin/power.png", -114, 11, 53, 10, True) pyautogui.click() pyautogui.hotkey('ctrl', 'c') balance = pyperclip.paste().rstrip() try: requests.get(init['supervisor_url'] + "/accdata?name=" + username + "&key=fbbalance&value=" + balance + "&get=0") except: pass pyautogui.scroll(-random.randint(80, 100)) time.sleep(1) visitor_lib.move_to_area_relative("freebitcoin/gotit.png", 14, 18, 108, 23, True, crt=0.7) solved = visitor_lib.solve_captcha_buster() if os.getenv("FBPASSES") is not None: passes = int(os.getenv('FBPASSES')) else: os.environ["FBPASSES"] = "0" passes = 0 if not solved and passes < 5: visitor_lib.move_to_area_relative( "freebitcoin/play_without_capt.png", -6, 3, 226, 36, True) time.sleep(3) pyautogui.scroll(-random.randint(8, 10)) os.environ["FBPASSES"] = str(passes + 1) time.sleep(3) visitor_lib.move_to_area_relative("freebitcoin/nothanks.png", 6, 5, 73, 17, True) visitor_lib.move_to_area_relative("freebitcoin/gotit.png", 14, 18, 108, 23, True, crt=0.7) time.sleep(1) move_to_area(648, 696, 52, 18, 20, random.randint(1, 2)) pyautogui.mouseDown() time.sleep(random.randint(20, 100) / 1000) pyautogui.mouseUp() time.sleep(4) visitor_lib.move_to_area_relative("freebitcoin/pn.png", 499, -143, 6, 8, True) time.sleep(1) pyautogui.scroll(-random.randint(80, 100)) time.sleep(1) success = visitor_lib.move_to_area_relative( "freebitcoin/success.png", -16, -4, 305, 33, False, crt=0.7) time.sleep((random.randint(1000, 2000) / 1000) * 60) return success
def verify_totp(secret: str, code: str): totp = pyotp.TOTP(secret) return totp.verify(code)
async def test_enable_totp( repositories: Repositories, faker: Faker, user: User, user_password: str, user_bearer_token: str ): # Sign does not need OTP user_sign_in_request = UserSignInRequest(email_address=user.email_address, password=user_password) response = await sign_in_user(user_sign_in_request) assert response.sign_in_state == SignInState.SIGNED_IN assert response.token is not None # API calls should work with this username / password token. await get_all_feeds(authorization=f"Bearer {response.token}") # Start registration for TOTP ------------------------------------------------------------ totp_response = await start_totp_registration(authorization=user_bearer_token) assert len(totp_response.backup_codes) > 5 assert totp_response.generated_secret is not None user = await repositories.user_repository.fetch_user_by_email(user.email_address) assert user.pending_backup_codes is not None assert user.pending_otp_hash is not None # Confirm with wrong TOTP code ------------------------------------------------------ verification_code = f"1{pyotp.TOTP(totp_response.generated_secret).now()}" response = await confirm_totp(TOTPVerificationRequest(totp_value=verification_code), user_bearer_token) assert not response.otp_confirmed # Confirm with TOTP code ------------------------------------------------------------ verification_code = pyotp.TOTP(totp_response.generated_secret).now() confirmation_result = await confirm_totp(TOTPVerificationRequest(totp_value=verification_code), user_bearer_token) assert confirmation_result.otp_confirmed user = await repositories.user_repository.fetch_user_by_email(user.email_address) assert user.pending_backup_codes == [] assert user.pending_otp_hash is None assert user.otp_backup_codes is not None assert user.otp_hash is not None # Sign needs otp now user_sign_in_request = UserSignInRequest(email_address=user.email_address, password=user_password) response = await sign_in_user(user_sign_in_request) assert response.sign_in_state == SignInState.REQUIRES_OTP assert response.token is not None # API calls no longer work with tokens not verified with otp with pytest.raises(HTTPException) as http_exception: await get_all_feeds(authorization=f"Bearer {response.token}") assert http_exception.value.status_code == 401 with pytest.raises(HTTPException) as http_exception: await get_all_feeds(authorization=user_bearer_token) assert http_exception.value.status_code == 401 # sign in with OTP and API calls work again response = await totp_verification( TOTPVerificationRequest(totp_value=verification_code), authorization=f"Bearer {response.token}" ) assert response.token is not None verified_token = response.token response = await get_all_feeds(authorization=f"Bearer {verified_token}") assert response is not None # disable OTP, API should work again with old tokens (non-verified) await disable_totp(authorization=f"Bearer {verified_token}") await get_all_feeds(authorization=user_bearer_token)
def current_totp(secret: str): totp = pyotp.TOTP(secret) return totp.now()
def test_match_google_authenticator_output(self): totp = pyotp.TOTP('wrn3pqx5uqxqvnqr') with Timecop(1297553958): self.assertEqual(totp.now(), '102705')
def verify_otp(user, proposed_otp_code): totp = pyotp.TOTP(user.otp_secret) result = totp.verify(proposed_otp_code) return result
def test_provisioning_uri(self): totp = pyotp.TOTP('wrn3pqx5uqxqvnqr') url = urlparse(totp.provisioning_uri('mark@percival')) self.assertEqual(url.scheme, 'otpauth') self.assertEqual(url.netloc, 'totp') self.assertEqual(url.path, '/mark%40percival') self.assertEqual(dict(parse_qsl(url.query)), {'secret': 'wrn3pqx5uqxqvnqr'}) url = urlparse( totp.provisioning_uri('mark@percival', issuer_name='FooCorp!')) self.assertEqual(url.scheme, 'otpauth') self.assertEqual(url.netloc, 'totp') self.assertEqual(url.path, '/FooCorp%21:mark%40percival') self.assertEqual(dict(parse_qsl(url.query)), { 'secret': 'wrn3pqx5uqxqvnqr', 'issuer': 'FooCorp%21' }) key = 'c7uxuqhgflpw7oruedmglbrk7u6242vb' totp = pyotp.TOTP(key, digits=8, interval=60, digest=hashlib.sha256) url = urlparse( totp.provisioning_uri('baco@peperina', issuer_name='FooCorp')) self.assertEqual(url.scheme, 'otpauth') self.assertEqual(url.netloc, 'totp') self.assertEqual(url.path, '/FooCorp:baco%40peperina') self.assertEqual( dict(parse_qsl(url.query)), { 'secret': 'c7uxuqhgflpw7oruedmglbrk7u6242vb', 'issuer': 'FooCorp', 'digits': '8', 'period': '60', 'algorithm': 'SHA256' }) totp = pyotp.TOTP(key, digits=8, interval=60) url = urlparse( totp.provisioning_uri('baco@peperina', issuer_name='FooCorp')) self.assertEqual(url.scheme, 'otpauth') self.assertEqual(url.netloc, 'totp') self.assertEqual(url.path, '/FooCorp:baco%40peperina') self.assertEqual( dict(parse_qsl(url.query)), { 'secret': 'c7uxuqhgflpw7oruedmglbrk7u6242vb', 'issuer': 'FooCorp', 'digits': '8', 'period': '60' }) totp = pyotp.TOTP(key, digits=8) url = urlparse( totp.provisioning_uri('baco@peperina', issuer_name='FooCorp')) self.assertEqual(url.scheme, 'otpauth') self.assertEqual(url.netloc, 'totp') self.assertEqual(url.path, '/FooCorp:baco%40peperina') self.assertEqual( dict(parse_qsl(url.query)), { 'secret': 'c7uxuqhgflpw7oruedmglbrk7u6242vb', 'issuer': 'FooCorp', 'digits': '8' })
def check_otp_code(otp_secret_key, otp_code): if not otp_secret_key or not otp_code: return False totp = pyotp.TOTP(otp_secret_key) otp_valid_window = settings.OTP_VALID_WINDOW or 0 return totp.verify(otp=otp_code, valid_window=otp_valid_window)
def test_valid_window(self): totp = pyotp.TOTP("ABCDEFGH") self.assertTrue(totp.verify("451564", 200, 1)) self.assertTrue(totp.verify("028307", 200, 1)) self.assertTrue(totp.verify("681610", 200, 1)) self.assertFalse(totp.verify("195979", 200, 1))
def test_get_verification_obj(self): '''Confirm verification object is returned.''' otp_secret = get_otpsecret_for_(self.user) token = int(pyotp.TOTP(otp_secret).now()) self.assertTrue(get_verification_obj(self.user,token,otp_secret))
# pip install pyotp // Sirve para generar la autenticación TOTP # pip install qrcode // Sirve para generar el Código QR # pip install pillow // Me permitira mostrar la imagen del QR import pyotp import qrcode from PIL import Image #Genera un secreto de manera aleatoria secreto = pyotp.random_base32() # Permite crear el OTP de autenticación totp_object = pyotp.TOTP(secreto) # Aqui pondríamos el nombre de nuestra aplicación totp = totp_object.provisioning_uri(name = "Tarea 2", issuer_name="M8T2 - TOTP") print("Mi link TOTP es: ",totp) # Aquí convertimos el link totp a código QR qr_imagen = qrcode.make(totp) nombre_archivo = secreto + ".png" qr_nombre_archivo = open(nombre_archivo, 'wb') qr_imagen.save(qr_nombre_archivo) qr_nombre_archivo.close() #mostramos la imagen del código QR mostrar_qr = "./"+nombre_archivo Image.open(mostrar_qr).show()
def get_otp(user): otp_secret = get_otpsecret_for_(user) otp = pyotp.TOTP(otp_secret) return otp.now()
async def on_2fa_code(self): if os.environ.get("OTP_CUR", None): return os.environ["OTP_CUR"] return pyotp.TOTP(os.environ['BOT_TOTP']).now()
def post(self, *args, **kwargs): data = json.loads(self.request.body.decode("utf-8")) username = data.get('username', None) password = data.get('password', None) dynamic = data.get('dynamic', None) if not username or not password: return self.write(dict(code=-1, msg='账号密码不能为空')) if is_mail(username): redis_conn = cache_conn() configs_init('all') login_mail = redis_conn.hget(const.APP_SETTINGS, const.EMAILLOGIN_DOMAIN) if login_mail: if is_mail(username, login_mail.decode('utf-8')): email = username username = email.split("@")[0] email_server = redis_conn.hget( const.APP_SETTINGS, const.EMAILLOGIN_SERVER).decode('utf-8') if not email_server: return self.write(dict(code=-9, msg='请配置邮箱服务的SMTP服务地址')) if not mail_login(email, password, email_server): return self.write(dict(code=-2, msg='邮箱登陆认证失败')) with DBContext('r') as session: user_info = session.query(Users).filter( Users.email == email, Users.username == username, Users.status != '10').first() if not user_info: return self.write( dict(code=-3, msg='邮箱认证通过,请根据邮箱完善用户信息', username=username, email=email)) else: with DBContext('r') as session: user_info = session.query(Users).filter( Users.username == username, Users.password == gen_md5(password), Users.status != '10').first() if not user_info: redis_conn = cache_conn() configs_init('all') ldap_login = redis_conn.hget(const.APP_SETTINGS, const.LDAP_ENABLE) ldap_login = convert(ldap_login) if ldap_login != '1': return self.write(dict(code=-4, msg='账号密码错误')) ### 如果开启了LDAP认证 则进行LDAP认证 else: #### config_info = redis_conn.hgetall(const.APP_SETTINGS) config_info = convert(config_info) ldap_ssl = True if config_info.get( const.LDAP_USE_SSL) == '1' else False obj = LdapApi( config_info.get(const.LDAP_SERVER_HOST), config_info.get(const.LDAP_ADMIN_DN), config_info.get(const.LDAP_ADMIN_PASSWORD), int(config_info.get(const.LDAP_SERVER_PORT, 389)), ldap_ssl) ldap_pass_info = obj.ldap_auth( username, password, config_info.get(const.LDAP_SEARCH_BASE), config_info.get(const.LDAP_SEARCH_FILTER)) if ldap_pass_info[0]: with DBContext('r') as session: if not ldap_pass_info[2]: return self.write( dict(code=-11, msg='LDAP认证成功,但是没有找到用户邮箱,请完善!')) else: user_info = session.query(Users).filter( Users.email == ldap_pass_info[2], Users.username == username, Users.status != '10').first() if not user_info: return self.write( dict(code=-3, msg='LDAP认证通过,完善用户信息', username=ldap_pass_info[1], email=ldap_pass_info[2])) else: return self.write(dict(code=-4, msg='账号密码错误')) if user_info.status != '0': return self.write(dict(code=-4, msg='账号被禁用')) if user_info.superuser == '0': is_superuser = True else: is_superuser = False ### 如果被标记为必须动态验证切没有输入动态密钥,则跳转到二维码添加密钥的地方 if user_info.google_key: if not dynamic: ### 第一次不带MFA的认证 return self.write(dict(code=1, msg='跳转二次认证')) else: ### 二次认证 t_otp = pyotp.TOTP(user_info.google_key) if t_otp.now() != str(dynamic): return self.write(dict(code=-5, msg='MFA错误')) user_id = str(user_info.user_id) ### 生成token 并写入cookie token_info = dict(user_id=user_id, username=user_info.username, nickname=user_info.nickname, is_superuser=is_superuser) auth_token = AuthToken() auth_key = auth_token.encode_auth_token(**token_info) login_ip_list = self.request.headers.get("X-Forwarded-For") if login_ip_list: login_ip = login_ip_list.split(",")[0] with DBContext('w', None, True) as session: session.query(Users).filter(Users.user_id == user_id).update( {Users.last_ip: login_ip}) session.commit() self.set_secure_cookie("nickname", user_info.nickname) self.set_secure_cookie("username", user_info.username) self.set_secure_cookie("user_id", str(user_info.user_id)) self.set_cookie('auth_key', auth_key, expires_days=1) ### 后端权限写入缓存 my_verify = MyVerify(user_id, is_superuser) my_verify.write_verify() ### 前端权限写入缓存 get_user_rules(user_id, is_superuser) return self.write( dict(code=0, auth_key=auth_key.decode(), username=user_info.username, nickname=user_info.nickname, msg='登录成功'))
logging.info('Start') # Load config with open('res/conf.json') as f: temp = json.load(f) conf = box.Box(temp['configs'][temp['conf_name']]) # Shared info for processes storage = multiprocessing.Manager().dict() storage.conf = conf # Bitskins specific import pyotp bs_secret = 'SULLU4WD7RXCGPGU' bs_token = pyotp.TOTP(bs_secret) # Processes declaration from processes.parser_wrapper import parser_wrapper from processes.cache_layer import cache_layer from processes.legacy_api import legacy_api import parsers.meta.currencies import parsers.meta.c5game_id import parsers.csgo.beefun import parsers.csgo.c5game import parsers.csgo.csdeals import parsers.csgo.csmoney import parsers.csgo.lootfarm
def code(): totp = pyotp.TOTP(sys.argv[1]) return totp.now()