diff --git a/js/legacy/model/doclist.js b/js/legacy/model/doclist.js
index e38d9b9b55..33638a4fbe 100644
--- a/js/legacy/model/doclist.js
+++ b/js/legacy/model/doclist.js
@@ -26,7 +26,9 @@ function compress_doclist(list) {
var o = list[i];
var fl = [];
if(!kl[o.doctype]) { // make key only once # doctype must be first
- var tfl = ['doctype', 'name', 'docstatus', 'owner', 'parent', 'parentfield', 'parenttype', 'idx', 'creation', 'modified', 'modified_by', '__islocal', '__newname', '__modified', '_user_tags']; // for text
+ var tfl = ['doctype', 'name', 'docstatus', 'owner', 'parent', 'parentfield', 'parenttype',
+ 'idx', 'creation', 'modified', 'modified_by', '__islocal', '__newname', '__modified',
+ '_user_tags', '__temp'];
var fl = [].concat(tfl);
for(key in wn.meta.docfield_map[o.doctype]) { // all other values
diff --git a/js/legacy/widgets/form/fields.js b/js/legacy/widgets/form/fields.js
index 3a6db8586b..7c9c7928c7 100644
--- a/js/legacy/widgets/form/fields.js
+++ b/js/legacy/widgets/form/fields.js
@@ -298,9 +298,9 @@ Field.prototype.set = function(val) {
this.docname = this.grid.add_newrow(); // new row
}
- var set_val = val;
- if(this.validate)set_val = this.validate(val);
- _f.set_value(this.doctype, this.docname, this.df.fieldname, set_val);
+ if(this.validate)
+ val = this.validate(val);
+ cur_frm.set_value_in_locals(this.doctype, this.docname, this.df.fieldname, val);
this.value = val; // for return
}
@@ -513,9 +513,9 @@ ReadOnlyField.prototype = new Field();
function HTMLField() { }
HTMLField.prototype = new Field();
HTMLField.prototype.with_label = 0;
-HTMLField.prototype.set_disp = function(val) { this.disp_area.innerHTML = val; }
+HTMLField.prototype.set_disp = function(val) { if(this.disp_area) this.disp_area.innerHTML = val; }
HTMLField.prototype.set_input = function(val) { if(val) this.set_disp(val); }
-HTMLField.prototype.onrefresh = function() { this.set_disp(this.df.options?this.df.options:''); }
+HTMLField.prototype.onrefresh = function() { if(this.df.options) this.set_disp(this.df.options); }
// ======================================================================================
diff --git a/js/legacy/widgets/form/form.js b/js/legacy/widgets/form/form.js
index b0ca86b7f1..efb436e1a7 100644
--- a/js/legacy/widgets/form/form.js
+++ b/js/legacy/widgets/form/form.js
@@ -838,7 +838,7 @@ _f.Frm.prototype.save = function(save_action, call_back) {
} else { // no validation for cancellation
validated = true;
if(this.cscript.validate)
- this.runclientscript('validate', this.doctype, this.docname);
+ this.runclientscript('validate');
if(!validated) {
this.savingflag = false;
@@ -1090,43 +1090,26 @@ _f.get_value = function(dt, dn, fn) {
return locals[dt][dn][fn];
}
-_f.set_value = function(dt, dn, fn, v) {
+_f.Frm.prototype.set_value_in_locals = function(dt, dn, fn, v) {
var d = locals[dt][dn];
-
- if(!d) {
- console.log('_f.set_value - '+ fn+': "'+dt+','+dn+'" not found');
- return;
- }
-
var changed = d[fn] != v;
- if(changed && (d[fn]==null || v==null) && (cstr(d[fn])==cstr(v))) changed = 0;
+ if(changed && (d[fn]==null || v==null) && (cstr(d[fn])==cstr(v)))
+ changed = false;
if(changed) {
- //console.log('value changed for ' + dt + ', ' + dn + ', ' + fn)
-
- var prev_unsaved = d.__unsaved
d[fn] = v;
- d.__unsaved = 1;
-
- if(d.parent && d.parenttype) {
- var doc = locals[d.parenttype][d.parent];
- doc.__unsaved = 1;
- var frm = wn.views.formview[d.parenttype].frm;
- } else {
- var doc = locals[d.doctype][d.name]
- doc.__unsaved = 1;
- var frm = wn.views.formview[d.doctype] && wn.views.formview[d.doctype].frm;
- }
-
- // No need to refresh labels and toolbar again and again.
- // Just check if __unsaved was not set previously
- if(frm && frm==cur_frm && frm.frm_head && !prev_unsaved) {
- frm.frm_head.refresh_labels();
- //frm.frm_head.refresh_toolbar();
- }
+ if(d.parenttype)
+ d.__unsaved = 1;
+ this.set_unsaved();
}
}
+_f.Frm.prototype.set_unsaved = function() {
+ if(cur_frm.doc.__unsaved) return;
+ cur_frm.doc.__unsaved = 1;
+ cur_frm.frm_head.refresh_labels()
+}
+
_f.Frm.prototype.show_comments = function() {
if(!cur_frm.comments) {
cur_frm.comments = new Dialog(540, 400, 'Comments');
diff --git a/js/legacy/widgets/form/form_grid.js b/js/legacy/widgets/form/form_grid.js
index bac0439fca..148da1d46b 100644
--- a/js/legacy/widgets/form/form_grid.js
+++ b/js/legacy/widgets/form/form_grid.js
@@ -138,8 +138,7 @@ _f.FormGrid.prototype.refresh = function() {
_f.FormGrid.prototype.set_unsaved = function() {
// set unsaved
- locals[cur_frm.doctype][cur_frm.docname].__unsaved=1;
- cur_frm.frm_head && cur_frm.frm_head.refresh_labels();
+ cur_frm.set_unsaved();
}
_f.FormGrid.prototype.insert_row = function() {
@@ -155,7 +154,6 @@ _f.FormGrid.prototype.insert_row = function() {
// refresh
this.refresh();
this.cell_select('', row_idx, ci);
- this.set_unsaved();
}
_f.FormGrid.prototype.new_row_doc = function() {
@@ -165,6 +163,7 @@ _f.FormGrid.prototype.new_row_doc = function() {
d.parent = this.field.frm.docname;
d.parentfield = this.field.df.fieldname;
d.parenttype = this.field.frm.doctype;
+ this.set_unsaved();
return d;
}
_f.FormGrid.prototype.add_newrow = function() {
diff --git a/py/core/doctype/profile/profile.py b/py/core/doctype/profile/profile.py
index 123027fa8a..22ab5adc02 100644
--- a/py/core/doctype/profile/profile.py
+++ b/py/core/doctype/profile/profile.py
@@ -20,25 +20,16 @@
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-# Please edit this list and import only required elements
-import webnotes
+import webnotes, json
+from webnotes.utils import cint
-from webnotes import msgprint
-
-sql = webnotes.conn.sql
-
-# -----------------------------------------------------------------------------------------
-
-
class DocType:
def __init__(self, doc, doclist):
self.doc = doc
self.doclist = doclist
-
- # Autoname is Email id
- # --------------------
def autoname(self):
+ """set name as email id"""
import re
from webnotes.utils import validate_email_add
@@ -49,12 +40,81 @@ class DocType:
raise Exception
self.doc.name = self.doc.email
+
+ def validate(self):
+ self.validate_max_users()
+ self.update_roles()
+ self.logout_if_disabled()
+
+ def logout_if_disabled(self):
+ """logout if disabled"""
+ if cint(self.doc.disabled):
+ import webnotes.login_manager
+ webnotes.login_manager.logout(self.doc.name)
+ def validate_max_users(self):
+ """don't allow more than max users if set in conf"""
+ import conf
+ if hasattr(conf, 'max_users'):
+ active_users = webnotes.conn.sql("""select count(*) from tabProfile
+ where ifnull(enabled, 0)=1 and docstatus<2
+ and name not in ('Administrator', 'Guest')""")[0][0]
+ if active_users >= conf.max_users and conf.max_users:
+ webnotes.msgprint("""
+ You already have %(active_users)s active users, \
+ which is the maximum number that you are currently allowed to add.
\
+ So, to add more users, you can:
\
+ 1. Upgrade to the unlimited users plan, or
\
+ 2. Disable one or more of your existing users and try again""" \
+ % {'active_users': active_users}, raise_exception=1)
+
+ def update_roles(self):
+ """update roles if set"""
+ if self.doc.fields.get('__temp'):
+ roles = json.loads(self.doc.fields['__temp'])
+ del self.doc.fields['__temp']
+
+ # remove roles
+ webnotes.conn.sql("""delete from tabUserRole where parent='%s'
+ and role in ('%s')""" % (self.doc.name, "','".join(roles['unset_roles'])))
+
+ self.check_one_system_manager()
+
+ # add roles
+ user_roles = webnotes.get_roles(self.doc.name)
+ for role in roles['set_roles']:
+ if not role in user_roles:
+ self.add_role(role)
+
+ def add_role(self, role):
+ """add role to Profile"""
+ from webnotes.model.doc import Document
+ d = Document('UserRole')
+ d.role = role
+ d.parenttype = 'Profile'
+ d.parentfield = 'user_roles'
+ d.parent = self.doc.name
+ d.save()
+
+ def check_one_system_manager(self):
+ if not webnotes.conn.sql("""select parent from tabUserRole where role='System Manager'
+ and docstatus<2"""):
+ webnotes.msgprint("""Cannot un-select as System Manager as there must
+ be atleast one 'System Manager'""", raise_exception=1)
+
def on_update(self):
# owner is always name
- if not self.doc.password:
- webnotes.conn.set(self.doc, 'password' ,'password')
webnotes.conn.set(self.doc, 'owner' ,self.doc.name)
+ self.update_new_password()
+
+ def update_new_password(self):
+ """update new password if set"""
+ if self.doc.new_password:
+ webnotes.conn.sql("""insert into __Auth (user, `password`) values (%s, password(%s))
+ on duplicate key update `password`=password(%s)""", (self.doc.name,
+ self.doc.new_password, self.doc.new_password))
+ webnotes.conn.set(self.doc, 'new_password', '')
+ webnotes.msgprint("Password updated.")
def get_fullname(self):
return (self.doc.first_name or '') + \
@@ -75,4 +135,60 @@ class DocType:
(tab[0], field, '%s', field, '%s'), (newdn, olddn))
webnotes.conn.sql("""\
update `tabProfile` set email=%s
- where name=%s""", (newdn, newdn))
\ No newline at end of file
+ where name=%s""", (newdn, newdn))
+
+@webnotes.whitelist()
+def get_all_roles(arg=None):
+ """return all roles"""
+ return [r[0] for r in webnotes.conn.sql("""select name from tabRole
+ where name not in ('Administrator', 'Guest', 'All') order by name""")]
+
+@webnotes.whitelist()
+def get_user_roles(arg=None):
+ """get roles for a user"""
+ return webnotes.get_roles(webnotes.form_dict['uid'])
+
+@webnotes.whitelist()
+def get_perm_info(arg=None):
+ """get permission info"""
+ return webnotes.conn.sql("""select parent, permlevel, `read`, `write`, submit,
+ cancel, amend from tabDocPerm where role=%s
+ and docstatus<2 order by parent, permlevel""",
+ webnotes.form_dict['role'], as_dict=1)
+
+def send_welcome_mail(email, args):
+ """send welcome mail to user with password and login url"""
+ pr = Document('Profile', email)
+ from webnotes.utils.email_lib import sendmail_md
+ args.update({
+ 'company': webnotes.conn.get_default('company'),
+ 'password': args.get('password'),
+ 'account_url': webnotes.conn.get_value('Website Settings',
+ 'Website Settings', 'subdomain') or ""
+ })
+ if not args.get('last_name'): args['last_name'] = ''
+ sendmail_md(pr.email, subject="Welcome to ERPNext", msg=welcome_txt % args)
+
+@webnotes.whitelist()
+def delete(arg=None):
+ """delete user"""
+ webnotes.conn.sql("update tabProfile set enabled=0, docstatus=2 where name=%s",
+ webnotes.form_dict['uid'])
+ webnotes.login_manager.logout(user=webnotes.form_dict['uid'])
+
+welcome_txt = """
+## %(company)s
+
+Dear %(first_name)s %(last_name)s
+
+Welcome!
+
+A new account has been created for you, here are your details:
+
+login-id: %(user)s
+password: %(password)s
+
+To login to your new ERPNext account, please go to:
+
+%(account_url)s
+"""
\ No newline at end of file
diff --git a/py/core/doctype/profile/profile.txt b/py/core/doctype/profile/profile.txt
index 35d8e8338b..5af90dbfbb 100644
--- a/py/core/doctype/profile/profile.txt
+++ b/py/core/doctype/profile/profile.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-05-03 18:43:24',
+ 'creation': '2012-07-03 13:30:35',
'docstatus': 0,
- 'modified': '2012-05-24 12:30:06',
+ 'modified': '2012-07-13 14:20:39',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -19,12 +19,14 @@
'allow_print': 0,
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'Profile Represents a User in the system.',
'doctype': 'DocType',
+ 'document_type': u'System',
'hide_heading': 0,
'hide_toolbar': 0,
'issingle': 0,
'istable': 0,
- 'max_attachments': 1,
+ 'max_attachments': 5,
'module': u'Core',
'name': '__common__',
'print_outline': u'Yes',
@@ -62,7 +64,7 @@
# DocPerm
{
- 'cancel': 0,
+ 'cancel': 1,
'create': 1,
'doctype': u'DocPerm',
'execute': 0,
@@ -74,6 +76,7 @@
# DocPerm
{
+ 'cancel': 1,
'create': 1,
'doctype': u'DocPerm',
'permlevel': 0,
@@ -83,6 +86,7 @@
# DocPerm
{
+ 'cancel': 0,
'doctype': u'DocPerm',
'permlevel': 1,
'role': u'Administrator',
@@ -91,10 +95,20 @@
# DocPerm
{
+ 'cancel': 0,
'doctype': u'DocPerm',
+ 'match': u'owner',
'permlevel': 0,
- 'role': u'All',
- 'write': 0
+ 'role': u'All'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'sb0',
+ 'fieldtype': u'Section Break',
+ 'label': u'Profile Details',
+ 'permlevel': 0
},
# DocField
@@ -112,20 +126,8 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'password',
- 'fieldtype': u'Password',
- 'hidden': 1,
- 'label': u'Password',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'registered',
- 'fieldtype': u'Check',
- 'hidden': 1,
- 'label': u'Registered',
+ 'fieldname': u'sb0_5',
+ 'fieldtype': u'Section Break',
'permlevel': 0
},
@@ -153,6 +155,22 @@
'search_index': 0
},
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Id of the profile will be the email.',
+ 'doctype': u'DocField',
+ 'fieldname': u'email',
+ 'fieldtype': u'Data',
+ 'hidden': 0,
+ 'label': u'Email',
+ 'oldfieldname': u'email',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'search_index': 0
+ },
+
# DocField
{
'doctype': u'DocField',
@@ -187,19 +205,6 @@
'permlevel': 0
},
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'gender',
- 'fieldtype': u'Select',
- 'label': u'Gender',
- 'oldfieldname': u'gender',
- 'oldfieldtype': u'Select',
- 'options': u'\nMale\nFemale',
- 'permlevel': 0,
- 'search_index': 0
- },
-
# DocField
{
'doctype': u'DocField',
@@ -212,41 +217,26 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'Set a new password.',
'doctype': u'DocField',
- 'fieldname': u'email',
- 'fieldtype': u'Data',
+ 'fieldname': u'new_password',
+ 'fieldtype': u'Password',
'hidden': 0,
- 'label': u'Email',
- 'oldfieldname': u'email',
- 'oldfieldtype': u'Data',
+ 'label': u'New Password',
'permlevel': 0,
- 'reqd': 1,
- 'search_index': 0
+ 'print_hide': 1
},
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'bio',
- 'fieldtype': u'Text',
+ 'fieldname': u'password',
+ 'fieldtype': u'Password',
'hidden': 1,
- 'label': u'Bio',
- 'oldfieldname': u'bio',
- 'oldfieldtype': u'Text',
- 'permlevel': 0,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'interests',
- 'fieldtype': u'Text',
- 'hidden': 1,
- 'label': u'Interests',
- 'oldfieldname': u'interests',
- 'oldfieldtype': u'Text',
- 'permlevel': 0
+ 'label': u'Password',
+ 'permlevel': 1,
+ 'print_hide': 1
},
# DocField
@@ -260,30 +250,6 @@
'permlevel': 0
},
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'activities',
- 'fieldtype': u'Text',
- 'hidden': 1,
- 'label': u'Activities',
- 'oldfieldname': u'activities',
- 'oldfieldtype': u'Text',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'messanger_status',
- 'fieldtype': u'Data',
- 'label': u'Messanger Status',
- 'oldfieldname': u'messanger_status',
- 'oldfieldtype': u'Data',
- 'permlevel': 0,
- 'search_index': 0
- },
-
# DocField
{
'doctype': u'DocField',
@@ -299,21 +265,42 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'section_break0',
+ 'fieldname': u'gender',
+ 'fieldtype': u'Select',
+ 'label': u'Gender',
+ 'oldfieldname': u'gender',
+ 'oldfieldtype': u'Select',
+ 'options': u'\nMale\nFemale\nOther',
+ 'permlevel': 0,
+ 'search_index': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Check / Uncheck roles assigned to the Profile. To find out what permissions the Role has, click on the "?" icon.',
+ 'doctype': u'DocField',
+ 'fieldname': u'sb1',
'fieldtype': u'Section Break',
- 'hidden': 0,
- 'oldfieldtype': u'Section Break',
- 'permlevel': 1,
- 'reqd': 0,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'roles',
- 'fieldtype': u'Column Break',
'label': u'Roles',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'roles_html',
+ 'fieldtype': u'HTML',
+ 'label': u'Roles HTML',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'sb2',
+ 'fieldtype': u'Section Break',
+ 'label': u'User Defaults',
'oldfieldtype': u'Column Break',
'permlevel': 1,
'width': u'50%'
@@ -324,41 +311,12 @@
'colour': u'White:FFF',
'default': u'Simple',
'doctype': u'DocField',
- 'fieldname': u'userroles',
- 'fieldtype': u'Table',
+ 'fieldname': u'defaults_html',
+ 'fieldtype': u'HTML',
'hidden': 0,
- 'label': u'User Roles',
- 'oldfieldname': u'userroles',
- 'oldfieldtype': u'Table',
- 'options': u'UserRole',
- 'permlevel': 1,
- 'reqd': 0,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'system_defaults',
- 'fieldtype': u'Column Break',
- 'label': u'System Defaults',
- 'oldfieldtype': u'Column Break',
- 'permlevel': 1,
- 'width': u'50%'
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'default': u'Simple',
- 'doctype': u'DocField',
- 'fieldname': u'defaults',
- 'fieldtype': u'Table',
- 'hidden': 0,
- 'label': u'Defaults',
+ 'label': u'Defaults HTML',
'oldfieldname': u'defaults',
'oldfieldtype': u'Table',
- 'options': u'DefaultValue',
'permlevel': 1,
'reqd': 0,
'search_index': 0
@@ -367,24 +325,17 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'login_details',
+ 'fieldname': u'sb3',
'fieldtype': u'Section Break',
- 'label': u'Login Details',
+ 'label': u'Security Settings',
'oldfieldtype': u'Section Break',
'permlevel': 1
},
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'login_before',
- 'fieldtype': u'Int',
- 'label': u'Login Before',
- 'permlevel': 1
- },
-
- # DocField
- {
+ 'colour': u'White:FFF',
+ 'description': u'Allow user to login only after this hour (0-24)',
'doctype': u'DocField',
'fieldname': u'login_after',
'fieldtype': u'Int',
@@ -394,6 +345,19 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'Allow user to login only before this hour (0-24)',
+ 'doctype': u'DocField',
+ 'fieldname': u'login_before',
+ 'fieldtype': u'Int',
+ 'label': u'Login Before',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Restrict user from this IP address only. Multiple IP addresses can be added by separating with commas. Also accepts partial IP addresses like (111.111.111)',
'doctype': u'DocField',
'fieldname': u'restrict_ip',
'fieldtype': u'Data',
diff --git a/py/core/doctype/userrole/userrole.txt b/py/core/doctype/userrole/userrole.txt
index 31d8c96f68..f8dc30b261 100644
--- a/py/core/doctype/userrole/userrole.txt
+++ b/py/core/doctype/userrole/userrole.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:39',
+ 'creation': '2012-07-03 13:30:34',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:39',
+ 'modified': '2012-07-13 12:25:07',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -21,13 +21,14 @@
'hide_heading': 0,
'hide_toolbar': 0,
'issingle': 0,
- 'istable': 1,
+ 'istable': 0,
'module': u'Core',
'name': '__common__',
'read_only': 0,
'section_style': u'Simple',
'server_code_error': u' ',
- 'show_in_menu': 0
+ 'show_in_menu': 0,
+ 'version': 1
},
# These values are common for all DocField
diff --git a/py/webnotes/__init__.py b/py/webnotes/__init__.py
index 1ae6d36956..acfbd4f0d2 100644
--- a/py/webnotes/__init__.py
+++ b/py/webnotes/__init__.py
@@ -218,7 +218,7 @@ def clear_cache(user=None):
from webnotes.session_cache import clear
clear(user)
-def get_roles(user=None):
+def get_roles(user=None, with_standard=True):
"""get roles of current user"""
if not user:
user = session['user']
@@ -226,5 +226,11 @@ def get_roles(user=None):
if user=='Guest':
return ['Guest']
- return [r[0] for r in conn.sql("""select distinct role from tabUserRole
+ roles = [r[0] for r in conn.sql("""select role from tabUserRole
where parent=%s and role!='All'""", user)] + ['All']
+
+ # filter standard if required
+ if not with_standard:
+ roles = filter(lambda x: x not in ['All', 'Guest', 'Administrator'], roles)
+
+ return roles
diff --git a/py/webnotes/auth.py b/py/webnotes/auth.py
index d37cba3f60..3d871c1dcd 100644
--- a/py/webnotes/auth.py
+++ b/py/webnotes/auth.py
@@ -107,7 +107,6 @@ class HTTPRequest:
class LoginManager:
def __init__(self):
- self.cp = None
if webnotes.form_dict.get('cmd')=='login':
# clear cache
from webnotes.session_cache import clear_cache
@@ -132,45 +131,31 @@ class LoginManager:
if not (user and pwd):
user, pwd = webnotes.form_dict.get('usr'), webnotes.form_dict.get('pwd')
if not (user and pwd):
- webnotes.response['message'] = 'Incomplete Login Details'
- raise webnotes.AuthenticationError
- # custom authentication (for single-sign on)
- self.load_control_panel()
- if hasattr(self.cp, 'authenticate'):
- self.user = self.cp.authenticate()
+ self.fail('Incomplete login details')
- # check the password
- if user=='Administrator':
- p = webnotes.conn.sql("""select name, first_name, last_name
- from tabProfile where name=%s
- and (`password`=%s OR `password`=PASSWORD(%s))""", (user, pwd, pwd), as_dict=1)
+ self.check_if_enabled(user)
+ self.user = self.check_password(user, pwd)
+
+ def check_if_enabled(self, user):
+ """raise exception if user not enabled"""
+ if user=='Administrator': return
+ if not int(webnotes.conn.get_value('Profile', user, 'enabled')):
+ self.fail('User disabled or missing')
+
+ def check_password(self, user, pwd):
+ """check password"""
+ user = webnotes.conn.sql("""select `user` from __Auth where `user`=%s
+ and `password`=password(%s)""", (user, pwd))
+ if not user:
+ self.fail('Incorrect password')
else:
- p = webnotes.conn.sql("""select name, first_name, last_name
- from tabProfile where name=%s
- and (`password`=%s OR `password`=PASSWORD(%s))
- and IFNULL(enabled,0)=1""", (user, pwd, pwd), as_dict=1)
- if not p:
- webnotes.response['message'] = 'Authentication Failed'
- raise webnotes.AuthenticationError
- #webnotes.msgprint('Authentication Failed',raise_exception=1)
-
- p = p[0]
- self.user = p['name']
- self.user_fullname = (p.get('first_name') and (p.get('first_name') + ' ') or '') \
- + (p.get('last_name') or '')
+ return user[0][0] # in correct case
- # triggers
- # --------
+ def fail(self, message):
+ webnotes.response['message'] = message
+ raise webnotes.AuthenticationError
+
- def load_control_panel(self):
- import webnotes.model.code
- try:
- if not self.cp:
- self.cp = webnotes.model.code.get_obj('Control Panel')
- except Exception, e:
- webnotes.response['Control Panel Exception'] = webnotes.utils.getTraceback()
-
- # --------
def run_trigger(self, method='on_login'):
try:
from startup import event_handlers
@@ -180,15 +165,8 @@ class LoginManager:
except ImportError, e:
pass
- # deprecated
- self.load_control_panel()
- if self.cp and hasattr(self.cp, method):
- getattr(self.cp, method)(self)
-
- # ip validation
- # -------------
-
def validate_ip_address(self):
+ """check if IP Address is valid"""
ip_list = webnotes.conn.get_value('Profile', self.user, 'restrict_ip', ignore=True)
if not ip_list:
@@ -205,9 +183,7 @@ class LoginManager:
raise webnotes.AuthenticationError
def validate_hour(self):
- """
- check if user is logging in during restricted hours
- """
+ """check if user is logging in during restricted hours"""
login_before = int(webnotes.conn.get_value('Profile', self.user, 'login_before', ignore=True) or 0)
login_after = int(webnotes.conn.get_value('Profile', self.user, 'login_after', ignore=True) or 0)
@@ -222,28 +198,17 @@ class LoginManager:
if login_after and current_hour < login_after:
webnotes.msgprint('Not allowed to login before restricted hour', raise_exception=1)
-
- # login as guest
- # --------------
def login_as_guest(self):
+ """login as guest"""
self.user = 'Guest'
self.post_login()
- # Logout
- # ------
-
- def call_on_logout_event(self):
- import webnotes.model.code
- cp = webnotes.model.code.get_obj('Control Panel', 'Control Panel')
- if hasattr(cp, 'on_logout'):
- cp.on_logout(self)
-
def logout(self, arg='', user=None):
if not user: user = webnotes.session.get('user')
self.user = user
self.run_trigger('on_logout')
- if user=='demo@webnotestech.com':
+ if user in ['demo@erpnext.com', 'Administrator']:
webnotes.conn.sql('delete from tabSessions where sid=%s', webnotes.session.get('sid'))
else:
webnotes.conn.sql('delete from tabSessions where user=%s', user)
@@ -258,8 +223,6 @@ class CookieManager:
webnotes.cookies = Cookie.SimpleCookie()
self.get_incoming_cookies()
- # get incoming cookies
- # --------------------
def get_incoming_cookies(self):
import os
cookies = {}
@@ -271,9 +234,6 @@ class CookieManager:
webnotes.incoming_cookies = cookies
- # Set cookies
- # -----------
-
def set_cookies(self):
if webnotes.session.get('sid'):
webnotes.cookies['sid'] = webnotes.session['sid']
@@ -284,9 +244,6 @@ class CookieManager:
webnotes.cookies['sid']['expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S')
webnotes.cookies['sid']['path'] = '/'
- # Set Remember Me
- # ---------------
-
def set_remember_me(self):
if webnotes.utils.cint(webnotes.form_dict.get('remember_me')):
remember_days = webnotes.conn.get_value('Control Panel',None,'remember_for_days') or 7
diff --git a/py/webnotes/install_lib/install.py b/py/webnotes/install_lib/install.py
index fa513958f8..f6adadfb15 100755
--- a/py/webnotes/install_lib/install.py
+++ b/py/webnotes/install_lib/install.py
@@ -98,6 +98,7 @@ class Installer:
self.create_scheduler_log()
self.create_session_cache()
self.create_cache_item()
+ self.create_auth_table()
# set the basic passwords
webnotes.conn.begin()
@@ -134,7 +135,7 @@ class Installer:
webnotes.conn.sql("""create table `__SessionCache` (
user VARCHAR(120),
country VARCHAR(120),
- cache LONGTEXT)""")
+ cache LONGTEXT) ENGINE=InnoDB""")
def create_cache_item(self):
import webnotes
@@ -143,7 +144,12 @@ class Installer:
`key` VARCHAR(180) NOT NULL PRIMARY KEY,
`value` LONGTEXT,
`expires_on` DATETIME
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8""")
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8""")
-
-
+ def create_auth_table(self):
+ import webnotes
+ self.dbman.drop_table('__Auth')
+ webnotes.conn.sql("""create table __Auth(
+ `user` VARCHAR(180) NOT NULL PRIMARY KEY,
+ `password` VARCHAR(180) NOT NULL
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8""")