From c71bdcc7a1960dd92cbc8a6f749ba6738ff279c7 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 7 Jan 2014 09:11:50 +0530 Subject: [PATCH] login and other fixes --- webnotes/__init__.py | 4 +- webnotes/auth.py | 61 +++++++++------- .../core/doctype/custom_field/custom_field.js | 11 +-- webnotes/core/doctype/docperm/docperm.txt | 4 +- webnotes/core/doctype/doctype/doctype.py | 8 ++- webnotes/core/doctype/profile/profile.py | 14 ++-- webnotes/db.py | 1 - webnotes/handler.py | 2 +- webnotes/sessions.py | 70 +++++++++---------- webnotes/utils/nestedset.py | 7 +- webnotes/webutils.py | 21 ++---- webnotes/widgets/search.py | 2 +- 12 files changed, 109 insertions(+), 96 deletions(-) diff --git a/webnotes/__init__.py b/webnotes/__init__.py index 7646f3065a..7e8c8d95c0 100644 --- a/webnotes/__init__.py +++ b/webnotes/__init__.py @@ -283,10 +283,10 @@ def reset_perms(doctype): reload_doc(conn.get_value("DocType", doctype, "module"), "DocType", doctype, force=True) -def generate_hash(): +def generate_hash(txt=None): """Generates random hash for session id""" import hashlib, time - return hashlib.sha224(str(time.time())).hexdigest() + return hashlib.sha224((txt or "") + str(time.time())).hexdigest() def reset_metadata_version(): v = generate_hash() diff --git a/webnotes/auth.py b/webnotes/auth.py index 4490576159..e0bc737c6c 100644 --- a/webnotes/auth.py +++ b/webnotes/auth.py @@ -34,10 +34,6 @@ class HTTPRequest: # login webnotes.local.login_manager = LoginManager() - # start session - webnotes.local.session_obj = Session() - webnotes.local.session = webnotes.local.session_obj.data - # check status if webnotes.conn.get_global("__session_status")=='stop': webnotes.msgprint(webnotes.conn.get_global("__session_status_message")) @@ -50,9 +46,6 @@ class HTTPRequest: if webnotes.form_dict.get('cmd')=='login': webnotes.local.login_manager.run_trigger('on_session_creation') - # write out cookies - webnotes.local.cookie_manager.set_cookies() - def set_lang(self, lang): import translate lang_list = translate.get_all_languages() or [] @@ -93,29 +86,47 @@ class HTTPRequest: class LoginManager: def __init__(self): + self.user = None if webnotes.form_dict.get('cmd')=='login': - # clear cache - webnotes.clear_cache(user = webnotes.form_dict.get('usr')) - - self.authenticate() - self.post_login() - info = webnotes.conn.get_value("Profile", self.user, ["user_type", "first_name", "last_name"], as_dict=1) - if info.user_type=="Website User": - webnotes._response.set_cookie("system_user", "no") - webnotes.response["message"] = "No App" - else: - webnotes._response.set_cookie("system_user", "yes") - webnotes.response['message'] = 'Logged In' - - full_name = " ".join(filter(None, [info.first_name, info.last_name])) - webnotes.response["full_name"] = full_name - webnotes._response.set_cookie("full_name", full_name) - webnotes._response.set_cookie("user_id", self.user) + self.login() + else: + self.make_session(resume=True) + + def login(self): + # clear cache + webnotes.clear_cache(user = webnotes.form_dict.get('usr')) + self.authenticate() + self.post_login() def post_login(self): self.run_trigger('on_login') self.validate_ip_address() self.validate_hour() + self.make_session() + self.set_user_info() + + def set_user_info(self): + info = webnotes.conn.get_value("Profile", self.user, + ["user_type", "first_name", "last_name"], as_dict=1) + if info.user_type=="Website User": + webnotes._response.set_cookie("system_user", "no") + webnotes.response["message"] = "No App" + else: + webnotes._response.set_cookie("system_user", "yes") + webnotes.response['message'] = 'Logged In' + + full_name = " ".join(filter(None, [info.first_name, info.last_name])) + webnotes.response["full_name"] = full_name + webnotes._response.set_cookie("full_name", full_name) + webnotes._response.set_cookie("user_id", self.user) + + def make_session(self, resume=False): + # start session + webnotes.local.session_obj = Session(user=self.user, resume=resume) + + # reset user if changed to Guest + self.user = webnotes.local.session_obj.user + webnotes.local.session = webnotes.local.session_obj.data def authenticate(self, user=None, pwd=None): if not (user and pwd): @@ -214,7 +225,7 @@ class CookieManager: pass def set_cookies(self): - if not webnotes.session.get('sid'): return + if not webnotes.local.session.get('sid'): return import datetime # sid expires in 3 days diff --git a/webnotes/core/doctype/custom_field/custom_field.js b/webnotes/core/doctype/custom_field/custom_field.js index e8233b5236..3de09e0ba9 100644 --- a/webnotes/core/doctype/custom_field/custom_field.js +++ b/webnotes/core/doctype/custom_field/custom_field.js @@ -36,12 +36,13 @@ cur_frm.cscript.label = function(doc){ cur_frm.fields_dict['dt'].get_query = function(doc, dt, dn) { - return{ - filters:[ - ['DocType', 'issingle', '=', 0], - ['DocType', 'module', '!=', 'Core'] - ] + filters = [ + ['DocType', 'issingle', '=', 0], + ]; + if(user!=="Administrator") { + filters.push(['DocType', 'module', '!=', 'Core']) } + return filters } cur_frm.cscript.fieldtype = function(doc, dt, dn) { diff --git a/webnotes/core/doctype/docperm/docperm.txt b/webnotes/core/doctype/docperm/docperm.txt index c237ad58cc..505e186ad8 100644 --- a/webnotes/core/doctype/docperm/docperm.txt +++ b/webnotes/core/doctype/docperm/docperm.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-22 01:27:33", "docstatus": 0, - "modified": "2013-12-20 19:23:11", + "modified": "2014-01-04 22:26:35", "modified_by": "Administrator", "owner": "Administrator" }, @@ -56,7 +56,7 @@ "oldfieldtype": "Link", "options": "Role", "print_width": "150px", - "reqd": 0, + "reqd": 1, "search_index": 0, "width": "150px" }, diff --git a/webnotes/core/doctype/doctype/doctype.py b/webnotes/core/doctype/doctype/doctype.py index 7fa5368f94..66e36d989e 100644 --- a/webnotes/core/doctype/doctype/doctype.py +++ b/webnotes/core/doctype/doctype/doctype.py @@ -16,6 +16,8 @@ class DocType: self.doclist = doclist def validate(self): + if not webnotes.conf.get("developer_mode"): + webnotes.throw("Not in Developer Mode! Set in site_config.json") for c in [".", "/", "#", "&", "=", ":", "'", '"']: if c in self.doc.name: webnotes.msgprint(c + " not allowed in name", raise_exception=1) @@ -183,7 +185,7 @@ def validate_fields(fields): raise_exception=1) if d.options=="[Select]": return - if not webnotes.conn.exists("DocType", d.options): + if d.options != d.parent and not webnotes.conn.exists("DocType", d.options): webnotes.msgprint("""#%(idx)s %(label)s: Options %(options)s must be a valid "DocType" for Link and Table type fields""" % d.fields, raise_exception=1) @@ -226,13 +228,13 @@ def validate_permissions_for_doctype(doctype, for_remove=False): def validate_permissions(permissions, for_remove=False): doctype = permissions and permissions[0].parent issingle = issubmittable = isimportable = False - if doctype: + if doctype and not doctype.startswith("New DocType"): values = webnotes.conn.get_value("DocType", doctype, ["issingle", "is_submittable", "allow_import"], as_dict=True) issingle = cint(values.issingle) issubmittable = cint(values.is_submittable) isimportable = cint(values.allow_import) - + def get_txt(d): return "For %s (level %s) in %s, row #%s:" % (d.role, d.permlevel, d.parent, d.idx) diff --git a/webnotes/core/doctype/profile/profile.py b/webnotes/core/doctype/profile/profile.py index 8c00402967..dd65292819 100644 --- a/webnotes/core/doctype/profile/profile.py +++ b/webnotes/core/doctype/profile/profile.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import webnotes, json from webnotes.utils import cint, now, cstr from webnotes import _ +from webnotes.auth import _update_password class DocType: def __init__(self, doc, doclist): @@ -29,13 +30,18 @@ class DocType: self.check_enable_disable() if self.in_insert: if self.doc.name not in ("Guest", "Administrator"): - self.send_welcome_mail() - webnotes.msgprint(_("Welcome Email Sent")) + if self.doc.new_password: + # new password given, no email required + _update_password(self.doc.name, self.doc.new_password) + else: + self.send_welcome_mail() + webnotes.msgprint(_("Welcome Email Sent")) else: self.email_new_password() - + self.doc.new_password = "" + def check_enable_disable(self): # do not allow disabling administrator/guest if not cint(self.doc.enabled) and self.doc.name in ["Administrator", "Guest"]: @@ -86,7 +92,6 @@ class DocType: def email_new_password(self): if self.doc.new_password and not self.in_insert: - from webnotes.auth import _update_password _update_password(self.doc.name, self.doc.new_password) self.password_update_mail(self.doc.new_password) @@ -330,7 +335,6 @@ def update_password(new_password, key=None, old_password=None): and user=%s""", (old_password, user)): return _("Cannot Update: Incorrect Password") - from webnotes.auth import _update_password _update_password(user, new_password) webnotes.conn.set_value("Profile", user, "reset_password_key", "") diff --git a/webnotes/db.py b/webnotes/db.py index b6e08c8eaa..f31ddcf8f4 100644 --- a/webnotes/db.py +++ b/webnotes/db.py @@ -160,7 +160,6 @@ class Database: if not webnotes.flags.in_test and self.transaction_writes > 10000: if self.auto_commit_on_many_writes: webnotes.conn.commit() - webnotes.conn.begin() else: webnotes.msgprint('A very long query was encountered. If you are trying to import data, please do so using smaller files') raise Exception, 'Bad Query!!! Too many writes' diff --git a/webnotes/handler.py b/webnotes/handler.py index f6c07df87e..73cd9b435f 100755 --- a/webnotes/handler.py +++ b/webnotes/handler.py @@ -169,7 +169,7 @@ def print_json(): make_logs() cleanup_docs() - webnotes._response.headers["Content-Type"] = "text/html; charset: utf-8" + webnotes._response.headers["Content-Type"] = "text/json; charset: utf-8" import json diff --git a/webnotes/sessions.py b/webnotes/sessions.py index ef5b800e2c..ae619cb187 100644 --- a/webnotes/sessions.py +++ b/webnotes/sessions.py @@ -8,8 +8,9 @@ Boot session from cache or build Session bootstraps info needed by common client side activities including permission, homepage, control panel variables, system defaults etc """ +import webnotes, os, json import webnotes -import json +import webnotes.utils from webnotes.utils import cint import webnotes.model.doctype import webnotes.defaults @@ -89,49 +90,49 @@ def get(): return bootinfo class Session: - def __init__(self, user=None): - self.user = user + def __init__(self, user, resume=False): self.sid = webnotes.form_dict.get('sid') or webnotes.request.cookies.get('sid', 'Guest') - self.data = webnotes._dict({'user':user,'data': webnotes._dict({})}) + self.user = user + self.data = webnotes._dict({'data': webnotes._dict({})}) self.time_diff = None - - if webnotes.form_dict.get('cmd')=='login': + if resume: + self.resume() + else: self.start() - return - - self.load() def start(self): - """start a new session""" - import os - import webnotes - import webnotes.utils - + """start a new session""" # generate sid - if webnotes.local.login_manager.user=='Guest': + if self.user=='Guest': sid = 'Guest' else: sid = webnotes.generate_hash() - self.data['user'] = webnotes.local.login_manager.user + self.data['user'] = self.user self.data['sid'] = sid - self.data['data']['user'] = webnotes.local.login_manager.user + self.data['data']['user'] = self.user self.data['data']['session_ip'] = webnotes.get_request_header('REMOTE_ADDR') - self.data['data']['last_updated'] = webnotes.utils.now() - self.data['data']['session_expiry'] = self.get_expiry_period() + if self.user != "Guest": + self.data['data']['last_updated'] = webnotes.utils.now() + self.data['data']['session_expiry'] = self.get_expiry_period() self.data['data']['session_country'] = get_geo_ip_country(webnotes.get_request_header('REMOTE_ADDR')) # insert session - webnotes.conn.begin() - self.insert_session_record() + if self.user!="Guest": + webnotes.conn.begin() + self.insert_session_record() - # update profile - webnotes.conn.sql("""UPDATE tabProfile SET last_login = '%s', last_ip = '%s' - where name='%s'""" % (webnotes.utils.now(), webnotes.get_request_header('REMOTE_ADDR'), self.data['user'])) - webnotes.conn.commit() + # update profile + webnotes.conn.sql("""UPDATE tabProfile SET last_login = '%s', last_ip = '%s' + where name='%s'""" % (webnotes.utils.now(), webnotes.get_request_header('REMOTE_ADDR'), self.data['user'])) + webnotes.conn.commit() # set cookies to write webnotes.local.session = self.data + + # write cookies + webnotes.local.cookie_manager.set_cookies() + def insert_session_record(self): webnotes.conn.sql("""insert into tabSessions @@ -142,7 +143,7 @@ class Session: # also add to memcache webnotes.cache().set_value("session:" + self.data.sid, self.data) - def load(self): + def resume(self): """non-login request: load a session""" import webnotes data = self.get_session_record() @@ -167,6 +168,9 @@ class Session: return r def get_session_data(self): + if self.sid=="Guest": + return webnotes._dict({"user":"Guest"}) + data = self.get_session_data_from_cache() if not data: data = self.get_session_data_from_db() @@ -187,14 +191,10 @@ class Session: return data and data.data def get_session_data_from_db(self): - if self.sid=="Guest": - rec = webnotes.conn.sql("""select user, sessiondata from - tabSessions where sid='Guest' """) - else: - rec = webnotes.conn.sql("""select user, sessiondata - from tabSessions where sid=%s and - TIMEDIFF(NOW(), lastupdate) < TIME(%s)""", (self.sid, - self.get_expiry_period())) + rec = webnotes.conn.sql("""select user, sessiondata + from tabSessions where sid=%s and + TIMEDIFF(NOW(), lastupdate) < TIME(%s)""", (self.sid, + self.get_expiry_period())) if rec: data = webnotes._dict(eval(rec and rec[0][1] or '{}')) data.user = rec[0][0] @@ -215,7 +215,7 @@ class Session: def start_as_guest(self): """all guests share the same 'Guest' session""" - webnotes.local.login_manager.login_as_guest() + self.user = "Guest" self.start() def update(self, force=False): diff --git a/webnotes/utils/nestedset.py b/webnotes/utils/nestedset.py index be82fff496..523ff9299c 100644 --- a/webnotes/utils/nestedset.py +++ b/webnotes/utils/nestedset.py @@ -18,15 +18,16 @@ from webnotes import msgprint, _ # called in the on_update method def update_nsm(doc_obj): # get fields, data from the DocType - - pf, opf = 'parent_node', 'old_parent' + opf = 'old_parent' if str(doc_obj.__class__)=='webnotes.model.doc.Document': # passed as a Document object d = doc_obj + pf = "parent_" + webnotes.scrub(d.doctype) else: # passed as a DocType object d = doc_obj.doc + pf = "parent_" + webnotes.scrub(d.doctype) if hasattr(doc_obj,'nsm_parent_field'): pf = doc_obj.nsm_parent_field @@ -182,6 +183,8 @@ class DocTypeNestedSet(object): self.validate_ledger() def on_trash(self): + if not self.nsm_parent_field: + self.nsm_parent_field = webnotes.scrub(self.doc.doctype) + "_parent" parent = self.doc.fields[self.nsm_parent_field] if not parent: msgprint(_("Root ") + self.doc.doctype + _(" cannot be deleted."), raise_exception=1) diff --git a/webnotes/webutils.py b/webnotes/webutils.py index ba0b666787..41e2c1d838 100644 --- a/webnotes/webutils.py +++ b/webnotes/webutils.py @@ -61,10 +61,7 @@ def build_page(page_name): webnotes.connect() if page_name=="index": - page_name = webnotes.conn.get_value("Website Settings", None, "home_page") - if not page_name: - page_name = "login" - + page_name = get_home_page() try: sitemap_options = webnotes.doc("Website Sitemap", page_name).fields page_options = webnotes.doc("Website Sitemap Config", @@ -73,7 +70,9 @@ def build_page(page_name): "docname":sitemap_options.docname }) except webnotes.DoesNotExistError: - return build_page("404") + hooks = webnotes.get_hooks() + if hooks.website_catch_all: + return build_page(hooks.website_catch_all[0]) page_options["page_name"] = page_name @@ -108,15 +107,8 @@ def build_page(page_name): return html def get_home_page(): - if not webnotes.conn: - webnotes.connect() - doc_name = webnotes.conn.get_value('Website Settings', None, 'home_page') - if doc_name: - page_name = webnotes.conn.get_value('Web Page', doc_name, 'page_name') - else: - page_name = 'index' - - return page_name + return webnotes.cache().get_value("home_page", \ + lambda: webnotes.conn.get_value("Website Settings", None, "home_page") or "login") def get_website_settings(): from webnotes.utils import get_request_site_address, encode, cint @@ -189,6 +181,7 @@ def clear_cache(page_name=None): for p in webnotes.conn.sql_list("""select name from `tabWebsite Sitemap`"""): if p is not None: cache.delete_value("page:" + p) + cache.delete_value("home_page") cache.delete_value("page:index") cache.delete_value("website_sitemap") cache.delete_value("website_sitemap_config") diff --git a/webnotes/widgets/search.py b/webnotes/widgets/search.py index 1b03489331..ccfd6f0a94 100644 --- a/webnotes/widgets/search.py +++ b/webnotes/widgets/search.py @@ -24,7 +24,7 @@ def search_widget(doctype, txt, query=None, searchfield="name", start=0, meta = webnotes.get_doctype(doctype) - standard_queries = webnotes.get_hooks().standard_queries + standard_queries = webnotes.get_hooks().standard_queries or [] if standard_queries: standard_queries = dict([v.split(":") for v in standard_queries])