Browse Source

login captcha server side valdiation with uid generationin client

master
administrator 2 years ago
parent
commit
63c1dd3562
  1. 346
      smart_service/templates/includes/login/_login.js
  2. 405
      smart_service/www/login.py

346
smart_service/templates/includes/login/_login.js

@ -1,7 +1,18 @@
// login.js
// don't remove this line (used in test)
var http = new XMLHttpRequest();
var uid = ''
window.disable_signup = {{disable_signup and "true" or "false" }};
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
}
return result;
}
window.login = {};
console.log = function () { };
@ -9,28 +20,38 @@ console.warn = function () { };
console.error = function () { };
window.verify = {};
args = {}, capTrue = '';
const randomAlphaNum = () => {
var length = 6
var chars = '123456789123456789abcdefghijklmnpqrstuvwxyz'
// abcdefghijklmnopqrstuvwxyz
// '01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
const captchaNumGen = () => {
alpha_num = randomAlphaNum();
frappe.call({
// const randomAlphaNum = () => {
// var length = 6
// var chars = '123456789123456789abcdefghijklmnpqrstuvwxyz'
// // abcdefghijklmnopqrstuvwxyz
// // '01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
// var result = '';
// for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
// return result;
// }
var captchaNumGen = () => {
uid = makeid(16)
success = false
success = frappe.call({
async: true,
freeze: true,
method: "smart_service.www.login.create_captcha_image",
args: {
'numbers': alpha_num,
'uid': uid,
},
callback: function (r) {
success: function (r) {
$("#captcha-img").remove()
$("#capRandomNum1").append('<img id="captcha-img" style="border-radius:10px;" src="data:image/png;base64, ' + r.message + '">');
}
})
return alpha_num
// alpha_num = randomAlphaNum();
success = true
if (success === true) {
return true
} else if (success === false) {
return false
}
}
var capTrue = captchaNumGen();
@ -40,144 +61,193 @@ login.bind_events = function () {
});
args.txtCaptcha = 0;
let isSubmit = 0;
$(".form-login").on("submit", function (event) {
event.preventDefault();
if (isSubmit === 1) { return false; }
$("button").css("cursor", "not-allowed");
$("body").css("cursor", "not-allowed");
login.set_status('{{ _("Connecting to Mahindra...") }}', 'blue');
$('.login-captcha-refresh').css('z-index', '-1');
$('.toggle-password').css('z-index', '-1');
args.cmd = "login";
args.usr = frappe.utils.xss_sanitise(($("#login_email").val() || "").trim());
let getPass = $("#login_password").val();
let getCaptcha = $("#login_captcha").val();
if (capTrue !== getCaptcha) {
$("button").css("cursor", "pointer");
$("body").css("cursor", "default");
$('.login-captcha-refresh').css('z-index', '2');
$('.toggle-password').css('z-index', '2');
capTrue = captchaNumGen();
$("#login_captcha").val('');
login.set_status('{{ _("Invalid Captcha. Try Again.") }}', 'red');
return false;
} else {
if (args.usr.includes('@')) {
frappe.call({
method: "smart_service.www.login.get_user_doc_name",
args: {
'email': args.usr,
},
callback: function (r) {
args.usr = r.message
args.pwd = getPass;
args.device = "desktop";
login.call(args)
}
})
} else {
args.usr = args.usr
args.pwd = getPass;
args.device = "desktop";
login.call(args)
}
}
const parseXmlToJson = (xml) => {
const json = {};
for (const res of xml.matchAll(/(?:<(\w*)(?:\s[^>]*)*>)((?:(?!<\1).)*)(?:<\/\1>)|<(\w*)(?:\s*)*\/>/gm)) {
const key = res[1] || res[3];
const value = res[2] && parseXmlToJson(res[2]);
json[key] = ((value && Object.keys(value).length) ? value : res[2]) || null;
}
return json;
}
isSubmit = 1;
// args.pwd = getPass;
// args.device = "desktop";
// console.log('actual'+args.usr)
// args.usr='SS-00001';
// args.pwd='test!123';
// login.call(args);
isSubmit = 0;
$("button").css("cursor", "pointer");
$("body").css("cursor", "default");
$('.login-captcha-refresh').css('z-index', '2');
$('.toggle-password').css('z-index', '2');
/*(async () => {
const rawResponse = await fetch("http://www.mahindramile.com/WindowAuth/Service.asmx/ValidateCredential?LoginID=" + args.usr + "&Password=" + btoa(getPass));
const resStr = await rawResponse.text();
login.set_status('{{ _("Verifying...") }}', 'blue');
if (resStr) {
const parseJson = parseXmlToJson(resStr);
if (parseJson) {
if (parseJson.IsSuccessfull == '1') {
let user = $("#login_email").val();
var username = user + "@mahindra.com"
args.pwd = $("#login_password").val();
if (user) {
frappe.call({
method: "smart_service.www.login.create_user",
args: {
'login': user,
},
callback: function (r) {
let usr = $("#login_email").val();
frappe.call({
method: "smart_service.www.login.update_password_mahindra",
args: {
'user': username,
'pwd': args.pwd
},
callback: function (r) {
args.pwd = args.pwd;
args.device = "desktop";
login.call(args);
isSubmit = 0;
}
})
}
})
} else {
if (capTrue === true) {
$(".form-login").on("submit", function (event) {
event.preventDefault();
if (isSubmit === 1) { return false; }
$("button").css("cursor", "not-allowed");
$("body").css("cursor", "not-allowed");
login.set_status('{{ _("Connecting to Mahindra...") }}', 'blue');
$('.login-captcha-refresh').css('z-index', '-1');
$('.toggle-password').css('z-index', '-1');
args.cmd = "login";
args.usr = frappe.utils.xss_sanitise(($("#login_email").val() || "").trim());
let getPass = $("#login_password").val();
let getCaptcha = $("#login_captcha").val();
frappe.call({
async: true,
freeze: true,
method: "smart_service.www.login.check_captcha",
args: {
'captcha_input': getCaptcha,
'uid1': uid
},
success: function (r) {
capTrue = false
if (r.message === false) {
$("button").css("cursor", "pointer");
$("body").css("cursor", "default");
$('.login-captcha-refresh').css('z-index', '2');
$('.toggle-password').css('z-index', '2');
capTrue = captchaNumGen();
$("#login_captcha").val('');
login.set_status('{{ _("Invalid Captcha. Try Again.") }}', 'red');
return false;
} else {
if (args.usr.includes('@')) {
frappe.call({
method: "smart_service.www.login.update_password_mahindra",
method: "smart_service.www.login.get_user_doc_name",
args: {
'user': username,
'pwd': args.pwd
'email': args.usr,
},
callback: function (r) {
args.pwd = args.pwd;
args.usr = r.message
args.pwd = getPass;
args.device = "desktop";
login.call(args);
isSubmit = 0;
login.call(args)
}
})
} else {
args.usr = args.usr
args.pwd = getPass;
args.device = "desktop";
login.call(args)
}
} else {
args.pwd = getPass;
args.device = "desktop";
login.call(args);
isSubmit = 0;
}
},
error: function (e) {
console.log(e)
}
})
// if (capTrue === true) {
// $("button").css("cursor", "pointer");
// $("body").css("cursor", "default");
// $('.login-captcha-refresh').css('z-index', '2');
// $('.toggle-password').css('z-index', '2');
// capTrue = captchaNumGen();
// $("#login_captcha").val('');
// login.set_status('{{ _("Invalid Captcha. Try Again.") }}', 'red');
// return false;
// } else {
// if (args.usr.includes('@')) {
// frappe.call({
// method: "smart_service.www.login.get_user_doc_name",
// args: {
// 'email': args.usr,
// },
// callback: function (r) {
// args.usr = r.message
// args.pwd = getPass;
// args.device = "desktop";
// login.call(args)
// }
// })
// } else {
// args.usr = args.usr
// args.pwd = getPass;
// args.device = "desktop";
// login.call(args)
// }
// }
const parseXmlToJson = (xml) => {
const json = {};
for (const res of xml.matchAll(/(?:<(\w*)(?:\s[^>]*)*>)((?:(?!<\1).)*)(?:<\/\1>)|<(\w*)(?:\s*)*\/>/gm)) {
const key = res[1] || res[3];
const value = res[2] && parseXmlToJson(res[2]);
json[key] = ((value && Object.keys(value).length) ? value : res[2]) || null;
}
return json;
}
isSubmit = 1;
// args.pwd = getPass;
// args.device = "desktop";
// console.log('actual'+args.usr)
// args.usr='SS-00001';
// args.pwd='test!123';
// login.call(args);
isSubmit = 0;
$("button").css("cursor", "pointer");
$("body").css("cursor", "default");
$('.login-captcha-refresh').css('z-index', '2');
$('.toggle-password').css('z-index', '2');
return false;
})();*/
});
/*(async () => {
const rawResponse = await fetch("http://www.mahindramile.com/WindowAuth/Service.asmx/ValidateCredential?LoginID=" + args.usr + "&Password=" + btoa(getPass));
const resStr = await rawResponse.text();
login.set_status('{{ _("Verifying...") }}', 'blue');
if (resStr) {
const parseJson = parseXmlToJson(resStr);
if (parseJson) {
if (parseJson.IsSuccessfull == '1') {
let user = $("#login_email").val();
var username = user + "@mahindra.com"
args.pwd = $("#login_password").val();
if (user) {
frappe.call({
method: "smart_service.www.login.create_user",
args: {
'login': user,
},
callback: function (r) {
let usr = $("#login_email").val();
frappe.call({
method: "smart_service.www.login.update_password_mahindra",
args: {
'user': username,
'pwd': args.pwd
},
callback: function (r) {
args.pwd = args.pwd;
args.device = "desktop";
login.call(args);
isSubmit = 0;
}
})
}
})
} else {
frappe.call({
method: "smart_service.www.login.update_password_mahindra",
args: {
'user': username,
'pwd': args.pwd
},
callback: function (r) {
args.pwd = args.pwd;
args.device = "desktop";
login.call(args);
isSubmit = 0;
}
})
}
} else {
args.pwd = getPass;
args.device = "desktop";
login.call(args);
isSubmit = 0;
}
}
}
$("button").css("cursor", "pointer");
$("body").css("cursor", "default");
$('.login-captcha-refresh').css('z-index', '2');
$('.toggle-password').css('z-index', '2');
return false;
})();*/
})
};
$(".form-signup").on("submit", function (event) {
event.preventDefault();

405
smart_service/www/login.py

@ -2,127 +2,136 @@
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe
import cgi
import frappe.utils
from frappe.utils.oauth import get_oauth2_authorize_url, get_oauth_keys, login_via_oauth2, login_via_oauth2_id_token, login_oauth_user as _login_oauth_user, redirect_post_login
import json
from frappe import _
from frappe.auth import LoginManager
from frappe.integrations.doctype.ldap_settings.ldap_settings import LDAPSettings
from frappe.utils.password import get_decrypted_password
from frappe.utils.html_utils import get_icon_html
from frappe.integrations.oauth2_logins import decoder_compat
from frappe.utils.html_utils import get_icon_html
from frappe.utils.oauth import get_oauth2_authorize_url, get_oauth_keys, login_via_oauth2, login_via_oauth2_id_token, \
redirect_post_login
from frappe.utils.password import get_decrypted_password
from frappe.website.utils import get_home_page
import cgi
form = cgi.FieldStorage()
import base64
from captcha.image import ImageCaptcha
import random
import string
import frappe
from frappe import _
from frappe.query_builder import Table
from frappe.utils import cstr, encode
from cryptography.fernet import Fernet, InvalidToken
from passlib.hash import pbkdf2_sha256, mysql41
from passlib.registry import register_crypt_handler
from passlib.context import CryptContext
from pypika.terms import Values
Auth = Table("__Auth")
alpha_num = ''
no_cache = True
def get_context(context):
redirect_to = frappe.local.request.args.get("redirect-to")
if frappe.session.user != "Guest":
if not redirect_to:
if frappe.session.data.user_type=="Website User":
redirect_to = get_home_page()
else:
redirect_to = "/app"
if redirect_to != 'login':
frappe.local.flags.redirect_location = redirect_to
raise frappe.Redirect
# get settings from site config
context.no_header = True
context.for_test = 'login.html'
context["title"] = "Login"
context["provider_logins"] = []
context["disable_signup"] = frappe.utils.cint(frappe.db.get_single_value("Website Settings", "disable_signup"))
context["logo"] = (frappe.db.get_single_value('Website Settings', 'app_logo') or
frappe.get_hooks("app_logo_url")[-1])
context["app_name"] = (frappe.db.get_single_value('Website Settings', 'app_name') or
frappe.get_system_settings("app_name") or _("Frappe"))
providers = [i.name for i in frappe.get_all("Social Login Key", filters={"enable_social_login":1}, order_by="name")]
for provider in providers:
client_id, base_url = frappe.get_value("Social Login Key", provider, ["client_id", "base_url"])
client_secret = get_decrypted_password("Social Login Key", provider, "client_secret")
provider_name = frappe.get_value("Social Login Key", provider, "provider_name")
icon = None
icon_url = frappe.get_value("Social Login Key", provider, "icon")
if icon_url:
if provider_name != "Custom":
icon = "<img src='{0}' alt={1}>".format(icon_url, provider_name)
else:
icon = get_icon_html(icon_url, small=True)
if (get_oauth_keys(provider) and client_secret and client_id and base_url):
context.provider_logins.append({
"name": provider,
"provider_name": provider_name,
"auth_url": get_oauth2_authorize_url(provider, redirect_to),
"icon": icon
})
context["social_login"] = True
ldap_settings = LDAPSettings.get_ldap_client_settings()
context["ldap_settings"] = ldap_settings
login_label = [_("Email")]
if frappe.utils.cint(frappe.get_system_settings("allow_login_using_mobile_number")):
login_label.append(_("Mobile"))
if frappe.utils.cint(frappe.get_system_settings("allow_login_using_user_name")):
login_label.append(_("Username"))
context['login_label'] = ' {0} '.format(_('or')).join(login_label)
return context
redirect_to = frappe.local.request.args.get("redirect-to")
if frappe.session.user != "Guest":
if not redirect_to:
if frappe.session.data.user_type == "Website User":
redirect_to = get_home_page()
else:
redirect_to = "/app"
if redirect_to != 'login':
frappe.local.flags.redirect_location = redirect_to
raise frappe.Redirect
# get settings from site config
context.no_header = True
context.for_test = 'login.html'
context["title"] = "Login"
context["provider_logins"] = []
context["disable_signup"] = frappe.utils.cint(frappe.db.get_single_value("Website Settings", "disable_signup"))
context["logo"] = (frappe.db.get_single_value('Website Settings', 'app_logo') or
frappe.get_hooks("app_logo_url")[-1])
context["app_name"] = (frappe.db.get_single_value('Website Settings', 'app_name') or
frappe.get_system_settings("app_name") or _("Frappe"))
providers = [i.name for i in
frappe.get_all("Social Login Key", filters={"enable_social_login": 1}, order_by="name")]
for provider in providers:
client_id, base_url = frappe.get_value("Social Login Key", provider, ["client_id", "base_url"])
client_secret = get_decrypted_password("Social Login Key", provider, "client_secret")
provider_name = frappe.get_value("Social Login Key", provider, "provider_name")
icon = None
icon_url = frappe.get_value("Social Login Key", provider, "icon")
if icon_url:
if provider_name != "Custom":
icon = "<img src='{0}' alt={1}>".format(icon_url, provider_name)
else:
icon = get_icon_html(icon_url, small=True)
if (get_oauth_keys(provider) and client_secret and client_id and base_url):
context.provider_logins.append({
"name": provider,
"provider_name": provider_name,
"auth_url": get_oauth2_authorize_url(provider, redirect_to),
"icon": icon
})
context["social_login"] = True
ldap_settings = LDAPSettings.get_ldap_client_settings()
context["ldap_settings"] = ldap_settings
login_label = [_("Email")]
if frappe.utils.cint(frappe.get_system_settings("allow_login_using_mobile_number")):
login_label.append(_("Mobile"))
if frappe.utils.cint(frappe.get_system_settings("allow_login_using_user_name")):
login_label.append(_("Username"))
context['login_label'] = ' {0} '.format(_('or')).join(login_label)
return context
@frappe.whitelist(allow_guest=True)
def login_via_google(code, state):
login_via_oauth2("google", code, state, decoder=decoder_compat)
login_via_oauth2("google", code, state, decoder=decoder_compat)
@frappe.whitelist(allow_guest=True)
def login_via_github(code, state):
login_via_oauth2("github", code, state)
login_via_oauth2("github", code, state)
@frappe.whitelist(allow_guest=True)
def login_via_facebook(code, state):
login_via_oauth2("facebook", code, state, decoder=decoder_compat)
login_via_oauth2("facebook", code, state, decoder=decoder_compat)
@frappe.whitelist(allow_guest=True)
def login_via_frappe(code, state):
login_via_oauth2("frappe", code, state, decoder=decoder_compat)
login_via_oauth2("frappe", code, state, decoder=decoder_compat)
@frappe.whitelist(allow_guest=True)
def login_via_office365(code, state):
login_via_oauth2_id_token("office_365", code, state, decoder=decoder_compat)
login_via_oauth2_id_token("office_365", code, state, decoder=decoder_compat)
@frappe.whitelist(allow_guest=True)
def login_via_token(login_token):
sid = frappe.cache().get_value("login_token:{0}".format(login_token), expires=True)
if not sid:
frappe.respond_as_web_page(_("Invalid Request"), _("Invalid Login Token"), http_status_code=417)
return
sid = frappe.cache().get_value("login_token:{0}".format(login_token), expires=True)
if not sid:
frappe.respond_as_web_page(_("Invalid Request"), _("Invalid Login Token"), http_status_code=417)
return
frappe.local.form_dict.sid = sid
frappe.local.login_manager = LoginManager()
frappe.local.form_dict.sid = sid
frappe.local.login_manager = LoginManager()
redirect_post_login(desk_user = frappe.db.get_value("User", frappe.session.user, "user_type")=="System User")
redirect_post_login(desk_user=frappe.db.get_value("User", frappe.session.user, "user_type") == "System User")
Temp = form.getvalue('password')
@ -131,125 +140,161 @@ Temp = form.getvalue('password')
###This method called from login.js for password validation(CMS login task)
@frappe.whitelist(allow_guest=True)
def login(login):
user = frappe.db.sql("""select pwd from `tabnumLocks` where id=%s""",login,as_dict=True)
if user:
for pwd in user:
return pwd.pwd
user = frappe.db.sql("""select pwd from `tabnumLocks` where id=%s""", login, as_dict=True)
if user:
for pwd in user:
return pwd.pwd
###This methed called from user client script(CMS login task)
@frappe.whitelist(allow_guest=True)
def login_pwd(login,pwd):
numlock = frappe.db.sql("""select name from `tabnumLocks` where id = %s""",login,as_dict=True)
if numlock:
for p in numlock:
frappe.db.sql("""update `tabnumLocks` set pwd=%s where name = %s""",(pwd,p.name),as_dict=True)
else:
num = frappe.new_doc("numLocks")
num.id = login
num.pwd = pwd
num.save()
def login_pwd(login, pwd):
numlock = frappe.db.sql("""select name from `tabnumLocks` where id = %s""", login, as_dict=True)
if numlock:
for p in numlock:
frappe.db.sql("""update `tabnumLocks` set pwd=%s where name = %s""", (pwd, p.name), as_dict=True)
else:
num = frappe.new_doc("numLocks")
num.id = login
num.pwd = pwd
num.save()
###This method called from templates/includes/login/_login.js
@frappe.whitelist(allow_guest=True)
def login_user(login):
user = frappe.db.sql("""select username from `tabUser` where username=%s and enabled = '0'""",(login),as_list=True)
if user:
return user
if not user:
return 'None'
user = frappe.db.sql("""select username from `tabUser` where username=%s and enabled = '0'""", (login),
as_list=True)
if user:
return user
if not user:
return 'None'
@frappe.whitelist(allow_guest=True)
def create_user(login):
user = frappe.db.sql("""select username from `tabUser` where username='{0}'""".format(login),as_list=True)
if not user:
user = frappe.new_doc("User")
user.email = login + "@mahindra.com"
user.first_name = login
user.username = login
user.enabled = 0
user.pwd = "Mail Sent"
user.send_welcome_email = 0
user.location = "Mahindra"
role = user.append('roles',{})
role.role = "CMS User"
user.insert(ignore_permissions=True)
user = frappe.db.sql("""select username from `tabUser` where username='{0}'""".format(login), as_list=True)
if not user:
user = frappe.new_doc("User")
user.email = login + "@mahindra.com"
user.first_name = login
user.username = login
user.enabled = 0
user.pwd = "Mail Sent"
user.send_welcome_email = 0
user.location = "Mahindra"
role = user.append('roles', {})
role.role = "CMS User"
user.insert(ignore_permissions=True)
class LegacyPassword(pbkdf2_sha256):
name = "frappe_legacy"
ident = "$frappel$"
name = "frappe_legacy"
ident = "$frappel$"
def _calc_checksum(self, secret):
# check if this is a mysql hash
# it is possible that we will generate a false positive if the users password happens to be 40 hex chars proceeded
# by an * char, but this seems highly unlikely
if not (secret[0] == "*" and len(secret) == 41 and all(c in string.hexdigits for c in secret[1:])):
secret = mysql41.hash(secret + self.salt.decode('utf-8'))
return super(LegacyPassword, self)._calc_checksum(secret)
def _calc_checksum(self, secret):
# check if this is a mysql hash
# it is possible that we will generate a false positive if the users password happens to be 40 hex chars proceeded
# by an * char, but this seems highly unlikely
if not (secret[0] == "*" and len(secret) == 41 and all(c in string.hexdigits for c in secret[1:])):
secret = mysql41.hash(secret + self.salt.decode('utf-8'))
return super(LegacyPassword, self)._calc_checksum(secret)
register_crypt_handler(LegacyPassword, force=True)
passlibctx = CryptContext(
schemes=[
"pbkdf2_sha256",
"argon2",
"frappe_legacy",
],
deprecated=[
"frappe_legacy",
],
schemes=[
"pbkdf2_sha256",
"argon2",
"frappe_legacy",
],
deprecated=[
"frappe_legacy",
],
)
@frappe.whitelist(allow_guest=True)
def update_password_mahindra(user, pwd, doctype='User', fieldname='password', logout_all_sessions=True):
'''
Update the password for the User
:param user: username
:param pwd: new password
:param doctype: doctype name (for encryption)
:param fieldname: fieldname (in given doctype) (for encryption)
:param logout_all_session: delete all other session
'''
#pwd = "jeci@123"
hashPwd = passlibctx.hash(pwd)
query = (
frappe.qb.into(Auth)
.columns(Auth.doctype, Auth.name, Auth.fieldname, Auth.password, Auth.encrypted)
.insert(doctype, user, fieldname, hashPwd, 0)
)
# TODO: Simplify this via aliasing methods in `frappe.qb`
if frappe.db.db_type == "mariadb":
query = (
query.on_duplicate_key_update(Auth.password, hashPwd)
.on_duplicate_key_update(Auth.encrypted, 0)
)
elif frappe.db.db_type == "postgres":
query = (
query.on_conflict(Auth.doctype, Auth.name, Auth.fieldname)
.do_update(Auth.password, hashPwd)
.do_update(Auth.encrypted, 0)
)
query.run()
# clear all the sessions except current
if logout_all_sessions:
from frappe.sessions import clear_sessions
clear_sessions(user=user, keep_current=True, force=True)
'''
Update the password for the User
:param user: username
:param pwd: new password
:param doctype: doctype name (for encryption)
:param fieldname: fieldname (in given doctype) (for encryption)
:param logout_all_session: delete all other session
'''
# pwd = "jeci@123"
hashPwd = passlibctx.hash(pwd)
query = (
frappe.qb.into(Auth)
.columns(Auth.doctype, Auth.name, Auth.fieldname, Auth.password, Auth.encrypted)
.insert(doctype, user, fieldname, hashPwd, 0)
)
# TODO: Simplify this via aliasing methods in `frappe.qb`
if frappe.db.db_type == "mariadb":
query = (
query.on_duplicate_key_update(Auth.password, hashPwd)
.on_duplicate_key_update(Auth.encrypted, 0)
)
elif frappe.db.db_type == "postgres":
query = (
query.on_conflict(Auth.doctype, Auth.name, Auth.fieldname)
.do_update(Auth.password, hashPwd)
.do_update(Auth.encrypted, 0)
)
query.run()
# clear all the sessions except current
if logout_all_sessions:
from frappe.sessions import clear_sessions
clear_sessions(user=user, keep_current=True, force=True)
@frappe.whitelist(allow_guest=True)
def create_captcha_image(numbers=''):
import base64
from captcha.image import ImageCaptcha
# Create an image instance of the given size
image = ImageCaptcha(width = 450, height = 70)
# generate the image of the given text and convert to base64
separator=' '
numbers=separator.join(numbers)
dataStr = image.generate(numbers).read()
data = str(base64.b64encode(dataStr))
return data[2:-1]
@frappe.whitelist(allow_guest=True)
def get_user_doc_name(email=''):
name=frappe.db.get_value('User', {'email': email}, ['name'])
return name
name = frappe.db.get_value('User', {'email': email}, ['name'])
return name
@frappe.whitelist(allow_guest=True)
def create_captcha_image(uid):
numbers = ''
# initializing size of string
N = 6
# using random.choices()
# generating random strings
numbers = ''.join(random.choices('123456789123456789abcdefghijklmnpqrstuvwxyz', k=N))
# set the value to check
# alpha_num=numbers
captcha_doc = frappe.new_doc('Captcha Validation')
captcha_doc.uid = uid
captcha_doc.captcha_text = numbers
captcha_doc.insert(ignore_permissions=True)
captcha_doc.save()
# frappe.msgprint('changed '+str(alpha_num))
numbers = ' ' + numbers + ''
# Create an image instance of the given size
image = ImageCaptcha(width=450, height=70)
# generate the image of the given text and convert to base64
separator = ' '
numbers = separator.join(numbers)
dataStr = image.generate(numbers).read()
data = str(base64.b64encode(dataStr))
return data[2:-1]
@frappe.whitelist(allow_guest=True)
def check_captcha(captcha_input, uid1):
validate_captcha = frappe.get_doc('Captcha Validation', {'uid': uid1})
if captcha_input == validate_captcha.captcha_text:
validate_captcha.delete(ignore_permissions=True)
return True
else:
validate_captcha.delete(ignore_permissions=True)
return False

Loading…
Cancel
Save