Settings to send Qrcode as email to user
This commit is contained in:
parent
68251a6112
commit
dcee43f646
5 changed files with 92 additions and 11 deletions
|
|
@ -744,6 +744,38 @@
|
|||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.enable_two_factor_auth==1 && doc.two_factor_method == \"OTP App\" && doc.send_barcode_as_email==1",
|
||||
"description": "Time in seconds to retain barcode image on server. Min:<strong>240</strong>",
|
||||
"fieldname": "lifespan_barcode_image",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Delete Barcode Image On server",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -968,7 +1000,7 @@
|
|||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.two_factor_method == \"OTP App\"",
|
||||
"depends_on": "eval:doc.enable_two_factor_auth==1 && doc.two_factor_method == \"OTP App\"",
|
||||
"fieldname": "send_barcode_as_email",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
|
|
@ -1125,7 +1157,7 @@
|
|||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-26 18:31:27.992012",
|
||||
"modified": "2017-07-27 12:23:01.135841",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "System Settings",
|
||||
|
|
|
|||
|
|
@ -128,7 +128,8 @@ scheduler_events = {
|
|||
"frappe.email.doctype.email_account.email_account.pull",
|
||||
"frappe.email.doctype.email_account.email_account.notify_unreplied",
|
||||
"frappe.oauth.delete_oauth2_data",
|
||||
"frappe.integrations.doctype.razorpay_settings.razorpay_settings.capture_payment"
|
||||
"frappe.integrations.doctype.razorpay_settings.razorpay_settings.capture_payment",
|
||||
"frappe.twofactor.delete_all_barcodes_for_users"
|
||||
],
|
||||
"hourly": [
|
||||
"frappe.model.utils.link_count.update_link_count",
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ login.login_handlers = (function() {
|
|||
}
|
||||
|
||||
//OTP verification
|
||||
if(data.verification) {
|
||||
if(data.verification && data.message != 'Logged In') {
|
||||
login.set_indicator("{{ _("Success") }}", 'green');
|
||||
|
||||
document.cookie = "tmp_id="+data.tmp_id;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from frappe.utils.background_jobs import enqueue
|
|||
from pyqrcode import create as qrcreate
|
||||
from StringIO import StringIO
|
||||
from base64 import b64encode,b32encode
|
||||
from frappe.utils import get_url, get_datetime, time_diff_in_seconds
|
||||
|
||||
|
||||
class ExpiredLoginExpection(Exception):pass
|
||||
|
|
@ -114,7 +115,8 @@ def confirm_otp_token(login_manager,otp=None,tmp_id=None):
|
|||
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)
|
||||
# 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)
|
||||
|
|
@ -168,8 +170,8 @@ def process_2fa_for_email(user,token,otp_secret,otp_issuer,method='email'):
|
|||
if method == 'otp_app' and not frappe.db.get_default(user + '_otplogin'):
|
||||
totp_uri = pyotp.TOTP(otp_secret).provisioning_uri(user, issuer_name=otp_issuer)
|
||||
message = '''<p>Please scan the barcode for One Time Password</p>
|
||||
<img src="data:image/svg+xml;base64{}"
|
||||
style':'width:250px;height:250px;>'''.format(get_qr_svg_code(totp_uri))
|
||||
<img src="{}"
|
||||
style':'width:150px;height:150px;>'''.format(qrcode_as_png(user,totp_uri))
|
||||
if method == 'email' or message:
|
||||
status = send_token_via_email(user,token,otp_secret,otp_issuer,message=message)
|
||||
verification_obj = {'token_delivery': status,
|
||||
|
|
@ -227,10 +229,6 @@ def should_send_barcode_as_email():
|
|||
return True
|
||||
return False
|
||||
|
||||
def send_barcode_as_email(user,svg_code):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def get_qr_svg_code(totp_uri):
|
||||
'''Get SVG code to display Qrcode for OTP.'''
|
||||
|
|
@ -245,7 +243,56 @@ def get_qr_svg_code(totp_uri):
|
|||
stream.close()
|
||||
return svg
|
||||
|
||||
def qrcode_as_png(user,totp_uri):
|
||||
'''Save temporary Qrcode to server.'''
|
||||
from frappe.utils.file_manager import save_file
|
||||
folder = create_barcode_folder()
|
||||
png_file_name = '{}.png'.format(frappe.generate_hash(length=20))
|
||||
file_obj = save_file(png_file_name,png_file_name,'User',user,folder=folder)
|
||||
frappe.db.commit()
|
||||
file_url = get_url(file_obj.file_url)
|
||||
file_path = os.path.join(frappe.get_site_path('public', 'files'),file_obj.file_name)
|
||||
url = qrcreate(totp_uri)
|
||||
with open(file_path,'w') as png_file:
|
||||
url.png(png_file,scale=8, module_color=[0, 0, 0, 180], background=[0xff, 0xff, 0xcc])
|
||||
return file_url
|
||||
|
||||
def create_barcode_folder():
|
||||
'''Get Barcodes folder.'''
|
||||
folder_name = 'Barcodes'
|
||||
folder = frappe.db.exists('File',{'file_name':folder_name})
|
||||
if folder:
|
||||
return folder
|
||||
folder = frappe.get_doc({
|
||||
'doctype':'File',
|
||||
'file_name':folder_name,
|
||||
'is_folder':1,
|
||||
'folder':'Home'
|
||||
})
|
||||
folder.insert(ignore_permissions=True)
|
||||
return folder.name
|
||||
|
||||
def delete_qrimage(user,check_expiry=False):
|
||||
'''Delete Qrimage when user logs in.'''
|
||||
user_barcodes = frappe.get_all('File',{'attached_to_doctype':'User',
|
||||
'attached_to_name':user,'folder':'Home/Barcodes'})
|
||||
for barcode in user_barcodes:
|
||||
if check_expiry and not should_remove_barcode_image(barcode):continue
|
||||
barcode = frappe.get_doc('File',barcode.name)
|
||||
frappe.delete_doc('File',barcode.name,ignore_permissions=True)
|
||||
|
||||
def delete_all_barcodes_for_users():
|
||||
'''Task to delete all barcodes for user.'''
|
||||
users = frappe.get_all('User',{'enabled':1})
|
||||
for user in users:
|
||||
delete_qrimage(user.name,check_expiry=True)
|
||||
|
||||
def should_remove_barcode_image(barcode):
|
||||
'''Check if it's time to delete barcode image from server. '''
|
||||
if isinstance(barcode, basestring):
|
||||
barcode = frappe.get_doc('File',barcode)
|
||||
lifespan = frappe.db.get_value('System Settings', 'System Settings', 'lifespan_barcode_image')
|
||||
if time_diff_in_seconds(get_datetime(),barcode.creation) > int(lifespan):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -43,5 +43,6 @@ pypdf
|
|||
openpyxl
|
||||
pyotp
|
||||
pyqrcode
|
||||
pypng
|
||||
premailer
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue