def _send_confirmation(self, email): token_storage = GenericCache('confirm-email') data = {'email': email, 'user_id': self.user.id} token = make_unique_token(lambda t: not token_storage.get(t)) token_storage.set(token, data, 24 * 3600) send_email(make_email(email, template=get_template_module('users/emails/verify_email.txt', user=self.user, email=email, token=token)))
def principal_from_identifier(identifier, allow_groups=False, allow_external_users=False): # XXX: this is currently only used in PrincipalList # if we ever need to support more than just users and groups, # make sure to add it in here as well from indico.modules.groups import GroupProxy from indico.modules.users import User try: type_, data = identifier.split(':', 1) except ValueError: raise ValueError('Invalid data') if type_ == 'User': try: user_id = int(data) except ValueError: raise ValueError('Invalid data') user = User.get(user_id, is_deleted=False) if user is None: raise ValueError('Invalid user: {}'.format(user_id)) return user elif type_ == 'ExternalUser': if not allow_external_users: raise ValueError('External users are not allowed') cache = GenericCache('external-user') external_user_data = cache.get(data) if not external_user_data: raise ValueError('Invalid data') user = User.query.filter(User.all_emails == external_user_data['email'], ~User.is_deleted).first() if user: return user # create a pending user. this user isn't sent to the DB unless it gets added # to the sqlalchemy session somehow (e.g. by adding it to an ACL). # like this processing form data does not result in something being stored in # the database, which is good! return User(first_name=external_user_data['first_name'], last_name=external_user_data['last_name'], email=external_user_data['email'], affiliation=external_user_data['affiliation'], address=external_user_data['address'], phone=external_user_data['phone'], is_pending=True) elif type_ == 'Group': if not allow_groups: raise ValueError('Groups are not allowed') try: provider, name = data.split(':', 1) except ValueError: raise ValueError('Invalid data') if not provider: # local group try: group_id = int(name) except ValueError: raise ValueError('Invalid data') group = GroupProxy(group_id) else: # multipass group group = GroupProxy(name, provider) if group.group is None: raise ValueError('Invalid group: {}'.format(data)) return group else: raise ValueError('Invalid data')
def unlock_task(name): """Unlock a locked task. :return: ``True`` if the task has been unlocked; ``False`` if it was not locked. """ cache = GenericCache('task-locks') if not cache.get(name): return False cache.delete(name) return True
class ZeepCache(Base): _instance = None def __init__(self, duration=DEFAULT_CACHE_TTL): self._cache = GenericCache("ZeepCache") self._duration = duration def get(self, url): self._cache.get(url) def add(self, url, content): self._cache.set(url, content, self._duration)
def _get_user_data(self): user_id = request.args.get('user') if user_id is None: return {} elif user_id.isdigit(): # existing indico user user = User.find_first(id=user_id, is_deleted=False) user_data = {t.name: getattr(user, t.name, None) if user else '' for t in PersonalDataType} else: # non-indico user data = GenericCache('pending_identities').get(user_id, {}) user_data = {t.name: data.get(t.name) for t in PersonalDataType} user_data['title'] = get_title_uuid(self.regform, user_data['title']) return user_data
def has_member(self, user): if not user: return False cache = GenericCache('group-membership') key = '{}:{}:{}'.format(self.provider, self.name, user.id) rv = cache.get(key) if rv is not None: return rv elif self.group is None: warn('Tried to check if {} is in invalid group {}'.format(user, self)) rv = False else: rv = any(x[1] in self.group for x in user.iter_identifiers(check_providers=True, providers={self.provider})) cache.set(key, rv, 1800) return rv
def get(cls, *args, **kwargs): """Create and return a serializable Report object, retrieved from cache if possible""" from indico_piwik.plugin import PiwikPlugin if not PiwikPlugin.settings.get('cache_enabled'): return cls(*args, **kwargs).to_serializable() cache = GenericCache('Piwik.Report') key = u'{}-{}-{}'.format(cls.__name__, args, kwargs) report = cache.get(key) if not report: report = cls(*args, **kwargs) cache.set(key, report, PiwikPlugin.settings.get('cache_ttl')) return report.to_serializable()
def wrapper(*args, **kwargs): cache = GenericCache('task-locks') name = current_task.name if cache.get(name): Logger.get('celery').warning('Task %s is locked; not executing it. ' 'To manually unlock it, run `indico celery unlock %s`', name, name) return cache.set(name, True, 86400) try: return f(*args, **kwargs) finally: cache.delete(name)
def principal_from_fossil(fossil, allow_pending=False, allow_groups=True, allow_missing_groups=False, allow_emails=False, allow_networks=False, existing_data=None, event=None): from indico.modules.networks.models.networks import IPNetworkGroup from indico.modules.events.models.roles import EventRole from indico.modules.groups import GroupProxy from indico.modules.users import User if existing_data is None: existing_data = set() type_ = fossil['_type'] id_ = fossil['id'] if type_ == 'Avatar': if isinstance(id_, int) or id_.isdigit(): # regular user user = User.get(int(id_)) elif allow_pending: data = GenericCache('pending_identities').get(id_) if not data: raise ValueError("Cannot find user '{}' in cache".format(id_)) data = {k: '' if v is None else v for k, v in data.items()} email = data['email'].lower() # check if there is not already a (pending) user with that e-mail # we need to check for non-pending users too since the search may # show a user from external results even though the email belongs # to an indico account in case some of the search criteria did not # match the indico account user = User.query.filter(User.all_emails == email, ~User.is_deleted).first() if not user: user = User(first_name=data.get('first_name') or '', last_name=data.get('last_name') or '', email=email, address=data.get('address', ''), phone=data.get('phone', ''), affiliation=data.get('affiliation', ''), is_pending=True) db.session.add(user) db.session.flush() else: raise ValueError("Id '{}' is not a number and allow_pending=False".format(id_)) if user is None: raise ValueError('User does not exist: {}'.format(id_)) return user elif allow_emails and type_ == 'Email': return EmailPrincipal(id_) elif allow_networks and type_ == 'IPNetworkGroup': group = IPNetworkGroup.get(int(id_)) if group is None or (group.hidden and group not in existing_data): raise ValueError('IP network group does not exist: {}'.format(id_)) return group elif allow_groups and type_ in {'LocalGroupWrapper', 'LocalGroup'}: group = GroupProxy(int(id_)) if group.group is None: raise ValueError('Local group does not exist: {}'.format(id_)) return group elif allow_groups and type_ in {'LDAPGroupWrapper', 'MultipassGroup'}: provider = fossil['provider'] group = GroupProxy(id_, provider) if group.group is None and not allow_missing_groups: raise ValueError('Multipass group does not exist: {}:{}'.format(provider, id_)) return group elif event and type_ == 'EventRole': role = EventRole.get(id_) role_name = fossil.get('name') if role is None: raise ValueError('Role does not exist: {}:{}'.format(role_name, id_)) if role.event != event: raise ValueError('Role does not belong to provided event: {}:{} - {}'.format(role_name, id_, event)) return role else: raise ValueError('Unexpected fossil type: {}'.format(type_))
import indico from indico.core import signals from indico.core.config import config from indico.core.db import db from indico.core.plugins import url_for_plugin from indico.legacy.common.cache import GenericCache from indico.modules.events.layout import layout_settings from indico.modules.events.layout.models.menu import MenuEntry, MenuEntryType, TransientMenuEntry from indico.util.caching import memoize_request from indico.util.signals import named_objects_from_signal, values_from_signal from indico.util.string import crc32, return_ascii from indico.web.flask.util import url_for _cache = GenericCache('updated-menus') def _menu_entry_key(entry_data): return entry_data.position == -1, entry_data.position, entry_data.name @memoize_request def get_menu_entries_from_signal(): return named_objects_from_signal(signals.event.sidemenu.send(), plugin_attr='plugin') def build_menu_entry_name(name, plugin=None): """ Builds the proper name for a menu entry. Given a menu entry's name and optionally a plugin, returns the
import uuid from flask import request from werkzeug.exceptions import Forbidden, NotFound from indico.legacy.common.cache import GenericCache from indico.modules.designer.models.templates import DesignerTemplate from indico.modules.events.management.controllers import RHManageEventBase from indico.modules.events.management.forms import PosterPrintingForm from indico.modules.events.posters import PosterPDF from indico.util.i18n import _ from indico.web.flask.util import send_file, url_for from indico.web.util import jsonify_data, jsonify_form poster_cache = GenericCache('poster-printing') class RHPosterPrintSettings(RHManageEventBase): ALLOW_LOCKED = True def _process_args(self): RHManageEventBase._process_args(self) self.template_id = request.args.get('template_id') def _process(self): self.commit = False form = PosterPrintingForm(self.event, template=self.template_id) if form.validate_on_submit(): data = dict(form.data) template_id = data.pop('template')
def handler(prefix, path): path = posixpath.join('/', prefix, path) clearCache() # init fossil cache logger = Logger.get('httpapi') if request.method == 'POST': # Convert POST data to a query string queryParams = [(key, [x.encode('utf-8') for x in values]) for key, values in request.form.iterlists()] query = urllib.urlencode(queryParams, doseq=1) # we only need/keep multiple values so we can properly validate the signature. # the legacy code below expects a dict with just the first value. # if you write a new api endpoint that needs multiple values get them from # ``request.values.getlist()`` directly queryParams = {key: values[0] for key, values in queryParams} else: # Parse the actual query string queryParams = dict((key, value.encode('utf-8')) for key, value in request.args.iteritems()) query = request.query_string apiKey = get_query_parameter(queryParams, ['ak', 'apikey'], None) cookieAuth = get_query_parameter(queryParams, ['ca', 'cookieauth'], 'no') == 'yes' signature = get_query_parameter(queryParams, ['signature']) timestamp = get_query_parameter(queryParams, ['timestamp'], 0, integer=True) noCache = get_query_parameter(queryParams, ['nc', 'nocache'], 'no') == 'yes' pretty = get_query_parameter(queryParams, ['p', 'pretty'], 'no') == 'yes' onlyPublic = get_query_parameter(queryParams, ['op', 'onlypublic'], 'no') == 'yes' onlyAuthed = get_query_parameter(queryParams, ['oa', 'onlyauthed'], 'no') == 'yes' scope = 'read:legacy_api' if request.method == 'GET' else 'write:legacy_api' try: oauth_valid, oauth_request = oauth.verify_request([scope]) if not oauth_valid and oauth_request and oauth_request.error_message != 'Bearer token not found.': raise BadRequest('OAuth error: {}'.format( oauth_request.error_message)) elif g.get( 'received_oauth_token' ) and oauth_request.error_message == 'Bearer token not found.': raise BadRequest('OAuth error: Invalid token') except ValueError: # XXX: Dirty hack to workaround a bug in flask-oauthlib that causes it # not to properly urlencode request query strings # Related issue (https://github.com/lepture/flask-oauthlib/issues/213) oauth_valid = False # Get our handler function and its argument and response type hook, dformat = HTTPAPIHook.parseRequest(path, queryParams) if hook is None or dformat is None: raise NotFound # Disable caching if we are not just retrieving data (or the hook requires it) if request.method == 'POST' or hook.NO_CACHE: noCache = True ak = error = result = None ts = int(time.time()) typeMap = {} responseUtil = ResponseUtil() is_response = False try: used_session = None if cookieAuth: used_session = session if not used_session.user: # ignore guest sessions used_session = None if apiKey or oauth_valid or not used_session: if not oauth_valid: # Validate the API key (and its signature) ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp, path, query) if enforceOnlyPublic: onlyPublic = True # Create an access wrapper for the API key's user user = ak.user if ak and not onlyPublic else None else: # Access Token (OAuth) at = load_token(oauth_request.access_token.access_token) user = at.user if at and not onlyPublic else None # Get rid of API key in cache key if we did not impersonate a user if ak and user is None: cacheKey = normalizeQuery( path, query, remove=('_', 'ak', 'apiKey', 'signature', 'timestamp', 'nc', 'nocache', 'oa', 'onlyauthed')) else: cacheKey = normalizeQuery(path, query, remove=('_', 'signature', 'timestamp', 'nc', 'nocache', 'oa', 'onlyauthed')) if signature: # in case the request was signed, store the result under a different key cacheKey = 'signed_' + cacheKey else: # We authenticated using a session cookie. token = request.headers.get( 'X-CSRF-Token', get_query_parameter(queryParams, ['csrftoken'])) if used_session.csrf_protected and used_session.csrf_token != token: raise HTTPAPIError('Invalid CSRF token', 403) user = used_session.user if not onlyPublic else None userPrefix = 'user-{}_'.format(used_session.user.id) cacheKey = userPrefix + normalizeQuery( path, query, remove=('_', 'nc', 'nocache', 'ca', 'cookieauth', 'oa', 'onlyauthed', 'csrftoken')) # Bail out if the user requires authentication but is not authenticated if onlyAuthed and not user: raise HTTPAPIError('Not authenticated', 403) addToCache = not hook.NO_CACHE cache = GenericCache('HTTPAPI') cacheKey = RE_REMOVE_EXTENSION.sub('', cacheKey) if not noCache: obj = cache.get(cacheKey) if obj is not None: result, extra, ts, complete, typeMap = obj addToCache = False if result is None: g.current_api_user = user # Perform the actual exporting res = hook(user) if isinstance(res, current_app.response_class): addToCache = False is_response = True result, extra, complete, typeMap = res, {}, True, {} elif isinstance(res, tuple) and len(res) == 4: result, extra, complete, typeMap = res else: result, extra, complete, typeMap = res, {}, True, {} if result is not None and addToCache: ttl = api_settings.get('cache_ttl') if ttl > 0: cache.set(cacheKey, (result, extra, ts, complete, typeMap), ttl) except HTTPAPIError as e: error = e if e.getCode(): responseUtil.status = e.getCode() if responseUtil.status == 405: responseUtil.headers[ 'Allow'] = 'GET' if request.method == 'POST' else 'POST' if result is None and error is None: # TODO: usage page raise NotFound else: if ak and error is None: # Commit only if there was an API key and no error norm_path, norm_query = normalizeQuery(path, query, remove=('signature', 'timestamp'), separate=True) uri = to_unicode('?'.join(filter(None, (norm_path, norm_query)))) ak.register_used(request.remote_addr, uri, not onlyPublic) db.session.commit() else: # No need to commit stuff if we didn't use an API key (nothing was written) # XXX do we even need this? db.session.rollback() # Log successful POST api requests if error is None and request.method == 'POST': logger.info('API request: %s?%s', path, query) if is_response: return result serializer = Serializer.create(dformat, query_params=queryParams, pretty=pretty, typeMap=typeMap, **hook.serializer_args) if error: if not serializer.schemaless: # if our serializer has a specific schema (HTML, ICAL, etc...) # use JSON, since it is universal serializer = Serializer.create('json') result = fossilize(error) else: if serializer.encapsulate: result = fossilize( HTTPAPIResult(result, path, query, ts, complete, extra), IHTTPAPIExportResultFossil) del result['_fossil'] try: data = serializer(result) serializer.set_headers(responseUtil) return responseUtil.make_response(data) except: logger.exception('Serialization error in request %s?%s', path, query) raise
def handler(prefix, path): path = posixpath.join('/', prefix, path) clearCache() # init fossil cache logger = Logger.get('httpapi') if request.method == 'POST': # Convert POST data to a query string queryParams = [(key, [x.encode('utf-8') for x in values]) for key, values in request.form.iterlists()] query = urllib.urlencode(queryParams, doseq=1) # we only need/keep multiple values so we can properly validate the signature. # the legacy code below expects a dict with just the first value. # if you write a new api endpoint that needs multiple values get them from # ``request.values.getlist()`` directly queryParams = {key: values[0] for key, values in queryParams} else: # Parse the actual query string queryParams = dict((key, value.encode('utf-8')) for key, value in request.args.iteritems()) query = request.query_string apiKey = get_query_parameter(queryParams, ['ak', 'apikey'], None) cookieAuth = get_query_parameter(queryParams, ['ca', 'cookieauth'], 'no') == 'yes' signature = get_query_parameter(queryParams, ['signature']) timestamp = get_query_parameter(queryParams, ['timestamp'], 0, integer=True) noCache = get_query_parameter(queryParams, ['nc', 'nocache'], 'no') == 'yes' pretty = get_query_parameter(queryParams, ['p', 'pretty'], 'no') == 'yes' onlyPublic = get_query_parameter(queryParams, ['op', 'onlypublic'], 'no') == 'yes' onlyAuthed = get_query_parameter(queryParams, ['oa', 'onlyauthed'], 'no') == 'yes' scope = 'read:legacy_api' if request.method == 'GET' else 'write:legacy_api' try: oauth_valid, oauth_request = oauth.verify_request([scope]) if not oauth_valid and oauth_request and oauth_request.error_message != 'Bearer token not found.': raise BadRequest('OAuth error: {}'.format(oauth_request.error_message)) elif g.get('received_oauth_token') and oauth_request.error_message == 'Bearer token not found.': raise BadRequest('OAuth error: Invalid token') except ValueError: # XXX: Dirty hack to workaround a bug in flask-oauthlib that causes it # not to properly urlencode request query strings # Related issue (https://github.com/lepture/flask-oauthlib/issues/213) oauth_valid = False # Get our handler function and its argument and response type hook, dformat = HTTPAPIHook.parseRequest(path, queryParams) if hook is None or dformat is None: raise NotFound # Disable caching if we are not just retrieving data (or the hook requires it) if request.method == 'POST' or hook.NO_CACHE: noCache = True ak = error = result = None ts = int(time.time()) typeMap = {} responseUtil = ResponseUtil() is_response = False try: used_session = None if cookieAuth: used_session = session if not used_session.user: # ignore guest sessions used_session = None if apiKey or oauth_valid or not used_session: if not oauth_valid: # Validate the API key (and its signature) ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp, path, query) if enforceOnlyPublic: onlyPublic = True # Create an access wrapper for the API key's user user = ak.user if ak and not onlyPublic else None else: # Access Token (OAuth) at = load_token(oauth_request.access_token.access_token) user = at.user if at and not onlyPublic else None # Get rid of API key in cache key if we did not impersonate a user if ak and user is None: cacheKey = normalizeQuery(path, query, remove=('_', 'ak', 'apiKey', 'signature', 'timestamp', 'nc', 'nocache', 'oa', 'onlyauthed')) else: cacheKey = normalizeQuery(path, query, remove=('_', 'signature', 'timestamp', 'nc', 'nocache', 'oa', 'onlyauthed')) if signature: # in case the request was signed, store the result under a different key cacheKey = 'signed_' + cacheKey else: # We authenticated using a session cookie. token = request.headers.get('X-CSRF-Token', get_query_parameter(queryParams, ['csrftoken'])) if used_session.csrf_protected and used_session.csrf_token != token: raise HTTPAPIError('Invalid CSRF token', 403) user = used_session.user if not onlyPublic else None userPrefix = 'user-{}_'.format(used_session.user.id) cacheKey = userPrefix + normalizeQuery(path, query, remove=('_', 'nc', 'nocache', 'ca', 'cookieauth', 'oa', 'onlyauthed', 'csrftoken')) # Bail out if the user requires authentication but is not authenticated if onlyAuthed and not user: raise HTTPAPIError('Not authenticated', 403) addToCache = not hook.NO_CACHE cache = GenericCache('HTTPAPI') cacheKey = RE_REMOVE_EXTENSION.sub('', cacheKey) if not noCache: obj = cache.get(cacheKey) if obj is not None: result, extra, ts, complete, typeMap = obj addToCache = False if result is None: g.current_api_user = user # Perform the actual exporting res = hook(user) if isinstance(res, current_app.response_class): addToCache = False is_response = True result, extra, complete, typeMap = res, {}, True, {} elif isinstance(res, tuple) and len(res) == 4: result, extra, complete, typeMap = res else: result, extra, complete, typeMap = res, {}, True, {} if result is not None and addToCache: ttl = api_settings.get('cache_ttl') if ttl > 0: cache.set(cacheKey, (result, extra, ts, complete, typeMap), ttl) except HTTPAPIError, e: error = e if e.getCode(): responseUtil.status = e.getCode() if responseUtil.status == 405: responseUtil.headers['Allow'] = 'GET' if request.method == 'POST' else 'POST'
def __init__(self): self.storage = GenericCache('flask-session')
def __init__(self): self.storage = GenericCache('flask-session')
def principal_from_identifier(identifier, allow_groups=False, allow_external_users=False, allow_event_roles=False, allow_category_roles=False, allow_registration_forms=False, allow_emails=False, allow_networks=False, event_id=None, category_id=None, soft_fail=False): from indico.modules.categories.models.categories import Category from indico.modules.categories.models.roles import CategoryRole from indico.modules.events.models.events import Event from indico.modules.events.models.roles import EventRole from indico.modules.events.registration.models.forms import RegistrationForm from indico.modules.groups import GroupProxy from indico.modules.networks.models.networks import IPNetworkGroup from indico.modules.users import User if allow_category_roles and category_id is None and event_id is None: raise ValueError( 'Cannot use category roles without a category/event context') if allow_event_roles and event_id is None: raise ValueError('Cannot use event roles without an event context') if allow_registration_forms and event_id is None: raise ValueError( 'Cannot use registration forms without an event context') try: type_, data = identifier.split(':', 1) except ValueError: raise ValueError('Invalid data') if type_ == 'User': try: user_id = int(data) except ValueError: raise ValueError('Invalid data') user = User.get(user_id, is_deleted=(None if soft_fail else False)) if user is None: raise ValueError(f'Invalid user: {user_id}') return user elif type_ == 'ExternalUser': if not allow_external_users: raise ValueError('External users are not allowed') cache = GenericCache('external-user') external_user_data = cache.get(data) if not external_user_data: raise ValueError('Invalid data') user = User.query.filter( User.all_emails == external_user_data['email'], ~User.is_deleted).first() if user: return user # create a pending user. this user isn't sent to the DB unless it gets added # to the sqlalchemy session somehow (e.g. by adding it to an ACL). # like this processing form data does not result in something being stored in # the database, which is good! return User(first_name=external_user_data['first_name'], last_name=external_user_data['last_name'], email=external_user_data['email'], affiliation=external_user_data['affiliation'], address=external_user_data['address'], phone=external_user_data['phone'], is_pending=True) elif type_ == 'Group': if not allow_groups: raise ValueError('Groups are not allowed') try: provider, name = data.split(':', 1) except ValueError: raise ValueError('Invalid data') if not provider: # local group try: group_id = int(name) except ValueError: raise ValueError('Invalid data') group = GroupProxy(group_id) else: # multipass group group = GroupProxy(name, provider) if not soft_fail and group.group is None: raise ValueError(f'Invalid group: {data}') return group elif type_ == 'EventRole': if not allow_event_roles: raise ValueError('Event roles are not allowed') try: event_role_id = int(data) except ValueError: raise ValueError('Invalid data') event_role = EventRole.get(event_role_id) if event_role is None or event_role.event_id != event_id: raise ValueError(f'Invalid event role: {event_role_id}') return event_role elif type_ == 'CategoryRole': if not allow_category_roles: raise ValueError('Category roles are not allowed') category = None if category_id is not None: category = Category.get(category_id) if category is None: raise ValueError(f'Invalid category id: {category_id}') elif event_id is not None: event = Event.get(event_id) if event is None: raise ValueError(f'Invalid event id: {event_id}') category = event.category try: category_role_id = int(data) except ValueError: raise ValueError('Invalid data') if soft_fail: category_role = CategoryRole.get(category_role_id) else: category_role = CategoryRole.get_category_role_by_id( category, category_role_id) if category_role is None: raise ValueError(f'Invalid category role: {category_role_id}') return category_role elif type_ == 'RegistrationForm': if not allow_registration_forms: raise ValueError('Registration forms are not allowed') try: reg_form_id = int(data) except ValueError: raise ValueError('Invalid data') registration_form = RegistrationForm.get( reg_form_id, is_deleted=(None if soft_fail else False)) if registration_form is None or registration_form.event_id != event_id: raise ValueError(f'Invalid registration form: {reg_form_id}') return registration_form elif type_ == 'Email': if not allow_emails: raise ValueError('Emails are not allowed') return EmailPrincipal(data) elif type_ == 'IPNetworkGroup': if not allow_networks: raise ValueError('Network groups are not allowed') try: netgroup_id = int(data) except ValueError: raise ValueError('Invalid data') netgroup = IPNetworkGroup.get(netgroup_id) if netgroup is None or (netgroup.hidden and not soft_fail): raise ValueError(f'Invalid network group: {netgroup_id}') return netgroup else: raise ValueError('Invalid data')
def __init__(self, duration=DEFAULT_CACHE_TTL): self._cache = GenericCache("ZeepCache") self._duration = duration
def __init__(self, duration=DEFAULT_CACHE_TTL): self._cache = GenericCache("ZeepCache") self._duration = duration
from indico.modules.events.sessions import Session from indico.modules.events.timetable.forms import ImportContributionsForm from indico.modules.events.timetable.operations import update_timetable_entry from indico.modules.events.tracks.models.tracks import Track from indico.modules.events.util import check_event_locked, get_field_values, track_time_changes from indico.util.date_time import format_datetime, format_human_timedelta from indico.util.i18n import _, ngettext from indico.util.spreadsheets import send_csv, send_xlsx from indico.util.string import handle_legacy_description from indico.web.flask.templating import get_template_module from indico.web.flask.util import send_file, url_for from indico.web.forms.base import FormDefaults from indico.web.forms.fields.principals import serialize_principal from indico.web.util import jsonify_data, jsonify_form, jsonify_template export_list_cache = GenericCache('export-list') def _render_subcontribution_list(contrib): tpl = get_template_module( 'events/contributions/management/_subcontribution_list.html') subcontribs = (SubContribution.query.with_parent(contrib).options( undefer('attachment_count')).order_by(SubContribution.position).all()) return tpl.render_subcontribution_list(contrib.event, contrib, subcontribs) class RHManageContributionsBase(RHManageEventBase): """Base class for all contributions management RHs.""" def _process_args(self): RHManageEventBase._process_args(self) self.list_generator = ContributionListGenerator(event=self.event)
from indico.modules.events.registration.util import ( create_registration, generate_spreadsheet_from_registrations, get_event_section_data, get_ticket_attachments, get_title_uuid, make_registration_form) from indico.modules.events.registration.views import WPManageRegistration from indico.modules.events.util import ZipGeneratorMixin from indico.modules.users import User from indico.util.fs import secure_filename from indico.util.i18n import _, ngettext from indico.util.placeholders import replace_placeholders from indico.util.spreadsheets import send_csv, send_xlsx from indico.web.flask.templating import get_template_module from indico.web.flask.util import send_file, url_for from indico.web.util import jsonify_data, jsonify_template badge_cache = GenericCache('badge-printing') def _render_registration_details(registration): event = registration.registration_form.event tpl = get_template_module( 'events/registration/management/_registration_details.html') return tpl.render_registration_details( registration=registration, payment_enabled=event.has_feature('payment')) class RHRegistrationsListManage(RHManageRegFormBase): """List all registrations of a specific registration form of an event""" def _process(self): if self.list_generator.static_link_used:
def _process_pending_users(self, results): cache = GenericCache('external-user') for entry in results: ext_id = entry.pop('_ext_id', None) if ext_id is not None: cache.set(ext_id, self.externals[ext_id], 86400)
reservation_occurrences_schema, reservation_user_event_schema) from indico.modules.rb.util import ( generate_spreadsheet_from_occurrences, get_linked_object, group_by_occurrence_date, is_booking_start_within_grace_period, serialize_availability, serialize_booking_details, serialize_occurrences) from indico.util.date_time import now_utc, utc_to_server from indico.util.i18n import _ from indico.util.spreadsheets import send_csv, send_xlsx from indico.web.args import use_args, use_kwargs from indico.web.flask.util import url_for from indico.web.util import ExpectedError NUM_SUGGESTIONS = 5 _export_cache = GenericCache('bookings-export') class RHTimeline(RHRoomBookingBase): def _process_args(self): self.room = None if 'room_id' in request.view_args: self.room = Room.get_one(request.view_args['room_id'], is_deleted=False) @use_kwargs({ 'start_dt': fields.DateTime(required=True), 'end_dt': fields.DateTime(required=True), 'repeat_frequency': EnumField(RepeatFrequency, missing='NEVER'), 'repeat_interval': fields.Int(missing=1), 'room_ids': fields.List(fields.Int(), missing=[]),
def load_error_data(uuid): return GenericCache('errors').get(uuid)
class IndicoSessionInterface(SessionInterface): pickle_based = True serializer = cPickle session_class = IndicoSession temporary_session_lifetime = timedelta(days=7) def __init__(self): self.storage = GenericCache('flask-session') def generate_sid(self): return str(uuid.uuid4()) def get_cookie_secure(self, app): return request.is_secure def get_storage_lifetime(self, app, session): # Permanent sessions are stored for exactly the same duration as the session id cookie. # "Temporary" session are stored for a period that is not too short/long as some people # close their browser very rarely and thus shouldn't be logged out that often. if session.permanent: return app.permanent_session_lifetime else: return self.temporary_session_lifetime def should_refresh_session(self, app, session): if session.new or '_expires' not in session: return False threshold = self.get_storage_lifetime(app, session) / 2 return session['_expires'] - datetime.now() < threshold def should_refresh_sid(self, app, session): if not session.new and self.get_cookie_secure(app) and not session.get('_secure'): return True if getattr(session, '_refresh_sid', False): return True return False def open_session(self, app, request): sid = request.cookies.get(app.session_cookie_name) if not sid: return self.session_class(sid=self.generate_sid(), new=True) data = self.storage.get(sid) if data is not None: return self.session_class(self.serializer.loads(data), sid=sid) return self.session_class(sid=self.generate_sid(), new=True) def save_session(self, app, session, response): domain = self.get_cookie_domain(app) secure = self.get_cookie_secure(app) refresh_sid = self.should_refresh_sid(app, session) if not session and not session.new: # empty session, delete it from storage and cookie self.storage.delete(session.sid) response.delete_cookie(app.session_cookie_name, domain=domain) return if not refresh_sid and not session.modified and not self.should_refresh_session(app, session): # If the session has not been modified we only store if it needs to be refreshed return if config.SESSION_LIFETIME > 0: # Setting session.permanent marks the session as modified so we only set it when we # are saving the session anyway! session.permanent = True storage_ttl = self.get_storage_lifetime(app, session) cookie_lifetime = self.get_expiration_time(app, session) session['_expires'] = datetime.now() + storage_ttl if refresh_sid: self.storage.delete(session.sid) session.sid = self.generate_sid() session['_secure'] = request.is_secure self.storage.set(session.sid, self.serializer.dumps(dict(session)), storage_ttl) response.set_cookie(app.session_cookie_name, session.sid, expires=cookie_lifetime, httponly=True, secure=secure)
from indico.modules.rb.models.equipment import EquipmentType, RoomEquipmentAssociation from indico.modules.rb.models.favorites import favorite_room_table from indico.modules.rb.models.principals import RoomPrincipal from indico.modules.rb.models.reservation_occurrences import ReservationOccurrence from indico.modules.rb.models.reservations import Reservation from indico.modules.rb.models.room_attributes import RoomAttribute, RoomAttributeAssociation from indico.modules.rb.models.room_bookable_hours import BookableHours from indico.modules.rb.models.room_nonbookable_periods import NonBookablePeriod from indico.modules.rb.util import rb_is_admin from indico.util.i18n import _ from indico.util.serializer import Serializer from indico.util.string import format_repr, natural_sort_key from indico.web.flask.util import url_for _cache = GenericCache('Rooms') class Room(ProtectionManagersMixin, db.Model, Serializer): __tablename__ = 'rooms' __table_args__ = (db.UniqueConstraint('id', 'location_id'), # useless but needed for the LocationMixin fkey db.CheckConstraint("verbose_name != ''", 'verbose_name_not_empty'), {'schema': 'roombooking'}) default_protection_mode = ProtectionMode.public disallowed_protection_modes = frozenset({ProtectionMode.inheriting}) __api_public__ = ( 'id', 'building', 'name', 'floor', 'longitude', 'latitude', ('number', 'roomNr'), ('location_name', 'location'), ('full_name', 'fullName') )
class IndicoSessionInterface(SessionInterface): pickle_based = True serializer = pickle session_class = IndicoSession temporary_session_lifetime = timedelta(days=7) def __init__(self): self.storage = GenericCache('flask-session') def generate_sid(self): return str(uuid.uuid4()) def get_cookie_secure(self, app): return request.is_secure def get_storage_lifetime(self, app, session): # Permanent sessions are stored for exactly the same duration as the session id cookie. # "Temporary" session are stored for a period that is not too short/long as some people # close their browser very rarely and thus shouldn't be logged out that often. if session.permanent: return app.permanent_session_lifetime else: return self.temporary_session_lifetime def should_refresh_session(self, app, session): if session.new or '_expires' not in session: return False threshold = self.get_storage_lifetime(app, session) / 2 return session['_expires'] - datetime.now() < threshold def should_refresh_sid(self, app, session): if not session.new and self.get_cookie_secure(app) and not session.get('_secure'): return True if getattr(session, '_refresh_sid', False): return True return False def open_session(self, app, request): sid = request.cookies.get(app.session_cookie_name) if not sid: return self.session_class(sid=self.generate_sid(), new=True) data = self.storage.get(sid) if data is not None: return self.session_class(self.serializer.loads(data), sid=sid) return self.session_class(sid=self.generate_sid(), new=True) def save_session(self, app, session, response): domain = self.get_cookie_domain(app) secure = self.get_cookie_secure(app) refresh_sid = self.should_refresh_sid(app, session) if not session and not session.new: # empty session, delete it from storage and cookie self.storage.delete(session.sid) response.delete_cookie(app.session_cookie_name, domain=domain) return if not refresh_sid and not session.modified and not self.should_refresh_session(app, session): # If the session has not been modified we only store if it needs to be refreshed return if config.SESSION_LIFETIME > 0: # Setting session.permanent marks the session as modified so we only set it when we # are saving the session anyway! session.permanent = True storage_ttl = self.get_storage_lifetime(app, session) cookie_lifetime = self.get_expiration_time(app, session) session['_expires'] = datetime.now() + storage_ttl if refresh_sid: self.storage.delete(session.sid) session.sid = self.generate_sid() session['_secure'] = request.is_secure self.storage.set(session.sid, self.serializer.dumps(dict(session)), storage_ttl) response.set_cookie(app.session_cookie_name, session.sid, expires=cookie_lifetime, httponly=True, secure=secure)
def _process_pending_users(self, results): cache = GenericCache('external-user') for entry in results: ext_id = entry.pop('_ext_id', None) if ext_id is not None: cache.set(ext_id, self.externals[ext_id], 86400)
from indico.legacy.common.cache import GenericCache from indico.modules.events.contributions.models.contributions import Contribution from indico.modules.events.editing.controllers.base import ( RHEditablesBase, RHEditableTypeEditorBase, RHEditableTypeManagementBase) from indico.modules.events.editing.models.editable import Editable from indico.modules.events.editing.models.revision_files import EditingRevisionFile from indico.modules.events.editing.models.revisions import EditingRevision from indico.modules.events.editing.operations import assign_editor, generate_editables_zip, unassign_editor from indico.modules.events.editing.schemas import EditableBasicSchema, EditingEditableListSchema, FilteredEditableSchema from indico.modules.files.models.files import File from indico.util.i18n import _ from indico.util.marshmallow import Principal from indico.web.args import use_kwargs from indico.web.flask.util import url_for archive_cache = GenericCache('editables-archive') class RHEditableList(RHEditableTypeEditorBase): """Return the list of editables of the event for a given type.""" def _process_args(self): RHEditableTypeEditorBase._process_args(self) self.contributions = (Contribution.query.with_parent( self.event).options(joinedload('editables')).order_by( Contribution.friendly_id).all()) def _process(self): return (EditingEditableListSchema(many=True, context={ 'editable_type': self.editable_type