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 _precache(self, info, force=False): """ Calculate prermitions for user actions. FIXME: compatibility layer only !!! """ # get autorization key acc_key = self.get_acc_key() acc = cache.get(acc_key) if not force and acc_key is not None and acc is not None: return acc #FIXME: acc_authorize_action should use flask request directly user_info = info user_info.update(self.req) from invenio.webuser import isUserSubmitter, isUserReferee, \ isUserAdmin, isUserSuperAdmin from invenio.access_control_engine import acc_authorize_action from invenio.access_control_admin import acc_get_role_id, \ acc_is_user_in_role from invenio.search_engine import get_permitted_restricted_collections data = {} data['precached_permitted_restricted_collections'] = \ get_permitted_restricted_collections(user_info) data['precached_usebaskets'] = acc_authorize_action( user_info, 'usebaskets')[0] == 0 data['precached_useloans'] = acc_authorize_action( user_info, 'useloans')[0] == 0 data['precached_usegroups'] = acc_authorize_action( user_info, 'usegroups')[0] == 0 data['precached_usealerts'] = acc_authorize_action( user_info, 'usealerts')[0] == 0 data['precached_usemessages'] = acc_authorize_action( user_info, 'usemessages')[0] == 0 data['precached_usestats'] = acc_authorize_action( user_info, 'runwebstatadmin')[0] == 0 data['precached_viewsubmissions'] = isUserSubmitter(user_info) data['precached_useapprove'] = isUserReferee(user_info) data['precached_useadmin'] = isUserAdmin(user_info) data['precached_usesuperadmin'] = isUserSuperAdmin(user_info) data['precached_canseehiddenmarctags'] = acc_authorize_action( user_info, 'runbibedit')[0] == 0 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 viewlink = False try: viewlink = session['personinfo']['claim_in_process'] except (KeyError, TypeError): pass if (CFG_BIBAUTHORID_ENABLED and usepaperattribution and viewlink): viewclaimlink = True # if (CFG_BIBAUTHORID_ENABLED # and ((usepaperclaim or usepaperattribution) # and acc_is_user_in_role(data, acc_get_role_id("paperattributionlinkviewers")))): # viewclaimlink = True data['precached_viewclaimlink'] = viewclaimlink data['precached_usepaperclaim'] = usepaperclaim data['precached_usepaperattribution'] = usepaperattribution cache.set(acc_key, data, timeout=CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT * 3600) return data
def answer(self, req, user_info, of, cc, colls_to_search, p, f, search_units, ln): """ Answer question given by context. Return (relevance, html_string) where relevance is integer from 0 to 100 indicating how relevant to the question the answer is (see C{CFG_WEBSEARCH_SERVICE_MAX_SERVICE_ANSWER_RELEVANCE} for details) , and html_string being a formatted answer. """ from invenio.search_engine import \ get_permitted_restricted_collections, \ get_coll_i18nname, \ collection_i18nname_cache, \ collection_restricted_p _ = gettext_set_language(ln) # stem search units. remove those with field # TODO: search in hosted collection names too # TODO: ignore unattached trees # TODO: use synonyms if f or (CFG_WEBSEARCH_COLLECTION_NAMES_SEARCH < 0) or \ (CFG_WEBSEARCH_COLLECTION_NAMES_SEARCH == 0 and cc != CFG_SITE_NAME): return (0, '') words = [ stem(unit[1], ln) for unit in search_units if unit[2] in ('', 'collection') ] # Stemming if not words: return (0, '') permitted_restricted_collections = get_permitted_restricted_collections( user_info) cache = self.get_data_cache() matching_collections = {} for word in words: if CFG_CERN_SITE and word == 'cern': # This keyword is useless here... continue colls = cache.get(word.lower(), []) for coll in colls: if collection_restricted_p(coll) and \ not coll in permitted_restricted_collections: # Skip restricted collection user do not have access continue if not matching_collections.has_key(coll): matching_collections[coll] = 0 matching_collections[coll] += 1 matching_collections_sorted = sorted(matching_collections.iteritems(), key=lambda (k, v): (v, k), reverse=True) if not matching_collections_sorted: return (0, '') matching_collections_names = [(get_coll_i18nname(coll, ln, False), CFG_SITE_URL + '/collection/' + urllib.quote(coll, safe='') + '?ln=en') \ for coll, score in matching_collections_sorted] best_score = matching_collections_sorted[0][1] best_coll_words = whitespace_re.split( matching_collections_sorted[0][0]) relevance = min( 100, max(0, (100 * float(2 * best_score) / float(len(best_coll_words) + len(words)) - 10))) if (('submit' in p.lower()) or (_('submit') in p.lower())) and \ not (('submit' in best_coll_words) or (_('submit') in best_coll_words)): # User is probably looking for a submission. Decrease relevance relevance = max(0, relevance - 30) return (relevance, self.display_answer_helper(matching_collections_names, ln))
def answer(self, req, user_info, of, cc, colls_to_search, p, f, search_units, ln): """ Answer question given by context. Return (relevance, html_string) where relevance is integer from 0 to 100 indicating how relevant to the question the answer is (see C{CFG_WEBSEARCH_SERVICE_MAX_SERVICE_ANSWER_RELEVANCE} for details) , and html_string being a formatted answer. """ from invenio.search_engine import \ get_permitted_restricted_collections, \ get_coll_i18nname, \ collection_i18nname_cache, \ collection_restricted_p _ = gettext_set_language(ln) # stem search units. remove those with field # TODO: search in hosted collection names too # TODO: ignore unattached trees # TODO: use synonyms if f or (CFG_WEBSEARCH_COLLECTION_NAMES_SEARCH < 0) or \ (CFG_WEBSEARCH_COLLECTION_NAMES_SEARCH == 0 and cc != CFG_SITE_NAME): return (0, '') words = [stem(unit[1], ln) for unit in search_units if unit[2] in ('', 'collection')] # Stemming if not words: return (0, '') permitted_restricted_collections = get_permitted_restricted_collections(user_info) cache = self.get_data_cache() matching_collections = {} for word in words: if CFG_CERN_SITE and word == 'cern': # This keyword is useless here... continue colls = cache.get(word.lower(), []) for coll in colls: if collection_restricted_p(coll) and \ not coll in permitted_restricted_collections: # Skip restricted collection user do not have access continue if not matching_collections.has_key(coll): matching_collections[coll] = 0 matching_collections[coll] += 1 matching_collections_sorted = sorted(matching_collections.iteritems(), key=lambda (k, v): (v, k), reverse=True) if not matching_collections_sorted: return (0, '') matching_collections_names = [(get_coll_i18nname(coll, ln, False), CFG_SITE_URL + '/collection/' + urllib.quote(coll, safe='') + '?ln=en') \ for coll, score in matching_collections_sorted] best_score = matching_collections_sorted[0][1] best_coll_words = whitespace_re.split(matching_collections_sorted[0][0]) relevance = min(100, max(0, (100 * float(2 * best_score) / float(len(best_coll_words) + len(words)) - 10))) if (('submit' in p.lower()) or (_('submit') in p.lower())) and \ not (('submit' in best_coll_words) or (_('submit') in best_coll_words)): # User is probably looking for a submission. Decrease relevance relevance = max(0, relevance - 30) return (relevance, self.display_answer_helper(matching_collections_names, ln))
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)