Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def confirm_otp_token(login_manager, otp=None, tmp_id=None):
'''Confirm otp matches.'''
if not otp:
otp = frappe.form_dict.get('otp')
if not otp:
if two_factor_is_enabled_for_(login_manager.user):
return False
return True
if not tmp_id:
tmp_id = frappe.form_dict.get('tmp_id')
hotp_token = frappe.cache().get(tmp_id + '_token')
otp_secret = frappe.cache().get(tmp_id + '_otp_secret')
if not otp_secret:
raise ExpiredLoginException(_('Login session expired, refresh page to retry'))
hotp = pyotp.HOTP(otp_secret)
if hotp_token:
if hotp.verify(otp, int(hotp_token)):
frappe.cache().delete(tmp_id + '_token')
return True
else:
login_manager.fail(_('Incorrect Verification code'), login_manager.user)
totp = pyotp.TOTP(otp_secret)
if totp.verify(otp):
# show qr code only once
if not frappe.db.get_default(login_manager.user + '_otplogin'):
frappe.db.set_default(login_manager.user + '_otplogin', 1)
delete_qrimage(login_manager.user)
return True
else:
login_manager.fail(_('Incorrect Verification code'), login_manager.user)
def _generate_otp(secret: str, count: int) -> str:
"""Generate one time password."""
import pyotp
return str(pyotp.HOTP(secret).at(count))
def send_token_via_email(user, token, otp_secret, otp_issuer, subject=None, message=None):
'''Send token to user as email.'''
user_email = frappe.db.get_value('User', user, 'email')
if not user_email:
return False
hotp = pyotp.HOTP(otp_secret)
otp = hotp.at(int(token))
template_args = {'otp': otp, 'otp_issuer': otp_issuer}
if not subject:
subject = get_email_subject_for_2fa(template_args)
if not message:
message = get_email_body_for_2fa(template_args)
email_args = {
'recipients': user_email,
'sender': None,
'subject': subject,
'message': message,
'header': [_('Verfication Code'), 'blue'],
'delayed': False,
'retry':3
}
def generatePassword():
config = getConfig()
counter = getCounter()
hotp = pyotp.HOTP(base64.b32encode(config["hotp_secret"].encode()))
hotpPassword = hotp.at(counter)
if config.get("pin"):
password = "{},{}".format(config.get("pin"), hotpPassword)
else:
password = hotpPassword
setCounter(counter + 1)
return password
@frappe.whitelist(allow_guest=True)
def send_token_via_email(tmp_id,token=None):
import pyotp
user = frappe.cache().get(tmp_id + '_user')
count = token or frappe.cache().get(tmp_id + '_token')
if ((not user) or (user == 'None') or (not count)):
return False
user_email = frappe.db.get_value('User',user, 'email')
if not user_email:
return False
otpsecret = frappe.cache().get(tmp_id + '_otp_secret')
hotp = pyotp.HOTP(otpsecret)
frappe.sendmail(
recipients=user_email, sender=None, subject='Verification Code',
message='<p>Your verification code is {0}</p>'.format(hotp.at(int(count))),
delayed=False, retry=3)
return True
def set_otp(self, hash, selector=None, elem=None, otp_type='time', otp_index=1):
try:
import pyotp
except ImportError:
print("You must install pyotp to use `set_otp`.")
print("pip install pyotp")
return
if not elem:
elem = self.get_element(selector)
if otp_type == 'time':
otp = pyotp.TOTP(hash)
response = otp.now()
else:
otp = pyotp.HOTP(hash)
response = otp.at(otp_index)
self.set_value(selector, response, elem=elem)
def set_hotp(self, counter):
if isinstance(self.otp, pyotp.totp.TOTP):
logger.info('Switching into HOTP mode')
self.otp = pyotp.HOTP(self.otp.secret)
self.counter = counter
def send_token_via_sms(otpsecret, token=None, phone_no=None):
'''Send token as sms to user.'''
try:
from frappe.core.doctype.sms_settings.sms_settings import send_request
except:
return False
if not phone_no:
return False
ss = frappe.get_doc('SMS Settings', 'SMS Settings')
if not ss.sms_gateway_url:
return False
hotp = pyotp.HOTP(otpsecret)
args = {
ss.message_parameter: 'Your verification code is {}'.format(hotp.at(int(token)))
}
for d in ss.get("parameters"):
args[d.parameter] = d.value
args[ss.receiver_parameter] = phone_no
sms_args = {
'params': args,
'gateway_url': ss.sms_gateway_url,
'use_post': ss.use_post
}
enqueue(method=send_request, queue='short', timeout=300, event=None,
async=True, job_name=None, now=False, **sms_args)