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 _setMailText(self): text = self.text if self.note: text = text + "Note: %s" % self.note if self.confSumary: #try: from MaKaC.common.output import outputGenerator from MaKaC.accessControl import AdminList, AccessWrapper import MaKaC.webinterface.urlHandlers as urlHandlers admin = AdminList().getInstance().getList()[0] aw = AccessWrapper() aw.setUser(admin) path = Config.getInstance().getStylesheetsDir() if os.path.exists("%s/text.xsl" % path): stylepath = "%s/text.xsl" % path outGen = outputGenerator(aw) vars = { \ "modifyURL": urlHandlers.UHConferenceModification.getURL( self.conf ), \ "sessionModifyURLGen": urlHandlers.UHSessionModification.getURL, \ "contribModifyURLGen": urlHandlers.UHContributionModification.getURL, \ "subContribModifyURLGen": urlHandlers.UHSubContribModification.getURL, \ "materialURLGen": urlHandlers.UHMaterialDisplay.getURL, \ "resourceURLGen": urlHandlers.UHFileAccess.getURL } confText = outGen.getOutput(self.conf, stylepath, vars) text += "\n\n\n" + confText #except: # text += "\n\n\nSorry could not embed text version of the agenda..." self.mail.setText(text)
def get_suggested_categories(user): """Gets the suggested categories of a user for the dashboard""" from MaKaC.conference import CategoryManager if not redis_write_client: return [] related = user.favorite_categories | user.get_linked_objects('category', 'manager') res = [] for id_, score in suggestions.get_suggestions(user, 'category').iteritems(): try: categ = CategoryManager().getById(id_) except KeyError: suggestions.unsuggest(user, 'category', id_) continue if not categ or categ.isSuggestionsDisabled() or categ in related: continue if any(p.isSuggestionsDisabled() for p in categ.iterParents()): continue if not categ.canAccess(AccessWrapper(user.as_avatar)): continue res.append({ 'score': score, 'categ': categ, 'path': truncate_path(categ.getCategoryPathTitles()[:-1], chars=50) }) return res
def can_access(self, user, allow_admin=True): if not allow_admin: raise NotImplementedError( 'can_access(..., allow_admin=False) is unsupported until ACLs are migrated' ) from MaKaC.accessControl import AccessWrapper return self.as_legacy.canAccess( AccessWrapper(user.as_avatar if user else None))
def __init__(self): self.closed = False self.xml_generator = XMLGen() self.xml_generator.initXml() self.xml_generator.openTag(b'collection', [[b'xmlns', b'http://www.loc.gov/MARC21/slim']]) # This is horrible. but refactoring all the code in the indico core would be just as bad. aw = AccessWrapper() aw.setUser(User.find_first(is_admin=True).as_avatar) self.output_generator = outputGenerator(aw, self.xml_generator)
def iter_interesting_events(avatar, data): idx = IndexesHolder().getById('categoryDateAll') now_local = utc2server(nowutc(), False) aw = AccessWrapper() aw.setUser(avatar) for event in _unique_events( idx.iterateObjectsIn('0', now_local, now_local + timedelta(weeks=24))): if _is_event_interesting(avatar, event, data) and event.canAccess(aw): yield event
def _process_PUT(self): category = CategoryManager().getById(request.view_args['category_id']) if category not in self.user.favorite_categories: if not category.canAccess(AccessWrapper(self.user.as_avatar)): raise Forbidden() self.user.favorite_categories.add(category) if redis_write_client: suggestions.unignore(self.user, 'category', category.getId()) suggestions.unsuggest(self.user, 'category', category.getId()) return jsonify(success=True)
def buildAW(ak, onlyPublic=False): aw = AccessWrapper() if ak and not onlyPublic: # If we have an authenticated request, require HTTPS # Dirty hack: Google calendar converts HTTP API requests from https to http # Therefore, not working with Indico setup (requiring https for HTTP API authenticated) if not request.is_secure and api_settings.get( 'require_https') and request.user_agent.browser != 'google': raise HTTPAPIError('HTTPS is required', 403) aw.setUser(ak.user.as_avatar) return aw
def buildAW(ak, req, onlyPublic=False): aw = AccessWrapper() if ak and not onlyPublic: # If we have an authenticated request, require HTTPS minfo = HelperMaKaCInfo.getMaKaCInfoInstance() # Dirty hack: Google calendar converts HTTP API requests from https to http # Therefore, not working with Indico setup (requiring https for HTTP API authenticated) if not req.is_https() and minfo.isAPIHTTPSRequired() and req.get_user_agent().find("Googlebot") == -1: raise HTTPAPIError('HTTPS is required', apache.HTTP_FORBIDDEN) aw.setUser(ak.getUser()) return aw
def can_view(self, user): """Checks if the user can see the folder. This does not mean the user can actually access its contents. It just determines if it is visible to him or not. """ if not self.linked_object.canView( AccessWrapper(user.as_avatar if user else None)): return False return self.is_always_visible or super(AttachmentFolder, self).can_access(user)
def __init__(self): self._responseUtil = ResponseUtil() self._requestStarted = False self._aw = AccessWrapper( ) # Fill in the aw instance with the current information self._target = None self._reqParams = {} self._startTime = None self._endTime = None self._tempFilesToDelete = [] self._redisPipeline = None self._doProcess = True # Flag which indicates whether the RH process
def buildAW(ak, onlyPublic=False): aw = AccessWrapper() aw.setIP(str(request.remote_addr)) if ak and not onlyPublic: # If we have an authenticated request, require HTTPS minfo = HelperMaKaCInfo.getMaKaCInfoInstance() # Dirty hack: Google calendar converts HTTP API requests from https to http # Therefore, not working with Indico setup (requiring https for HTTP API authenticated) if not request.is_secure and minfo.isAPIHTTPSRequired( ) and request.user_agent.browser != 'google': raise HTTPAPIError('HTTPS is required', 403) aw.setUser(ak.getUser()) return aw
def buildCache(ids): i = 1 for id in ids: DBMgr.getInstance().startRequest() try: conf = ConferenceHolder().getById(id) except: print "conf %s not found" continue print i, ":", conf.getId() og = outputGenerator(AccessWrapper()) x = og.confToXML(conf, 1, 1, 1, overrideCache=True) y = og.confToXMLMarc21(conf, 1, 1, 1, overrideCache=True) i += 1 DBMgr.getInstance().endRequest()
def __init__(self, params): if not self.UNICODE_PARAMS: params = unicode_struct_to_utf8(params) self._reqParams = self._params = params self._requestStarted = False # Fill in the aw instance with the current information self._aw = AccessWrapper() self._aw.setUser(session.avatar) self._target = None self._startTime = None self._tohttps = request.is_secure self._endTime = None self._doProcess = True #Flag which indicates whether the RH process # must be carried out; this is useful for # the checkProtection methods self._tempFilesToDelete = [] self._redisPipeline = None
def __init__(self, req=None): """Constructor. Initialises the rh setting up basic attributes so it is able to process the request. Parameters: req - OBSOLETE, MUST BE NONE """ RequestHandlerBase.__init__(self, req) self._responseUtil = ResponseUtil() self._requestStarted = False self._aw = AccessWrapper( ) # Fill in the aw instance with the current information self._target = None self._reqParams = {} self._startTime = None self._endTime = None self._tempFilesToDelete = [] self._redisPipeline = None self._doProcess = True # Flag which indicates whether the RH process
def __init__(self, req): """Constructor. Initialises the rh setting up basic attributes so it is able to process the request. Parameters: req - (mod_python.Request) mod_python request received for the current rh. """ RequestHandlerBase.__init__(self, req) self._requestStarted = False self._websession = None self._aw = AccessWrapper( ) #Fill in the aw instance with the current information self._target = None self._reqParams = {} self._startTime = None self._endTime = None self._tempFilesToDelete = [] self._doProcess = True #Flag which indicates whether the RH process
def buildCache(ids): i = 1 for id in ids: DBMgr.getInstance().startRequest() try: conf = ConferenceHolder().getById(id) except: print "conf %s not found" continue j = 1 for cont in conf.getContributionList(): print "conf %d:%s - contrib %d:%s"%(i, conf.getId(), j, cont.getId()) og = outputGenerator(AccessWrapper()) x = og.contribToXMLMarc21(cont, 1, overrideCache=True) for subCont in cont.getSubContributionList(): print "conf %d:%s - contrib %d:%s - subContrib:%s"%(i, conf.getId(), j, cont.getId(), subCont.getId()) y = og.subContribToXMLMarc21(subCont, 1, overrideCache=True) j += 1 i += 1 DBMgr.getInstance().endRequest()
def __init__(self, params, remoteHost, session): """ Constructor. Initializes provate variables @param req: HTTP Request provided by the previous layer """ self._params = params self._requestStarted = False self._websession = session # Fill in the aw instance with the current information self._aw = AccessWrapper() self._aw.setIP(remoteHost) self._aw.setSession(session) self._aw.setUser(session.getUser()) self._target = None self._startTime = None self._endTime = None self._doProcess = True #Flag which indicates whether the RH process # must be carried out; this is useful for # the checkProtection methods self._tempFilesToDelete = []
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 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 = [(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 _checkProtection(self): RHNoteBase._checkProtection(self) if not self.object.canAccess(AccessWrapper(session.avatar)): raise Forbidden
def can_access(self, user, allow_admin=True): """Checks if the user can access the object. :param user: The :class:`.User` to check. May be None if the user is not logged in. :param allow_admin: If admin users should always have access """ # Trigger signals for protection overrides rv = values_from_signal(signals.acl.can_access.send( type(self), obj=self, user=user, allow_admin=allow_admin), single_value=True) if rv: # in case of contradictory results (shouldn't happen at all) # we stay on the safe side and deny access return all(rv) # Usually admins can access everything, so no need for checks if allow_admin and user and user.is_admin: return True if self.protection_mode == ProtectionMode.public: # if it's public we completely ignore the parent protection # this is quite ugly which is why it should only be allowed # in rare cases (e.g. events which might be in a protected # category but should be public nonetheless) return True elif self.protection_mode == ProtectionMode.protected: # if it's protected, we also ignore the parent protection # and only check our own ACL if user is None: return False elif any(user in entry.principal for entry in iter_acl(self.acl_entries)): return True elif isinstance(self, ProtectionManagersMixin): return self.can_manage(user, allow_admin=allow_admin) else: return False elif self.protection_mode == ProtectionMode.inheriting: # if it's inheriting, we only check the parent protection # unless `inheriting_have_acl` is set, in which case we # might not need to check the parents at all if (self.inheriting_have_acl and user is not None and any(user in entry.principal for entry in iter_acl(self.acl_entries))): return True # the parent can be either an object inheriting from this # mixin or a legacy object with an AccessController parent = self.protection_parent if parent is None: # This should be the case for the top-level object, # i.e. the root category, which shouldn't allow # ProtectionMode.inheriting as it makes no sense. raise TypeError('protection_parent of {} is None'.format(self)) elif hasattr(parent, 'can_access'): return parent.can_access(user, allow_admin=allow_admin) elif hasattr(parent, 'canAccess'): return parent.canAccess( AccessWrapper(user.as_avatar if user else None)) else: raise TypeError( 'protection_parent of {} is of invalid type {} ({})'. format(self, type(parent), parent)) else: # should never happen, but since this is a sensitive area # we better fail loudly if we have garbage raise ValueError('Invalid protection mode: {}'.format( self.protection_mode))
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 _getAW(self): return AccessWrapper(session.avatar)