def _run(self): Logger.get('OfflineEventGeneratorTask').info("Started generation of the offline website for task: %s" % self._task.id) setLocale(self._task.avatar.getLang()) self._rh = RHCustomizable() self._aw = self._rh._aw = AccessWrapper() self._rh._conf = self._rh._target = self._task.conference ContextManager.set('currentRH', self._rh) ContextManager.set('offlineMode', True) # Get event type wf = self._rh.getWebFactory() if wf: eventType = wf.getId() else: eventType = "conference" try: websiteZipFile = OfflineEvent(self._rh, self._rh._conf, eventType).create() except Exception, e: Logger.get('OfflineEventGeneratorTask').exception("Generation of the offline website for task %s failed \ with message error: %s" % (self._task.id, e)) self._task.status = "Failed" return
def _run(self): Logger.get('OfflineEventGeneratorTask').info( "Started generation of the offline website for task: %s" % self._task.id) setLocale(self._task.avatar.getLang()) self._rh = RHCustomizable() self._aw = self._rh._aw = AccessWrapper() self._rh._conf = self._rh._target = self._task.conference ContextManager.set('currentRH', self._rh) ContextManager.set('offlineMode', True) # Get event type wf = self._rh.getWebFactory() if wf: eventType = wf.getId() else: eventType = "conference" try: websiteZipFile = OfflineEvent(self._rh, self._rh._conf, eventType).create() except Exception, e: Logger.get('OfflineEventGeneratorTask').exception( "Generation of the offline website for task %s failed \ with message error: %s" % (self._task.id, e)) self._task.status = "Failed" return
def _initializeMenuItensComponents(self): self._menu_offline_items["programme"] = WPStaticConferenceProgram(self._rh, self._conf) self._menu_offline_items["timetable"] = WPStaticConferenceTimeTable(self._rh, self._conf) self._menu_offline_items["authorIndex"] = WPStaticAuthorIndex(self._rh, self._conf) self._menu_offline_items["speakerIndex"] = WPStaticSpeakerIndex(self._rh, self._conf) self._menu_offline_items["contributionList"] = WPStaticContributionList(self._rh, self._conf) self._menu_offline_items["registrants"] = WPStaticConfRegistrantsList(self._rh, self._conf) ContextManager.set("_menu_offline_items", self._menu_offline_items)
def _wrapper(self, func, *args, **kwargs): # if there is a locale already defined, use it # (unless we have forced "lazy mode") if 'translation' in ContextManager.get() and not self.force: # straight translation translation = ContextManager.get('translation') return getattr(translation, func)(*args, **kwargs) else: # otherwise, defer translation to eval time return LazyProxy(_tr_eval, func, *args, **kwargs)
def main(self, testsToRun, options): """ Runs the main test cycle, iterating over all the TestRunners available * testsToRun - a list of strings specifying which tests to run * options - test options (such as verbosity...) """ result = False killself = options.pop('killself', False) TestManager._title("Starting test framework\n") # the SMTP server will choose a free port smtpAddr = self._startSMTPServer() self._startManageDB() self._setFakeConfig({"SmtpServer": smtpAddr}) if 'functional' in testsToRun: serverAddr = self._runFakeWebServer() baseURL = "http://{0}:{1}".format(*serverAddr) else: baseURL = "http://localhost:8000" self._cfg._configVars.update({"BaseURL": baseURL}) ContextManager.set('test_env', True) try: for test in testsToRun: if test in TEST_RUNNERS: try: result = TEST_RUNNERS[test](**options).run() except TestOptionException, e: TestManager._error(e) else: print colored( "[ERR] Test set '%s' does not exist. " "It has to be added in the TEST_RUNNERS variable\n", 'red') % test finally: # whatever happens, clean this mess up self._stopManageDB(killself) self._stopSMTPServer() if killself: # Forcefully kill ourselves. This avoids waiting for the db to shutdown (SLOW) self._info( 'Committing suicide to avoid waiting for slow database shutdown' ) os.kill(os.getpid(), 9) if result: return 0 else: return -1
def _tr_eval(func, *args, **kwargs): # ok, eval time... is there a translation? if 'translation' in ContextManager.get(): # yes? good, let's do it tr = ContextManager.get('translation') else: # no? too bad, just don't translate anything tr = nullTranslations res = getattr(tr, func)(*args, **kwargs).encode('utf-8') return res
def main(self, testsToRun, options): """ Runs the main test cycle, iterating over all the TestRunners available * testsToRun - a list of strings specifying which tests to run * options - test options (such as verbosity...) """ result = False killself = options.pop('killself', False) TestManager._title("Starting test framework\n") # the SMTP server will choose a free port smtpAddr = self._startSMTPServer() self._startManageDB() self._setFakeConfig({"SmtpServer": smtpAddr}) if 'functional' in testsToRun: serverAddr = self._runFakeWebServer() baseURL = "http://{0}:{1}".format(*serverAddr) else: baseURL = "http://localhost:8000/indico" self._cfg._configVars.update({"BaseURL": baseURL}) ContextManager.set('test_env', True) try: for test in testsToRun: if test in TEST_RUNNERS: try: result = TEST_RUNNERS[test](**options).run() except TestOptionException, e: TestManager._error(e) else: print colored("[ERR] Test set '%s' does not exist. " "It has to be added in the TEST_RUNNERS variable\n", 'red') % test finally: # whatever happens, clean this mess up self._stopManageDB(killself) self._stopSMTPServer() if killself: # Forcefully kill ourselves. This avoids waiting for the db to shutdown (SLOW) self._info('Committing suicide to avoid waiting for slow database shutdown') os.kill(os.getpid(), 9) if result: return 0 else: return -1
def _define_lookup(): return IndicoTemplateLookup(directories=[TEMPLATE_DIR], module_directory=os.path.join(Config.getInstance().getTempDir(), "mako_modules"), disable_unicode=True, filesystem_checks=True, imports=FILTER_IMPORTS, cache_enabled=not ContextManager.get('offlineMode'))
def url(self): # explicit _external=False since offline site creation forces # _external=True if not specified and we want to be able to mangle # the generated urls into something suitable as filenames if self.is_user_link: return self.link_url elif self.is_internal_link: data = self.default_data if data.static_site and isinstance(data.static_site, basestring) and ContextManager.get('offlineMode'): return data.static_site kwargs = {} if self.name == 'timetable': from indico.modules.events. layout import layout_settings if layout_settings.get(self.event, 'timetable_by_room'): kwargs['ttLyt'] = 'room' if layout_settings.get(self.event, 'timetable_detailed'): start_date = self.event.getSchedule().getAdjustedStartDate() kwargs['_anchor'] = start_date.strftime('%Y%m%d.detailed') return url_for(data.endpoint, self.event, _external=False, **kwargs) elif self.is_plugin_link: from indico.core.plugins import url_for_plugin return url_for_plugin(self.default_data.endpoint, self.event, _external=False) elif self.is_page: return url_for('event_pages.page_display', self.event, page_id=self.page_id, slug=slugify(self.title), _external=False) else: return None
def getInstance(cls): connector = ContextManager.get('ldap.connector', default=None) if not connector: connector = cls() connector.open() connector.login() return connector
def getPluginIconURL( self, pluginName, iconId ): rh = ContextManager.get('currentRH', None) if rh and request.is_secure and self.getBaseSecureURL(): baseURL = self.getBaseSecureURL() else: baseURL = self.getBaseURL() return "%s/%s/images/%s.png"%(baseURL, pluginName, iconId)
def getPluginIconURL(self, pluginName, iconId): rh = ContextManager.get('currentRH', None) if rh and rh._req.is_https() and self.getBaseSecureURL(): baseURL = self.getBaseSecureURL() else: baseURL = self.getBaseURL() return "%s/%s/images/%s.png" % (baseURL, pluginName, iconId)
def url_for(endpoint, *targets, **values): """Wrapper for Flask's url_for() function. Instead of an endpoint you can also pass an URLHandler - in this case **only** its _endpoint will be used. However, there is usually no need to do so. This is just so you can use it in places where sometimes a UH might be passed instead. The `target` argument allows you to pass some object having a `locator` property or `getLocator` method returning a dict. This should be used e.g. when generating an URL for an event since ``getLocator()`` provides the ``{'confId': 123}`` dict instead of you having to pass ``confId=event.getId()`` as a kwarg. For details on Flask's url_for, please see its documentation. Anyway, the important arguments you can put in `values` besides actual arguments are: _external: if set to `True`, an absolute URL is generated _secure: if True/False, set _scheme to https/http if possible (only with _external) _scheme: a string specifying the desired URL scheme (only with _external) - use _secure if possible! _anchor: if provided this is added as #anchor to the URL. """ if hasattr(endpoint, '_endpoint'): endpoint = endpoint._endpoint secure = values.pop('_secure', None) if secure is not None: from indico.core.config import Config if secure and Config.getInstance().getBaseSecureURL(): values['_scheme'] = 'https' elif not secure: values['_scheme'] = 'http' if targets: locator = {} for target in targets: if target: # don't fail on None or mako's Undefined locator.update(get_locator(target)) intersection = set(locator.iterkeys()) & set(values.iterkeys()) if intersection: raise ValueError('url_for kwargs collide with locator: %s' % ', '.join(intersection)) values.update(locator) static_site_mode = bool(ContextManager.get('offlineMode')) values.setdefault('_external', static_site_mode) for key, value in values.iteritems(): # Avoid =True and =False in the URL if isinstance(value, bool): values[key] = int(value) url = _url_for(endpoint, **values) if static_site_mode and not values['_external']: # for static sites we assume all relative urls need to be # mangled to a filename # we should really fine a better way to handle anything # related to offline site urls... from indico.modules.events.static.util import url_to_static_filename url = url_to_static_filename(url) return url
def add(self, newItem): oid = "" try: oid = newItem._p_oid except: raise MaKaCError( _("Cannot put an object which is not persistent in the trash can.")) tree = self._getIdx() if not (ContextManager.get('test_env')): tree[oid] = newItem
def getCssConfTemplateBaseURL(self): rh = ContextManager.get('currentRH', None) if rh and request.is_secure and self.getBaseSecureURL(): baseURL = self.getBaseSecureURL() else: baseURL = self.getBaseURL() return "%s/css/confTemplates" % baseURL
class OfflineEventGeneratorTask(OneShotTask): def __init__(self, task): super(OfflineEventGeneratorTask, self).__init__(task.requestTime) self._task = task def run(self): with current_app.test_request_context(): self._run() def _run(self): Logger.get('OfflineEventGeneratorTask').info( "Started generation of the offline website for task: %s" % self._task.id) setLocale(self._task.avatar.getLang()) self._rh = RHCustomizable() self._aw = self._rh._aw = AccessWrapper() self._rh._conf = self._rh._target = self._task.conference ContextManager.set('currentRH', self._rh) ContextManager.set('offlineMode', True) # Get event type wf = self._rh.getWebFactory() if wf: eventType = wf.getId() else: eventType = "conference" try: websiteZipFile = OfflineEvent(self._rh, self._rh._conf, eventType).create() except Exception, e: Logger.get('OfflineEventGeneratorTask').exception( "Generation of the offline website for task %s failed \ with message error: %s" % (self._task.id, e)) self._task.status = "Failed" return self._task.creationTime = nowutc() if not websiteZipFile: Logger.get('OfflineEventGeneratorTask').info( "Generation of the offline website for task %s failed" % self._task.id) self._task.status = "Failed" return self._task.status = "Generated" self._task.file = websiteZipFile Logger.get('OfflineEventGeneratorTask').info( "Finished generation of the offline website for task %s" % self._task.id) ContextManager.set('offlineMode', False) notification = OfflineEventGeneratedNotification(self._task) GenericMailer.sendAndLog(notification, self._task.conference, "OfflineEventGenerator")
def _wrapper(*args, **kwargs): # if there are kwargs, skip caching if kwargs: return f(*args, **kwargs) else: # create a unique key k = (f, args) cache = ContextManager.setdefault('request_cache', {}) if k not in cache: cache[k] = f(*args) return cache[k]
def is_visible(self): if not self.is_enabled: return False if not self.name: return True if self.is_orphaned: return False data = self.default_data if not data.static_site and ContextManager.get('offlineMode'): return False return data.visible(self.event)
def setNotifyMgrNewParticipant(self, value): currentUser = ContextManager.get('currentUser') self._notifyMgrNewParticipant = value logData = {} if value: logData["subject"] = _("Manager notification of participant application has been enabled") else: logData["subject"] = _("Manager notification of participant application has been disabled") self._conference.getLogHandler().logAction(logData, "participants", currentUser) self.notifyModification()
def _define_lookup(): # TODO: disable_unicode shouldn't be used # since unicode is disabled, template waits for # byte strings provided by default_filters # i.e converting SQLAlchemy model unicode properties to byte strings return IndicoTemplateLookup(directories=[TEMPLATE_DIR], module_directory=os.path.join(Config.getInstance().getTempDir(), "mako_modules"), disable_unicode=True, input_encoding='utf-8', default_filters=['encode_if_unicode', 'str'], filesystem_checks=True, imports=FILTER_IMPORTS, cache_enabled=not ContextManager.get('offlineMode'))
def get_download_url(self, absolute=False): """Returns the download url for the attachment. During static site generation this returns a local URL for the file or the target URL for the link. :param absolute: If the returned URL should be absolute. """ if ContextManager.get('offlineMode'): return _offline_download_url(self) else: filename = self.file.filename if self.type == AttachmentType.file else 'go' return url_for('attachments.download', self, filename=filename, _external=absolute)
def _get_redis_pipeline(): rh = ContextManager.get('currentRH', None) if not rh: # If you are reading this because you tried to use this e.g. in a migration script # or somewhere else outside a RH context: Use `with client.pipeline() as pipe:` and # execute it on your own. The sole reason why this pipeline accessor exists is that # the pipeline can be properly executed/discarded in case of a DB commit/conflict. raise Exception('Cannot get Redis pipeline outside a request') if rh._redisPipeline: return rh._redisPipeline if not client: return None rh._redisPipeline = client.pipeline(transaction=False) return rh._redisPipeline
def setNotifyMgrNewParticipant(self, value): currentUser = ContextManager.get('currentUser') self._notifyMgrNewParticipant = value logData = {} if value: logData["subject"] = _( "Manager notification of participant application has been enabled" ) else: logData["subject"] = _( "Manager notification of participant application has been disabled" ) self._conference.getLogHandler().logAction( logData, log.ModuleNames.PARTICIPANTS) self.notifyModification()
def __init__(self, user, logInfo, module): self._logId = None self._logDate = nowutc() self._logType = "generalLog" # User who has performed / authorised the logged action self._responsibleUser = user if user else ContextManager.get("currentUser") # Indico module, the logged action comes from self._module = module # DICTIONARY containing infos that have to be logged # MUST CONTAIN entry with key : "subject" # keys as well as values should be meaningful self._logInfo = logInfo if self._logInfo.get("subject", None) is None : self._logInfo["subject"] = "%s : %s : %s" % (self._logDate, self._module, self._logType)
def __init__(self, user, logInfo, module): self._logId = None self._logDate = nowutc() self._logType = "generalLog" # User who has performed / authorised the logged action self._responsibleUser = user if user else ContextManager.get( "currentUser") # Indico module, the logged action comes from self._module = module # DICTIONARY containing infos that have to be logged # MUST CONTAIN entry with key : "subject" # keys as well as values should be meaningful self._logInfo = logInfo if self._logInfo.get("subject", None) is None: self._logInfo["subject"] = "%s : %s : %s" % ( self._logDate, self._module, self._logType)
def url(self): # explicit _external=False since offline site creation forces # _external=True if not specified and we want to be able to mangle # the generated urls into something suitable as filenames if self.is_user_link: return self.link_url elif self.is_internal_link: data = self.default_data if data.static_site and isinstance( data.static_site, basestring) and ContextManager.get('offlineMode'): return data.static_site kwargs = {} if self.name == 'timetable': from indico.modules.events.layout import layout_settings if layout_settings.get(self.event, 'timetable_by_room'): kwargs['ttLyt'] = 'room' if layout_settings.get(self.event, 'timetable_detailed'): start_date = self.event.getSchedule().getAdjustedStartDate( ) kwargs['_anchor'] = start_date.strftime('%Y%m%d.detailed') return url_for(data.endpoint, self.event, _external=False, **kwargs) elif self.is_plugin_link: from indico.core.plugins import url_for_plugin return url_for_plugin(self.default_data.endpoint, self.event, _external=False) elif self.is_page: return url_for('event_pages.page_display', self.event, page_id=self.page_id, slug=slugify(self.title), _external=False) else: return None
def build_static_site(static_site): static_site.state = StaticSiteState.running db.session.commit() try: logger.info('Building static site: %s', static_site) session.lang = static_site.creator.settings.get('lang') rh = RHCustomizable() rh._aw = AccessWrapper() rh._conf = rh._target = static_site.event_new.as_legacy g.rh = rh ContextManager.set('currentRH', rh) g.static_site = True # Get event type wf = rh.getWebFactory() event_type = wf.getId() if wf else 'conference' zip_file_path = OfflineEvent(rh, rh._conf, event_type).create(static_site.id) static_site.path = zip_file_path static_site.state = StaticSiteState.success db.session.commit() logger.info('Building static site successful: %s', static_site) g.static_site = False ContextManager.set('currentRH', None) notify_static_site_success(static_site) except Exception: logger.exception('Building static site failed: %s', static_site) static_site.state = StaticSiteState.failed db.session.commit() raise finally: g.static_site = False ContextManager.set('currentRH', None)
def getFontsBaseURL(self): if ContextManager.get('offlineMode', False): return "static/fonts" else: return "%s/fonts" % self.getBaseURL()
def flush_after_commit_queue(execute): queue = ContextManager.get('afterCommitQueue', []) if execute: for func in queue: func() del queue[:]
def getImagesBaseSecureURL(self): if ContextManager.get('offlineMode', False): return "static/images" else: return "%s/images" % self.getBaseSecureURL()
def destroy(self, obj): super(ContextManager_Feature, self).destroy(obj) ContextManager.destroy()
def handler(prefix, path): path = posixpath.join('/', prefix, path) ContextManager.destroy() clearCache() # init fossil cache logger = Logger.get('httpapi') if request.method == 'POST': # Convert POST data to a query string queryParams = dict((key, value.encode('utf-8')) for key, value in request.form.iteritems()) query = urllib.urlencode(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 dbi = DBMgr.getInstance() dbi.startRequest() 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' oauthToken = 'oauth_token' in queryParams # Check if OAuth data is supplied in the Authorization header if not oauthToken and request.headers.get('Authorization') is not None: oauthToken = 'oauth_token' in request.headers.get('Authorization') # 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() try: used_session = None if cookieAuth: used_session = session if not used_session.avatar: # ignore guest sessions used_session = None if apiKey or oauthToken or not used_session: if not oauthToken: # 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 aw = buildAW(ak, onlyPublic) else: # Access Token (OAuth) at = OAuthUtils.OAuthCheckAccessResource() aw = buildAW(at, onlyPublic) # Get rid of API key in cache key if we did not impersonate a user if ak and aw.getUser() 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. if Config.getInstance().getCSRFLevel() >= 2: 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) aw = AccessWrapper() if not onlyPublic: aw.setUser(used_session.avatar) userPrefix = 'user-' + used_session.avatar.getId() + '_' 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 aw.getUser(): 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: ContextManager.set("currentAW", aw) # Perform the actual exporting res = hook(aw) if 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') 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 _get_redis_write_client(): if ContextManager.get('currentRH', None): return _get_redis_pipeline() return _get_redis_client()
def getScriptBaseURL(self): if ContextManager.get("offlineMode", False): return "static/js" else: return url_parse("%s/js" % self.getBaseURL()).path
def handler(prefix, path): path = posixpath.join('/', prefix, path) ContextManager.destroy() 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 dbi = DBMgr.getInstance() dbi.startRequest() 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 aw = buildAW(ak, onlyPublic) else: # Access Token (OAuth) at = load_token(oauth_request.access_token.access_token) aw = buildAW(at, onlyPublic) # Get rid of API key in cache key if we did not impersonate a user if ak and aw.getUser() 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. if Config.getInstance().getCSRFLevel() >= 2: 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) aw = AccessWrapper() if not onlyPublic: aw.setUser(used_session.avatar) 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 aw.getUser(): 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: ContextManager.set("currentAW", aw) # Perform the actual exporting res = hook(aw) 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 handler(req, **params): ContextManager.destroy() logger = Logger.get('httpapi') path, query = req.URLFields['PATH_INFO'], req.URLFields['QUERY_STRING'] if req.method == 'POST': # Convert POST data to a query string queryParams = dict(req.form) for key, value in queryParams.iteritems(): queryParams[key] = [str(value)] query = urllib.urlencode(remove_lists(queryParams)) else: # Parse the actual query string queryParams = parse_qs(query) dbi = DBMgr.getInstance() dbi.startRequest() minfo = HelperMaKaCInfo.getMaKaCInfoInstance() if minfo.getRoomBookingModuleActive(): Factory.getDALManager().connect() 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' # 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 apache.SERVER_RETURN, apache.HTTP_NOT_FOUND # Disable caching if we are not just retrieving data (or the hook requires it) if req.method == 'POST' or hook.NO_CACHE: noCache = True ak = error = result = None ts = int(time.time()) typeMap = {} try: session = None if cookieAuth: session = getSessionForReq(req) if not session.getUser(): # ignore guest sessions session = None if apiKey or not session: # 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 aw = buildAW(ak, req, onlyPublic) # Get rid of API key in cache key if we did not impersonate a user if ak and aw.getUser() 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. if Config.getInstance().getCSRFLevel() >= 2: token = req.headers_in.get('X-CSRF-Token', get_query_parameter(queryParams, ['csrftoken'])) if session.csrf_token != token: raise HTTPAPIError('Invalid CSRF token', apache.HTTP_FORBIDDEN) aw = AccessWrapper() if not onlyPublic: aw.setUser(session.getUser()) userPrefix = 'user-' + session.getUser().getId() + '_' 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 aw.getUser(): raise HTTPAPIError('Not authenticated', apache.HTTP_FORBIDDEN) obj = None 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: # Perform the actual exporting res = hook(aw, req) if 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 = HelperMaKaCInfo.getMaKaCInfoInstance().getAPICacheTTL() cache.set(cacheKey, (result, extra, ts, complete, typeMap), ttl) except HTTPAPIError, e: error = e if e.getCode(): req.status = e.getCode() if req.status == apache.HTTP_METHOD_NOT_ALLOWED: req.headers_out['Allow'] = 'GET' if req.method == 'POST' else 'POST'
def handler(prefix, path): path = posixpath.join('/', prefix, path) ContextManager.destroy() clearCache() # init fossil cache logger = Logger.get('httpapi') if request.method == 'POST': # Convert POST data to a query string queryParams = dict((key, value.encode('utf-8')) for key, value in request.form.iteritems()) query = urllib.urlencode(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 dbi = DBMgr.getInstance() dbi.startRequest() minfo = HelperMaKaCInfo.getMaKaCInfoInstance() if minfo.getRoomBookingModuleActive(): Factory.getDALManager().connect() 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' oauthToken = 'oauth_token' in queryParams # 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() try: used_session = None if cookieAuth: used_session = session if not used_session.user: # ignore guest sessions used_session = None if apiKey or oauthToken or not used_session: if not oauthToken: # 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 aw = buildAW(ak, onlyPublic) else: # Access Token (OAuth) at = OAuthUtils.OAuthCheckAccessResource() aw = buildAW(at, onlyPublic) # Get rid of API key in cache key if we did not impersonate a user if ak and aw.getUser() 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. if Config.getInstance().getCSRFLevel() >= 2: 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) aw = AccessWrapper() if not onlyPublic: aw.setUser(used_session.user) userPrefix = 'user-' + used_session.user.getId() + '_' 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 aw.getUser(): 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: # Perform the actual exporting res = hook(aw) if 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 = HelperMaKaCInfo.getMaKaCInfoInstance().getAPICacheTTL() 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 _checkParams(self, params): l = locators.WebLocator() l.setConference(params) self._conf = self._target = l.getObject() ContextManager.set("currentConference", self._conf)
def getScriptBaseURL(self): if ContextManager.get('offlineMode', False): return 'static/js' else: return url_parse('%s/js' % self.getBaseURL()).path
def getFontsBaseURL(self): if ContextManager.get('offlineMode', False): return "static/fonts" else: return url_parse("%s/fonts" % self.getBaseURL()).path
def getImagesBaseSecureURL(self): if ContextManager.get("offlineMode", False): return "static/images" else: return url_parse("%s/images" % self.getBaseSecureURL()).path
def wrapper(*args, **kwargs): func = partial(f, *args, **kwargs) if not ContextManager.get('currentRH', None): return func() ContextManager.setdefault('afterCommitQueue', []).append(func)
def tearDown( self ): super(TestTasks, self).tearDown() ContextManager.destroy()
def getImagesBaseSecureURL(self): if ContextManager.get('offlineMode', False): return "static/images" else: return url_parse("%s/images" % self.getBaseSecureURL()).path
def _checkParams(self, params): # getById raises a NotFoundError if the event doesn't exist self._conf = self._target = ConferenceHolder().getById( params['confId']) ContextManager.set("currentConference", self._conf)