def test_synchronize_external_groups(self): """webgroup - synchronizing one user external groups""" from invenio.webgroup import synchronize_external_groups from invenio.webgroup_dblayer import get_external_groups synchronize_external_groups(self.uid, { 'group1': 'descr1', 'group2': 'descr2' }, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group2' in groups_names) synchronize_external_groups(self.uid, { 'group1': 'descr1', 'group2': 'descr2' }, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group2' in groups_names) self.failUnless(len(groups_names) == 2) synchronize_external_groups(self.uid, { 'group1': 'descr1', 'group3': 'descr2' }, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group3' in groups_names) self.failUnless(len(groups_names) == 2) synchronize_external_groups(self.uid, {}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless(len(groups_names) == 0)
def test_synchronize_external_groups(self): """webgroup - synchronizing one user external groups""" from invenio.webgroup import synchronize_external_groups from invenio.legacy.websession.dblayer import get_external_groups synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group2' : 'descr2'}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group2' in groups_names) synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group2' : 'descr2'}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group2' in groups_names) self.failUnless(len(groups_names) == 2) synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group3' : 'descr2'}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group3' in groups_names) self.failUnless(len(groups_names) == 2) synchronize_external_groups(self.uid, {}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless(len(groups_names) == 0)
def test_synchronize_external_groups(self): """webgroup - synchronizing one user external groups""" synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group2' : 'descr2'}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group2' in groups_names) synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group2' : 'descr2'}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group2' in groups_names) self.failUnless(len(groups_names) == 2) synchronize_external_groups(self.uid, {'group1' : 'descr1', 'group3' : 'descr2'}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless('group1' in groups_names) self.failUnless('group3' in groups_names) self.failUnless(len(groups_names) == 2) synchronize_external_groups(self.uid, {}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless(len(groups_names) == 0)
def test_synchronize_external_groups(self): """webgroup - synchronizing one user external groups""" synchronize_external_groups(self.uid, {"group1": "descr1", "group2": "descr2"}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless("group1" in groups_names) self.failUnless("group2" in groups_names) synchronize_external_groups(self.uid, {"group1": "descr1", "group2": "descr2"}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless("group1" in groups_names) self.failUnless("group2" in groups_names) self.failUnless(len(groups_names) == 2) synchronize_external_groups(self.uid, {"group1": "descr1", "group3": "descr2"}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless("group1" in groups_names) self.failUnless("group3" in groups_names) self.failUnless(len(groups_names) == 2) synchronize_external_groups(self.uid, {}, self.login_method) groups = get_external_groups(self.uid) groups_names = [name[1] for name in groups] self.failUnless(len(groups_names) == 0)
def loginUser(req, p_un, p_pw, login_method): """It is a first simple version for the authentication of user. It returns the id of the user, for checking afterwards if the login is correct """ # p_un passed may be an email or a nickname: p_email = get_email_from_username(p_un) # go on with the old stuff based on p_email: if not login_method in CFG_EXTERNAL_AUTHENTICATION: return ([], p_email, p_pw, 12) if CFG_EXTERNAL_AUTHENTICATION[login_method]: # External Authenthication try: p_email = CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(p_email, p_pw, req) or CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(p_un, p_pw, req) ## We try to login with either the email of the nickname if p_email: p_email = p_email.lower() else: return([], p_email, p_pw, 15) except InvenioWebAccessExternalAuthError: register_exception(req=req, alert_admin=True) raise if p_email: # Authenthicated externally query_result = run_sql("SELECT id from user where email=%s", (p_email,)) if not query_result: # First time user p_pw_local = int(random.random() * 1000000) p_nickname = '' if CFG_EXTERNAL_AUTHENTICATION[login_method].enforce_external_nicknames: try: # Let's discover the external nickname! p_nickname = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_nickname(p_email, p_pw, req) except (AttributeError, NotImplementedError): pass except: register_exception(req=req, alert_admin=True) raise res = registerUser(req, p_email, p_pw_local, p_nickname, register_without_nickname=p_nickname == '', login_method=login_method) if res == 4 or res == 2: # The nickname was already taken res = registerUser(req, p_email, p_pw_local, '', register_without_nickname=True, login_method=login_method) query_result = run_sql("SELECT id from user where email=%s", (p_email,)) elif res == 0: # Everything was ok, with or without nickname. query_result = run_sql("SELECT id from user where email=%s", (p_email,)) elif res == 6: # error in contacting the user via email return([], p_email, p_pw_local, 19) else: return([], p_email, p_pw_local, 13) elif CFG_EXTERNAL_AUTHENTICATION[login_method].enforce_external_nicknames: ## Let's still fetch a possibly upgraded nickname. try: # Let's discover the external nickname! p_nickname = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_nickname(p_email, p_pw, req) if nickname_valid_p(p_nickname) and nicknameUnique(p_nickname) == 0: updateDataUser(query_result[0][0], p_email, p_nickname) except (AttributeError, NotImplementedError): pass except: register_exception(alert_admin=True) raise try: groups = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_groups_membership(p_email, p_pw, req) # groups is a dictionary {group_name : group_description,} new_groups = {} for key, value in groups.items(): new_groups[key + " [" + str(login_method) + "]"] = value groups = new_groups except (AttributeError, NotImplementedError): pass except: register_exception(req=req, alert_admin=True) return([], p_email, p_pw, 16) else: # Groups synchronization if groups: userid = query_result[0][0] from invenio.webgroup import synchronize_external_groups synchronize_external_groups(userid, groups, login_method) user_prefs = get_user_preferences(query_result[0][0]) if not CFG_EXTERNAL_AUTHENTICATION[login_method]: ## I.e. if the login method is not of robot type: if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4: # Let's prevent the user to switch login_method if user_prefs.has_key("login_method") and \ user_prefs["login_method"] != login_method: return([], p_email, p_pw, 11) user_prefs["login_method"] = login_method # Cleaning external settings for key in user_prefs.keys(): if key.startswith('EXTERNAL_'): del user_prefs[key] try: # Importing external settings new_prefs = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_preferences(p_email, p_pw, req) for key, value in new_prefs.items(): user_prefs['EXTERNAL_' + key] = value except (AttributeError, NotImplementedError): pass except InvenioWebAccessExternalAuthError: register_exception(req=req, alert_admin=True) return([], p_email, p_pw, 16) # Storing settings set_user_preferences(query_result[0][0], user_prefs) else: return ([], p_un, p_pw, 10) else: # Internal Authenthication if not p_pw: p_pw = '' query_result = run_sql("SELECT id,email,note from user where email=%s and password=AES_ENCRYPT(email,%s)", (p_email, p_pw,)) if query_result: #FIXME drop external groups and settings note = query_result[0][2] if note == '1': # Good account preferred_login_method = get_user_preferences(query_result[0][0])['login_method'] p_email = query_result[0][1].lower() if login_method != preferred_login_method: if preferred_login_method in CFG_EXTERNAL_AUTHENTICATION: return ([], p_email, p_pw, 11) elif note == '2': # Email address need to be confirmed by user return ([], p_email, p_pw, 17) elif note == '0': # Account need to be confirmed by administrator return ([], p_email, p_pw, 18) else: return ([], p_email, p_pw, 14) # Login successful! Updating the last access time run_sql("UPDATE user SET last_login=NOW() WHERE email=%s", (p_email,)) return (query_result, p_email, p_pw, 0)
def collect_user_info(req, login_time=False, refresh=False): """Given the mod_python request object rec or a uid it returns a dictionary containing at least the keys uid, nickname, email, groups, plus any external keys in the user preferences (collected at login time and built by the different external authentication plugins) and if the mod_python request object is provided, also the remote_ip, remote_host, referer, agent fields. NOTE: if req is a mod_python request object, the user_info dictionary is saved into req._user_info (for caching purpouses) setApacheUser & setUid will properly reset it. """ from invenio.search_engine import get_permitted_restricted_collections user_info = { 'remote_ip' : '', 'remote_host' : '', 'referer' : '', 'uri' : '', 'agent' : '', 'uid' :-1, 'nickname' : '', 'email' : '', 'group' : [], 'guest' : '1', 'session' : None, 'precached_permitted_restricted_collections' : [], 'precached_usebaskets' : False, 'precached_useloans' : False, 'precached_usegroups' : False, 'precached_usealerts' : False, 'precached_usemessages' : False, 'precached_viewsubmissions' : False, 'precached_useapprove' : False, 'precached_useadmin' : False, 'precached_usestats' : False, 'precached_viewclaimlink' : False, 'precached_usepaperclaim' : False, 'precached_usepaperattribution' : False, } try: is_req = False if not req: uid = -1 elif type(req) in (type(1), type(1L)): ## req is infact a user identification uid = req elif type(req) is dict: ## req is by mistake already a user_info try: assert(req.has_key('uid')) assert(req.has_key('email')) assert(req.has_key('nickname')) except AssertionError: ## mmh... misuse of collect_user_info. Better warn the admin! register_exception(alert_admin=True) user_info.update(req) return user_info else: is_req = True uid = getUid(req) if hasattr(req, '_user_info') and not login_time: user_info = req._user_info if not refresh: return req._user_info req._user_info = user_info try: user_info['remote_ip'] = req.remote_ip except gaierror: #FIXME: we should support IPV6 too. (hint for FireRole) pass user_info['session'] = get_session(req).sid() user_info['remote_host'] = req.remote_host or '' user_info['referer'] = req.headers_in.get('Referer', '') user_info['uri'] = req.unparsed_uri or () user_info['agent'] = req.headers_in.get('User-Agent', 'N/A') user_info['uid'] = uid user_info['nickname'] = get_nickname(uid) or '' user_info['email'] = get_email(uid) or '' user_info['group'] = [] user_info['guest'] = str(isGuestUser(uid)) if user_info['guest'] == '1' and CFG_INSPIRE_SITE: usepaperattribution = False viewclaimlink = False if (CFG_BIBAUTHORID_ENABLED and acc_is_user_in_role(user_info, acc_get_role_id("paperattributionviewers"))): usepaperattribution = True # if (CFG_BIBAUTHORID_ENABLED # and usepaperattribution # and acc_is_user_in_role(user_info, acc_get_role_id("paperattributionlinkviewers"))): # viewclaimlink = True if is_req: session = get_session(req) viewlink = False try: viewlink = session['personinfo']['claim_in_process'] except (KeyError, TypeError): viewlink = False else: viewlink = False if (CFG_BIBAUTHORID_ENABLED and usepaperattribution and viewlink): viewclaimlink = True user_info['precached_viewclaimlink'] = viewclaimlink user_info['precached_usepaperattribution'] = usepaperattribution if user_info['guest'] == '0': user_info['group'] = [group[1] for group in get_groups(uid)] prefs = get_user_preferences(uid) login_method = prefs['login_method'] login_object = CFG_EXTERNAL_AUTHENTICATION[login_method] if login_object and ((datetime.datetime.now() - get_last_login(uid)).seconds > 3600): ## The user uses an external authentication method and it's a bit since ## she has not performed a login if not CFG_EXTERNAL_AUTH_USING_SSO or ( is_req and login_object.in_shibboleth(req)): ## If we're using SSO we must be sure to be in HTTPS and Shibboleth handler ## otherwise we can't really read anything, hence ## it's better skip the synchronization try: groups = login_object.fetch_user_groups_membership(user_info['email'], req=req) # groups is a dictionary {group_name : group_description,} new_groups = {} for key, value in groups.items(): new_groups[key + " [" + str(login_method) + "]"] = value groups = new_groups except (AttributeError, NotImplementedError, TypeError, InvenioWebAccessExternalAuthError): pass else: # Groups synchronization from invenio.webgroup import synchronize_external_groups synchronize_external_groups(uid, groups, login_method) user_info['group'] = [group[1] for group in get_groups(uid)] try: # Importing external settings new_prefs = login_object.fetch_user_preferences(user_info['email'], req=req) for key, value in new_prefs.items(): prefs['EXTERNAL_' + key] = value except (AttributeError, NotImplementedError, TypeError, InvenioWebAccessExternalAuthError): pass else: set_user_preferences(uid, prefs) prefs = get_user_preferences(uid) run_sql('UPDATE user SET last_login=NOW() WHERE id=%s', (uid,)) if prefs: for key, value in prefs.iteritems(): user_info[key.lower()] = value if login_time: ## Heavy computational information from invenio.access_control_engine import acc_authorize_action if CFG_WEBSEARCH_PERMITTED_RESTRICTED_COLLECTIONS_LEVEL > 0: user_info['precached_permitted_restricted_collections'] = get_permitted_restricted_collections(user_info) user_info['precached_usebaskets'] = acc_authorize_action(user_info, 'usebaskets')[0] == 0 user_info['precached_useloans'] = acc_authorize_action(user_info, 'useloans')[0] == 0 user_info['precached_usegroups'] = acc_authorize_action(user_info, 'usegroups')[0] == 0 user_info['precached_usealerts'] = acc_authorize_action(user_info, 'usealerts')[0] == 0 user_info['precached_usemessages'] = acc_authorize_action(user_info, 'usemessages')[0] == 0 user_info['precached_usestats'] = acc_authorize_action(user_info, 'runwebstatadmin')[0] == 0 user_info['precached_viewsubmissions'] = isUserSubmitter(user_info) user_info['precached_useapprove'] = isUserReferee(user_info) user_info['precached_useadmin'] = isUserAdmin(user_info) usepaperclaim = False usepaperattribution = False viewclaimlink = False if (CFG_BIBAUTHORID_ENABLED and acc_is_user_in_role(user_info, acc_get_role_id("paperclaimviewers"))): usepaperclaim = True if (CFG_BIBAUTHORID_ENABLED and acc_is_user_in_role(user_info, acc_get_role_id("paperattributionviewers"))): usepaperattribution = True if is_req: session = get_session(req) viewlink = False try: viewlink = session['personinfo']['claim_in_process'] except (KeyError, TypeError): viewlink = False else: viewlink = False if (CFG_BIBAUTHORID_ENABLED and usepaperattribution and viewlink): viewclaimlink = True # if (CFG_BIBAUTHORID_ENABLED # and ((usepaperclaim or usepaperattribution) # and acc_is_user_in_role(user_info, acc_get_role_id("paperattributionlinkviewers")))): # viewclaimlink = True user_info['precached_viewclaimlink'] = viewclaimlink user_info['precached_usepaperclaim'] = usepaperclaim user_info['precached_usepaperattribution'] = usepaperattribution except Exception, e: register_exception()
def loginUser(req, p_un, p_pw, login_method): """It is a first simple version for the authentication of user. It returns the id of the user, for checking afterwards if the login is correct """ # p_un passed may be an email or a nickname: p_email = get_email_from_username(p_un) # go on with the old stuff based on p_email: if not login_method in CFG_EXTERNAL_AUTHENTICATION: return (None, p_email, p_pw, 12) if CFG_EXTERNAL_AUTHENTICATION[login_method]: # External Authentication try: result = CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(p_email, p_pw, req) if (result == (None, None) or result is None) and not login_method in ['oauth1', 'oauth2', 'openid']: # There is no need to call auth_user with username for # OAuth1, OAuth2 and OpenID authentication result = CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user(p_un, p_pw, req) ## We try to login with either the email of the nickname if isinstance(result, (tuple, list)) and len(result) == 2: p_email, p_extid = result else: ## For backward compatibility we use the email as external ## identifier if it was not returned already by the plugin p_email, p_extid = str(result), str(result) if p_email: p_email = p_email.lower() if not p_extid: p_extid = p_email elif not p_extid: try: # OpenID and OAuth authentications have own error messages return (None, p_email, p_pw, CFG_EXTERNAL_AUTHENTICATION[login_method].get_msg(req)) except NotImplementedError: return(None, p_email, p_pw, 15) else: # External login is successfull but couldn't fetch the email # address. generate_string = lambda: reduce((lambda x, y: x+y), [random.choice("qwertyuiopasdfghjklzxcvbnm1234567890") for i in range(32)]) random_string = generate_string() p_email = CFG_TEMP_EMAIL_ADDRESS % random_string while run_sql("SELECT * FROM user WHERE email=%s", (p_email,)): random_string = generate_string() p_email = CFG_TEMP_EMAIL_ADDRESS % random_string except InvenioWebAccessExternalAuthError: register_exception(req=req, alert_admin=True) raise if p_email: # Authenthicated externally query_result = run_sql("SELECT id_user FROM userEXT WHERE id=%s and method=%s", (p_extid, login_method)) if query_result: ## User was already registered with this external method. id_user = query_result[0][0] old_email = run_sql("SELECT email FROM user WHERE id=%s", (id_user,))[0][0] # Look if the email address matches with the template given. # If it matches, use the email address saved in the database. regexp = re.compile(CFG_TEMP_EMAIL_ADDRESS % r"\w*") if regexp.match(p_email): p_email = old_email if old_email != p_email: ## User has changed email of reference. res = run_sql("SELECT id FROM user WHERE email=%s", (p_email,)) if res: ## User was also registered with the other email. ## We should merge the two! new_id = res[0][0] if new_id == id_user: raise AssertionError("We should not reach this situation: new_id=%s, id_user=%s, old_email=%s, p_email=%s" % (new_id, id_user, old_email, p_email)) merge_usera_into_userb(id_user, new_id) run_sql("DELETE FROM user WHERE id=%s", (id_user, )) for row in run_sql("SELECT method FROM userEXT WHERE id_user=%s", (id_user, )): ## For all known accounts of id_user not conflicting with new_id we move them to refer to new_id if not run_sql("SELECT method FROM userEXT WHERE id_user=%s AND method=%s", (new_id, row[0])): run_sql("UPDATE userEXT SET id_user=%s WHERE id_user=%s AND method=%s", (new_id, id_user, row[0])) ## And we delete the duplicate remaining ones :-) run_sql("DELETE FROM userEXT WHERE id_user=%s", (id_user, )) id_user = new_id else: ## We just need to rename the email address of the ## corresponding user. Unfortunately the local ## password will be then invalid, but its unlikely ## the user is using both an external and a local ## account. run_sql("UPDATE user SET email=%s WHERE id=%s", (p_email, id_user)) else: ## User was not already registered with this external method. query_result = run_sql("SELECT id FROM user WHERE email=%s", (p_email, )) if query_result: ## The user was already known with this email id_user = query_result[0][0] ## We fix the inconsistence in the userEXT table. run_sql("INSERT INTO userEXT(id, method, id_user) VALUES(%s, %s, %s) ON DUPLICATE KEY UPDATE id=%s, method=%s, id_user=%s", (p_extid, login_method, id_user, p_extid, login_method, id_user)) else: ## First time user p_pw_local = int(random.random() * 1000000) p_nickname = '' if CFG_EXTERNAL_AUTHENTICATION[login_method].enforce_external_nicknames: try: # Let's discover the external nickname! p_nickname = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_nickname(p_email, p_pw, req) except (AttributeError, NotImplementedError): pass except: register_exception(req=req, alert_admin=True) raise res = registerUser(req, p_email, p_pw_local, p_nickname, register_without_nickname=p_nickname == '', login_method=login_method) if res == 4 or res == 2: # The nickname was already taken res = registerUser(req, p_email, p_pw_local, '', register_without_nickname=True, login_method=login_method) query_result = run_sql("SELECT id from user where email=%s", (p_email,)) id_user = query_result[0][0] elif res == 0: # Everything was ok, with or without nickname. query_result = run_sql("SELECT id from user where email=%s", (p_email,)) id_user = query_result[0][0] elif res == 6: # error in contacting the user via email return (None, p_email, p_pw_local, 19) else: return (None, p_email, p_pw_local, 13) run_sql("INSERT INTO userEXT(id, method, id_user) VALUES(%s, %s, %s)", (p_extid, login_method, id_user)) if CFG_EXTERNAL_AUTHENTICATION[login_method].enforce_external_nicknames: ## Let's still fetch a possibly upgraded nickname. try: # Let's discover the external nickname! p_nickname = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_nickname(p_email, p_pw, req) if nickname_valid_p(p_nickname) and nicknameUnique(p_nickname) == 0: updateDataUser(id_user, p_email, p_nickname) except (AttributeError, NotImplementedError): pass except: register_exception(alert_admin=True) raise try: groups = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_groups_membership(p_email, p_pw, req) # groups is a dictionary {group_name : group_description,} new_groups = {} for key, value in groups.items(): new_groups[key + " [" + str(login_method) + "]"] = value groups = new_groups except (AttributeError, NotImplementedError): pass except: register_exception(req=req, alert_admin=True) return (None, p_email, p_pw, 16) else: # Groups synchronization if groups: from invenio.webgroup import synchronize_external_groups synchronize_external_groups(id_user, groups, login_method) user_prefs = get_user_preferences(id_user) if not CFG_EXTERNAL_AUTHENTICATION[login_method]: ## I.e. if the login method is not of robot type: if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4: # Let's prevent the user to switch login_method if "login_method" in user_prefs and \ user_prefs["login_method"] != login_method: return (None, p_email, p_pw, 11) user_prefs["login_method"] = login_method # Cleaning external settings for key in user_prefs.keys(): if key.startswith('EXTERNAL_'): del user_prefs[key] try: # Importing external settings new_prefs = CFG_EXTERNAL_AUTHENTICATION[login_method].fetch_user_preferences(p_email, p_pw, req) for key, value in new_prefs.items(): user_prefs['EXTERNAL_' + key] = value except (AttributeError, NotImplementedError): pass except InvenioWebAccessExternalAuthError: register_exception(req=req, alert_admin=True) return (None, p_email, p_pw, 16) # Storing settings set_user_preferences(id_user, user_prefs) else: return (None, p_un, p_pw, 10) else: # Internal Authenthication if not p_pw: p_pw = '' query_result = run_sql("SELECT id,email,note from user where email=%s and password=AES_ENCRYPT(email,%s)", (p_email, p_pw,)) if query_result: #FIXME drop external groups and settings note = query_result[0][2] id_user = query_result[0][0] if note == '1': # Good account preferred_login_method = get_user_preferences(query_result[0][0])['login_method'] p_email = query_result[0][1].lower() if login_method != preferred_login_method: if preferred_login_method in CFG_EXTERNAL_AUTHENTICATION: return (None, p_email, p_pw, 11) elif note == '2': # Email address need to be confirmed by user return (None, p_email, p_pw, 17) elif note == '0': # Account need to be confirmed by administrator return (None, p_email, p_pw, 18) else: return (None, p_email, p_pw, 14) # Login successful! Updating the last access time run_sql("UPDATE user SET last_login=NOW() WHERE email=%s", (p_email,)) return (id_user, p_email, p_pw, 0)
def loginUser(req, p_un, p_pw, login_method): """It is a first simple version for the authentication of user. It returns the id of the user, for checking afterwards if the login is correct """ # p_un passed may be an email or a nickname: p_email = get_email_from_username(p_un) # go on with the old stuff based on p_email: if not login_method in CFG_EXTERNAL_AUTHENTICATION: return ([], p_email, p_pw, 12) if CFG_EXTERNAL_AUTHENTICATION[login_method]: # External Authenthication try: p_email = CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user( p_email, p_pw, req) or CFG_EXTERNAL_AUTHENTICATION[login_method].auth_user( p_un, p_pw, req ) ## We try to login with either the email of the nickname if p_email: p_email = p_email.lower() else: return ([], p_email, p_pw, 15) except InvenioWebAccessExternalAuthError: register_exception(req=req, alert_admin=True) raise if p_email: # Authenthicated externally query_result = run_sql("SELECT id from user where email=%s", (p_email, )) if not query_result: # First time user p_pw_local = int(random.random() * 1000000) p_nickname = '' if CFG_EXTERNAL_AUTHENTICATION[ login_method].enforce_external_nicknames: try: # Let's discover the external nickname! p_nickname = CFG_EXTERNAL_AUTHENTICATION[ login_method].fetch_user_nickname( p_email, p_pw, req) except (AttributeError, NotImplementedError): pass except: register_exception(req=req, alert_admin=True) raise res = registerUser(req, p_email, p_pw_local, p_nickname, register_without_nickname=p_nickname == '', login_method=login_method) if res == 4 or res == 2: # The nickname was already taken res = registerUser(req, p_email, p_pw_local, '', register_without_nickname=True, login_method=login_method) query_result = run_sql( "SELECT id from user where email=%s", (p_email, )) elif res == 0: # Everything was ok, with or without nickname. query_result = run_sql( "SELECT id from user where email=%s", (p_email, )) elif res == 6: # error in contacting the user via email return ([], p_email, p_pw_local, 19) else: return ([], p_email, p_pw_local, 13) try: groups = CFG_EXTERNAL_AUTHENTICATION[ login_method].fetch_user_groups_membership( p_email, p_pw, req) # groups is a dictionary {group_name : group_description,} new_groups = {} for key, value in groups.items(): new_groups[key + " [" + str(login_method) + "]"] = value groups = new_groups except (AttributeError, NotImplementedError): pass except: register_exception(req=req, alert_admin=True) return ([], p_email, p_pw, 16) else: # Groups synchronization if groups: userid = query_result[0][0] from invenio.webgroup import synchronize_external_groups synchronize_external_groups(userid, groups, login_method) user_prefs = get_user_preferences(query_result[0][0]) if not CFG_EXTERNAL_AUTHENTICATION[login_method]: ## I.e. if the login method is not of robot type: if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4: # Let's prevent the user to switch login_method if user_prefs.has_key("login_method") and \ user_prefs["login_method"] != login_method: return ([], p_email, p_pw, 11) user_prefs["login_method"] = login_method # Cleaning external settings for key in user_prefs.keys(): if key.startswith('EXTERNAL_'): del user_prefs[key] try: # Importing external settings new_prefs = CFG_EXTERNAL_AUTHENTICATION[ login_method].fetch_user_preferences(p_email, p_pw, req) for key, value in new_prefs.items(): user_prefs['EXTERNAL_' + key] = value except (AttributeError, NotImplementedError): pass except InvenioWebAccessExternalAuthError: register_exception(req=req, alert_admin=True) return ([], p_email, p_pw, 16) # Storing settings set_user_preferences(query_result[0][0], user_prefs) else: return ([], p_un, p_pw, 10) else: # Internal Authenthication if not p_pw: p_pw = '' query_result = run_sql( "SELECT id,email,note from user where email=%s and password=AES_ENCRYPT(email,%s)", ( p_email, p_pw, )) if query_result: #FIXME drop external groups and settings note = query_result[0][2] if note == '1': # Good account preferred_login_method = get_user_preferences( query_result[0][0])['login_method'] p_email = query_result[0][1].lower() if login_method != preferred_login_method: if preferred_login_method in CFG_EXTERNAL_AUTHENTICATION: return ([], p_email, p_pw, 11) elif note == '2': # Email address need to be confirmed by user return ([], p_email, p_pw, 17) elif note == '0': # Account need to be confirmed by administrator return ([], p_email, p_pw, 18) else: return ([], p_email, p_pw, 14) # Login successful! Updating the last access time run_sql("UPDATE user SET last_login=NOW() WHERE email=%s", (p_email, )) return (query_result, p_email, p_pw, 0)
## it's better skeep the synchronization try: groups = login_object.fetch_user_groups_membership( user_info['email'], req=req) # groups is a dictionary {group_name : group_description,} new_groups = {} for key, value in groups.items(): new_groups[key + " [" + str(login_method) + "]"] = value groups = new_groups except (AttributeError, NotImplementedError, TypeError, InvenioWebAccessExternalAuthError): pass else: # Groups synchronization from invenio.webgroup import synchronize_external_groups synchronize_external_groups(uid, groups, login_method) user_info['group'] = [ group[1] for group in get_groups(uid) ] try: # Importing external settings new_prefs = login_object.fetch_user_preferences( user_info['email'], req=req) for key, value in new_prefs.items(): prefs['EXTERNAL_' + key] = value except (AttributeError, NotImplementedError, TypeError, InvenioWebAccessExternalAuthError): pass else: set_user_preferences(uid, prefs)