class UserInfo(CombinedMultiDict, UserMixin): """Provide legacy implementation. Methods that Flask-Login and Invenio 1.x expect user objects to have. """ def __init__(self, uid=None, force=False): """Retrieve information about user.""" def on_update(self): """Change own status when the user info is modified.""" self.modified = True self.modified = False self.uid = uid self.req = self._get_request_info() acc = {} if uid is not None and uid > 0: data = self._login(uid, force) acc = self._precache(data, force) else: data = self._create_guest() self.info = CallbackDict(data, on_update) # FIXME remove req after everybody start using flask request. CombinedMultiDict.__init__(self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def get_key(self): """Generate key for caching user information.""" key = 'current_user::' + str(self.uid) return key def get_acc_key(self): """Generate key for caching autorizations.""" remote_ip = str(request.remote_addr) if has_request_context() else '0' return 'current_user::' + str(self.uid) + '::' + remote_ip def save(self): """Save modified data pernamently for logged users.""" if not self.is_guest and self.modified: timeout = current_app.config.get( 'CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT', 0)*3600 cache.set(self.get_key(), dict(self.info), timeout=timeout) def reload(self): """Reload user login information and saves them.""" data = self._login(self.uid, force=True) acc = self._precache(data, force=True) self.info.update(data) CombinedMultiDict.__init__(self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def update_request_info(self): """Update request information.""" self.req = self._get_request_info() def _get_request_info(self): """Get request information.""" # FIXME: we should support IPV6 too. (hint for FireRole) data = {} if has_request_context(): data['remote_ip'] = request.remote_addr or '' data['remote_host'] = request.environ.get('REMOTE_HOST', '') data['referer'] = request.referrer data['uri'] = request.environ['PATH_INFO'] or '' data['agent'] = request.headers.get('User-Agent', 'N/A') return data def _create_guest(self): data = {'settings': {}} # Minimal information about user. data['id'] = data['uid'] = 0 return data def _login(self, uid, force=False): """Get account information about currently logged user from database. Should raise an exception when session.uid is not valid User.id. """ data = cache.get(self.get_key()) if not force and data is not None: return data from invenio.modules.accounts.models import User data = {} try: user = User.query.get(uid) data['id'] = data['uid'] = user.id or -1 data['nickname'] = user.nickname or '' data['given_names'] = user.given_names or '' data['family_name'] = user.family_name or '' data['email'] = user.email or '' data['note'] = user.note or '' data['group'] = map(lambda x: x.usergroup.name, user.usergroups or []) data.update(user.settings or {}) data['settings'] = user.settings or {} data['guest'] = str(int(user.guest)) # '1' or '0' self.modified = True except Exception: data = self._create_guest() return data def _precache(self, info, force=False): """Calculate prermitions for user actions. FIXME: compatibility layer only !!! """ CFG_BIBAUTHORID_ENABLED = current_app.config.get( 'CFG_BIBAUTHORID_ENABLED', False) # 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.legacy.webuser import isUserSubmitter, isUserReferee, \ isUserAdmin, isUserSuperAdmin from invenio.modules.access.engine import acc_authorize_action from invenio.modules.access.control import acc_get_role_id, \ acc_is_user_in_role from invenio.modules.search.utils 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 try: data['precached_viewsubmissions'] = isUserSubmitter(user_info) except Exception: data['precached_viewsubmissions'] = None 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 (current_app.config.get('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 timeout = current_app.config.get( 'CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT', 0)*3600 cache.set(acc_key, data, timeout=timeout) return data def is_authenticated(self): """Check if user is authenticated.""" return not self.is_guest def is_authorized(self, name, **kwargs): """Check if user is authorized.""" from invenio.modules.access.engine import acc_authorize_action return acc_authorize_action(self, name)[0] == 0 def is_active(self): """Check if user is active.""" return not self.is_guest def is_confirmed(self): """Return true if accounts has been confirmed.""" return self['note'] == "1" @property def is_guest(self): """Check if user is guest.""" return True if self['email'] == '' else False @property def is_admin(self): """Check if user is admin.""" return self.get('precached_useadmin', False) @property def is_super_admin(self): """Check if user is super admin.""" return self.get('precached_usesuperadmin', False) def get_id(self): """Get user id.""" return self.get('id', -1)
class UserInfo(CombinedMultiDict, UserMixin): def __init__(self, uid=None, force=False): """ Keeps information about user. """ def on_update(self): """ Changes own status when the user info is modified. """ self.modified = True self.modified = False self.uid = uid self.req = self._get_request_info() acc = {} if uid > 0: data = self._login(uid, force) acc = self._precache(data, force) else: data = self._create_guest() self.info = CallbackDict(data, on_update) #FIXME remove req after everybody start using flask request. CombinedMultiDict.__init__( self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def get_key(self): """ Generates key for caching user information. """ key = 'current_user::' + str(self.uid) return key def get_acc_key(self): """ Generates key for caching autorizations. """ remote_ip = str(request.remote_addr) if has_request_context() else '0' return 'current_user::' + str(self.uid) + '::' + remote_ip def save(self): """ Saves modified data pernamently for logged users. """ if not self.is_guest and self.modified: cache.set(self.get_key(), dict(self.info), timeout=CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT * 3600) def reload(self): """ Reloads user login information and saves them. """ data = self._login(self.uid, force=True) acc = self._precache(data, force=True) self.info.update(data) CombinedMultiDict.__init__( self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def update_request_info(self): self.req = self._get_request_info() def _get_request_info(self): """ Get request information. """ #FIXME: we should support IPV6 too. (hint for FireRole) data = {} if has_request_context(): data['remote_ip'] = request.remote_addr or '' data['remote_host'] = request.environ.get('REMOTE_HOST', '') data['referer'] = request.referrer data['uri'] = request.environ['PATH_INFO'] or '' data['agent'] = request.headers.get('User-Agent', 'N/A') #data['session'] = session.sid return data def _create_guest(self): data = {'settings': {}} if CFG_WEBSESSION_DIFFERENTIATE_BETWEEN_GUESTS: from invenio.sqlalchemyutils import db from invenio.websession_model import User note = '1' if CFG_ACCESS_CONTROL_LEVEL_GUESTS == 0 else '0' u = User(email='', note=note, password='******') db.session.add(u) db.session.commit() data.update(u.__dict__) else: # Minimal information about user. data['id'] = data['uid'] = 0 return data def _login(self, uid, force=False): """ Get account information about currently logged user from database. Should raise an exception when session.uid is not valid User.id. """ data = cache.get(self.get_key()) if not force and data is not None: return data from invenio.websession_model import User data = {} try: user = User.query.get(uid) data['id'] = data['uid'] = user.id or -1 data['nickname'] = user.nickname or '' data['email'] = user.email or '' data['note'] = user.note or '' data.update(user.settings or {}) data['settings'] = user.settings or {} data['guest'] = str(int(user.guest)) # '1' or '0' self.modified = True except: data = self._create_guest() return data 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 is_authenticated(self): return not self.is_guest def is_authorized(self, name, **kwargs): from invenio.access_control_engine import acc_authorize_action return acc_authorize_action(self, name)[0] == 0 def is_active(self): return not self.is_guest @property def is_guest(self): return True if self['email'] == '' else False @property def is_admin(self): return self.get('precached_useadmin', False) @property def is_super_admin(self): return self.get('precached_usesuperadmin', False) def get_id(self): return self.get('id', -1)
class UserInfo(CombinedMultiDict, UserMixin): """Provide legacy implementation. Methods that Flask-Login and Invenio 1.x expect user objects to have. """ def __init__(self, uid=None, force=False): """Retrieve information about user.""" def on_update(self): """Change own status when the user info is modified.""" self.modified = True self.modified = False self.uid = uid self.req = self._get_request_info() acc = {} if uid is not None and uid > 0: data = self._login(uid, force) acc = self._precache(data, force) else: data = self._create_guest() self.info = CallbackDict(data, on_update) # FIXME remove req after everybody start using flask request. CombinedMultiDict.__init__(self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def get_key(self): """Generate key for caching user information.""" key = "current_user::" + str(self.uid) return key def get_acc_key(self): """Generate key for caching authorizations.""" remote_ip = str(request.remote_addr) if has_request_context() else "0" return "current_user::" + str(self.uid) + "::" + remote_ip def save(self): """Save modified data permanently for logged users.""" if not self.is_guest and self.modified: timeout = current_app.config.get("CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT", 0) * 3600 cache.set(self.get_key(), dict(self.info), timeout=timeout) def reload(self): """Reload user login information and saves them.""" data = self._login(self.uid, force=True) acc = self._precache(data, force=True) self.info.update(data) CombinedMultiDict.__init__(self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def update_request_info(self): """Update request information.""" self.req = self._get_request_info() def _get_request_info(self): """Get request information.""" # FIXME: we should support IPV6 too. (hint for FireRole) data = {} if has_request_context(): data["remote_ip"] = request.remote_addr or "" data["remote_host"] = request.environ.get("REMOTE_HOST", "") data["referer"] = request.referrer data["uri"] = request.environ["PATH_INFO"] or "" data["agent"] = request.headers.get("User-Agent", "N/A") return data def _create_guest(self): # Minimal information about user. return {"settings": {}, "id": 0, "uid": 0} def _login(self, uid, force=False): """Get account information about currently logged user from database. Should raise an exception when session.uid is not valid User.id. """ data = cache.get(self.get_key()) if not force and data is not None: return data from invenio_accounts.models import User data = {} try: user = User.query.get(uid) data["id"] = data["uid"] = user.id or -1 data["nickname"] = user.nickname or "" data["given_names"] = user.given_names or "" data["family_name"] = user.family_name or "" data["email"] = user.email or "" data["note"] = user.note or "" data["group"] = map(lambda x: x.group.name, getattr(user, "groups", [])) data.update(user.settings or {}) data["settings"] = user.settings or {} data["guest"] = str(int(user.guest)) # '1' or '0' self.modified = True except Exception: data = self._create_guest() return data def _precache(self, info, force=False): """Calculate permissions for user actions. FIXME: compatibility layer only !!! """ CFG_BIBAUTHORID_ENABLED = current_app.config.get("CFG_BIBAUTHORID_ENABLED", False) # get authorization 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.legacy.webuser import isUserSubmitter, isUserReferee, isUserAdmin, isUserSuperAdmin from invenio_access.engine import acc_authorize_action from invenio_access.control import acc_get_role_id, acc_is_user_in_role from invenio_search.utils import get_permitted_restricted_collections from invenio_deposit.cache import get_authorized_deposition_types data = {} data["precached_permitted_restricted_collections"] = get_permitted_restricted_collections(user_info) data["precached_allowed_deposition_types"] = get_authorized_deposition_types(user_info) data["precached_useloans"] = acc_authorize_action(user_info, "useloans")[0] == 0 data["precached_usegroups"] = acc_authorize_action(user_info, "usegroups")[0] == 0 data["precached_usemessages"] = acc_authorize_action(user_info, "usemessages")[0] == 0 try: data["precached_viewsubmissions"] = isUserSubmitter(user_info) except Exception: data["precached_viewsubmissions"] = None 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 current_app.config.get("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 timeout = current_app.config.get("CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT", 0) * 3600 cache.set(acc_key, data, timeout=timeout) return data def is_authenticated(self): """Check if user is authenticated.""" return not self.is_guest def is_authorized(self, name, **kwargs): """Check if user is authorized.""" from invenio_access.engine import acc_authorize_action return acc_authorize_action(self, name)[0] == 0 def is_active(self): """Check if user is active.""" return not self.is_guest def is_confirmed(self): """Return true if accounts has been confirmed.""" return self["note"] == "1" @property def is_guest(self): """Check if user is guest.""" return True if self["email"] == "" else False @property def is_admin(self): """Check if user is admin.""" return self.get("precached_useadmin", False) @property def is_super_admin(self): """Check if user is super admin.""" return self.get("precached_usesuperadmin", False) def get_id(self): """Get user id.""" return self.get("id", -1)
class UserInfo(CombinedMultiDict, UserMixin): """Provide legacy implementation. Methods that Flask-Login and Invenio 1.x expect user objects to have. """ def __init__(self, uid=None, force=False): """Retrieve information about user.""" def on_update(self): """Change own status when the user info is modified.""" self.modified = True self.modified = False self.uid = uid self.req = self._get_request_info() acc = {} if uid is not None and uid > 0: data = self._login(uid, force) acc = self._precache(data, force) else: data = self._create_guest() self.info = CallbackDict(data, on_update) # FIXME remove req after everybody start using flask request. CombinedMultiDict.__init__(self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def get_key(self): """Generate key for caching user information.""" key = 'current_user::' + str(self.uid) return key def get_acc_key(self): """Generate key for caching authorizations.""" remote_ip = str(request.remote_addr) if has_request_context() else '0' return 'current_user::' + str(self.uid) + '::' + remote_ip def save(self): """Save modified data permanently for logged users.""" if not self.is_guest and self.modified: timeout = current_app.config.get( 'CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT', 0) * 3600 cache.set(self.get_key(), dict(self.info), timeout=timeout) def reload(self): """Reload user login information and saves them.""" data = self._login(self.uid, force=True) acc = self._precache(data, force=True) self.info.update(data) CombinedMultiDict.__init__(self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def update_request_info(self): """Update request information.""" self.req = self._get_request_info() def _get_request_info(self): """Get request information.""" # FIXME: we should support IPV6 too. (hint for FireRole) data = {} if has_request_context(): data['remote_ip'] = request.remote_addr or '' data['remote_host'] = request.environ.get('REMOTE_HOST', '') data['referer'] = request.referrer data['uri'] = request.environ['PATH_INFO'] or '' data['agent'] = request.headers.get('User-Agent', 'N/A') return data def _create_guest(self): # Minimal information about user. return {'settings': {}, 'id': 0, 'uid': 0} def _login(self, uid, force=False): """Get account information about currently logged user from database. Should raise an exception when session.uid is not valid User.id. """ data = cache.get(self.get_key()) if not force and data is not None: return data from invenio_accounts.models import User data = {} try: user = User.query.get(uid) data['id'] = data['uid'] = user.id or -1 data['nickname'] = user.nickname or '' data['given_names'] = user.given_names or '' data['family_name'] = user.family_name or '' data['email'] = user.email or '' data['note'] = user.note or '' data['group'] = map(lambda x: x.group.name, getattr(user, 'groups', [])) data.update(user.settings or {}) data['settings'] = user.settings or {} data['guest'] = str(int(user.guest)) # '1' or '0' self.modified = True except Exception: data = self._create_guest() return data def _precache(self, info, force=False): """Calculate permissions for user actions. FIXME: compatibility layer only !!! """ try: from invenio_accounts.models import User except ImportError: return {} CFG_BIBAUTHORID_ENABLED = current_app.config.get( 'CFG_BIBAUTHORID_ENABLED', False) # get authorization 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) user = User.query.get(user_info['uid']) from invenio_access.engine import acc_authorize_action from invenio_access.control import acc_get_role_id, \ acc_is_user_in_role from invenio_search.utils import \ get_permitted_restricted_collections from invenio_deposit.cache import \ get_authorized_deposition_types data = {} data['precached_permitted_restricted_collections'] = \ get_permitted_restricted_collections(user_info) data['precached_allowed_deposition_types'] = \ get_authorized_deposition_types(user_info) data['precached_useloans'] = acc_authorize_action( user_info, 'useloans')[0] == 0 data['precached_usegroups'] = acc_authorize_action( user_info, 'usegroups')[0] == 0 data['precached_usemessages'] = acc_authorize_action( user_info, 'usemessages')[0] == 0 data['precached_useadmin'] = user.has_admin_role data['precached_usesuperadmin'] = user.has_super_admin_role 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 (current_app.config.get('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 timeout = current_app.config.get( 'CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT', 0) * 3600 cache.set(acc_key, data, timeout=timeout) return data def is_authenticated(self): """Check if user is authenticated.""" return not self.is_guest def is_authorized(self, name, **kwargs): """Check if user is authorized.""" from invenio_access.engine import acc_authorize_action return acc_authorize_action(self, name)[0] == 0 def is_active(self): """Check if user is active.""" return not self.is_guest def is_confirmed(self): """Return true if accounts has been confirmed.""" return self['note'] == "1" @property def is_guest(self): """Check if user is guest.""" return True if self['email'] == '' else False @property def is_admin(self): """Check if user is admin.""" return self.get('precached_useadmin', False) @property def is_super_admin(self): """Check if user is super admin.""" return self.get('precached_usesuperadmin', False) def get_id(self): """Get user id.""" return self.get('id', -1)
class UserInfo(CombinedMultiDict, UserMixin): """ This provides legacy implementations for the methods that Flask-Login and Invenio 1.x expects user objects to have. """ def __init__(self, uid=None, force=False): """Retreave information about user.""" def on_update(self): """ Changes own status when the user info is modified. """ self.modified = True self.modified = False self.uid = uid self.req = self._get_request_info() acc = {} if uid is not None and uid > 0: data = self._login(uid, force) acc = self._precache(data, force) else: data = self._create_guest() self.info = CallbackDict(data, on_update) # FIXME remove req after everybody start using flask request. CombinedMultiDict.__init__(self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def get_key(self): """Generates key for caching user information.""" key = 'current_user::' + str(self.uid) return key def get_acc_key(self): """Generates key for caching autorizations.""" remote_ip = str(request.remote_addr) if has_request_context() else '0' return 'current_user::' + str(self.uid) + '::' + remote_ip def save(self): """Save modified data pernamently for logged users.""" if not self.is_guest and self.modified: timeout = current_app.config.get( 'CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT', 0)*3600 cache.set(self.get_key(), dict(self.info), timeout=timeout) def reload(self): """Reload user login information and saves them.""" data = self._login(self.uid, force=True) acc = self._precache(data, force=True) self.info.update(data) CombinedMultiDict.__init__(self, [self.req, self.info, acc, dict(CFG_USER_DEFAULT_INFO)]) self.save() def update_request_info(self): self.req = self._get_request_info() def _get_request_info(self): """Get request information.""" # FIXME: we should support IPV6 too. (hint for FireRole) data = {} if has_request_context(): data['remote_ip'] = request.remote_addr or '' data['remote_host'] = request.environ.get('REMOTE_HOST', '') data['referer'] = request.referrer data['uri'] = request.environ['PATH_INFO'] or '' data['agent'] = request.headers.get('User-Agent', 'N/A') return data def _create_guest(self): data = {'settings': {}} if current_app.config.get( 'CFG_WEBSESSION_DIFFERENTIATE_BETWEEN_GUESTS', False): from invenio.ext.sqlalchemy import db from invenio.modules.accounts.models import User note = '1' if current_app.config.get( 'CFG_ACCESS_CONTROL_LEVEL_GUESTS', 0) == 0 else '0' u = User(email='', note=note, password='******') db.session.add(u) db.session.commit() data.update(u.__dict__) else: # Minimal information about user. data['id'] = data['uid'] = 0 return data def _login(self, uid, force=False): """Get account information about currently logged user from database. Should raise an exception when session.uid is not valid User.id. """ data = cache.get(self.get_key()) if not force and data is not None: return data from invenio.modules.accounts.models import User data = {} try: user = User.query.get(uid) data['id'] = data['uid'] = user.id or -1 data['nickname'] = user.nickname or '' data['email'] = user.email or '' data['note'] = user.note or '' data['group'] = map(lambda x: x.usergroup.name, user.usergroups or []) data.update(user.settings or {}) data['settings'] = user.settings or {} data['guest'] = str(int(user.guest)) # '1' or '0' self.modified = True except: data = self._create_guest() return data def _precache(self, info, force=False): """Calculate prermitions for user actions. FIXME: compatibility layer only !!! """ CFG_BIBAUTHORID_ENABLED = current_app.config.get( 'CFG_BIBAUTHORID_ENABLED', False) # 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.legacy.webuser import isUserSubmitter, isUserReferee, \ isUserAdmin, isUserSuperAdmin from invenio.modules.access.engine import acc_authorize_action from invenio.modules.access.control import acc_get_role_id, \ acc_is_user_in_role from invenio.legacy.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 try: data['precached_viewsubmissions'] = isUserSubmitter(user_info) except: data['precached_viewsubmissions'] = None 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 (current_app.config.get('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 timeout = current_app.config.get( 'CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT', 0)*3600 cache.set(acc_key, data, timeout=timeout) return data def is_authenticated(self): return not self.is_guest def is_authorized(self, name, **kwargs): from invenio.modules.access.engine import acc_authorize_action return acc_authorize_action(self, name)[0] == 0 def is_active(self): return not self.is_guest @property def is_guest(self): return True if self['email'] == '' else False @property def is_admin(self): return self.get('precached_useadmin', False) @property def is_super_admin(self): return self.get('precached_usesuperadmin', False) def get_id(self): return self.get('id', -1)