Пример #1
0
def generate_public_auth_request(apiKey, path, params=None):
    apiMode = api_settings.get('security_mode')
    if params is None:
        params = {}
    if apiKey:
        key = apiKey.token
        secret_key = apiKey.secret
        persistent = apiKey.is_persistent_allowed and api_settings.get('allow_persistent')
    else:
        key = secret_key = None
        persistent = False
    if api_settings.get('require_https'):
        baseURL = Config.getInstance().getBaseSecureURL()
    else:
        baseURL = Config.getInstance().getBaseURL()
    publicRequestsURL = None
    authRequestURL = None
    if apiMode == APIMode.KEY:
        publicRequestsURL = build_indico_request(path, params)
        authRequestURL = build_indico_request(path, params, key) if key else None
    elif apiMode == APIMode.ONLYKEY:
        authRequestURL = build_indico_request(path, params, key) if key else None
        params["onlypublic"] = "yes"
        publicRequestsURL = build_indico_request(path, params, key) if key else None
    elif apiMode == APIMode.SIGNED:
        publicRequestsURL = build_indico_request(path, params)
        authRequestURL = build_indico_request(path, params, key, secret_key, persistent)  if key and secret_key else None
    elif apiMode == APIMode.ONLYKEY_SIGNED:
        publicRequestsURL = build_indico_request(path, params, key)  if key else None
        authRequestURL = build_indico_request(path, params, key, secret_key, persistent)  if key and secret_key else None
    elif apiMode == APIMode.ALL_SIGNED:
        authRequestURL = build_indico_request(path, params, key, secret_key, persistent)  if key else None
        params["onlypublic"] = "yes"
        publicRequestsURL = build_indico_request(path, params, key, secret_key, persistent)  if key else None
    return {"publicRequestURL": (baseURL + publicRequestsURL) if publicRequestsURL else "", "authRequestURL": (baseURL + authRequestURL) if authRequestURL else ""}
Пример #2
0
def get_base_ical_parameters(user, detail, path, params=None):
    """Returns a dict of all parameters expected by iCal template"""

    from indico.web.http_api.util import generate_public_auth_request

    api_mode = api_settings.get('security_mode')
    persistent_allowed = api_settings.get('allow_persistent')
    api_key = user.api_key if user else None
    persistent_user_enabled = api_key.is_persistent_allowed if api_key else None
    tpl = get_template_module('api/_messages.html')
    persistent_agreement = tpl.get_ical_persistent_msg()
    top_urls = generate_public_auth_request(api_key, path, params)
    urls = generate_public_auth_request(api_key, path,
                                        dict(params or {}, detail=detail))
    request_urls = {
        'publicRequestURL': top_urls['publicRequestURL'],
        'authRequestURL': top_urls['authRequestURL'],
        'publicRequestDetailedURL': urls['publicRequestURL'],
        'authRequestDetailedURL': urls['authRequestURL']
    }

    return {
        'api_mode': api_mode,
        'api_key': api_key,
        'persistent_allowed': persistent_allowed,
        'persistent_user_enabled': persistent_user_enabled,
        'api_active': api_key is not None,
        'api_key_user_agreement': tpl.get_ical_api_key_msg(),
        'api_persistent_user_agreement': persistent_agreement,
        'user_logged': user is not None,
        'request_urls': request_urls
    }
Пример #3
0
def get_base_ical_parameters(user, event, detail, session_=None):
    """Returns a dict of all parameters expected by iCal template"""

    from indico.web.http_api.util import generate_public_auth_request

    api_mode = api_settings.get('security_mode')
    persistent_allowed = api_settings.get('allow_persistent')
    api_key = user.api_key if user else None
    persistent_user_enabled = api_key.is_persistent_allowed if api_key else None
    tpl = get_template_module('api/_messages.html')
    persistent_agreement = tpl.get_ical_persistent_msg()
    if session_:
        path = '/export/event/{0}/session/{1}.ics'.format(event.id, session_.id)
    else:
        path = '/export/event/{0}.ics'.format(event.id)
    top_urls = generate_public_auth_request(api_key, path)
    urls = generate_public_auth_request(api_key, path, {'detail': detail})
    request_urls = {
        'publicRequestURL': top_urls['publicRequestURL'],
        'authRequestURL': top_urls['authRequestURL'],
        'publicRequestDetailedURL': urls['publicRequestURL'],
        'authRequestDetailedURL': urls['authRequestURL']
    }

    return {'api_mode': api_mode, 'api_key': api_key, 'persistent_allowed': persistent_allowed,
            'persistent_user_enabled': persistent_user_enabled, 'api_active': api_key is not None,
            'api_key_user_agreement': tpl.get_ical_api_key_msg(), 'api_persistent_user_agreement': persistent_agreement,
            'user_logged': user is not None, 'request_urls': request_urls}
Пример #4
0
    def getVars( self ):
        from indico.web.http_api.util import generate_public_auth_request

        vars = WHeader.getVars( self )
        vars["categurl"] = self._conf.as_event.category.url

        vars["conf"] = vars["target"] = self._conf

        vars["imgLogo"] = Config.getInstance().getSystemIconURL("miniLogo")
        vars["MaKaCHomeURL"] = self._conf.as_event.category.url

        # Default values to avoid NameError while executing the template
        styles = theme_settings.get_themes_for("conference")

        vars["viewoptions"] = [{'id': theme_id, 'name': data['title']}
                               for theme_id, data in sorted(styles.viewitems(), key=lambda x: x[1]['title'])]
        vars["SelectedStyle"] = ""
        vars["pdfURL"] = ""
        vars["displayURL"] = str(urlHandlers.UHConferenceOtherViews.getURL(self._conf))

        # Setting the buttons that will be displayed in the header menu
        vars["showFilterButton"] = False
        vars["showMoreButton"] = True
        vars["showExportToICal"] = True
        vars["showExportToPDF"] = False
        vars["showDLMaterial"] = True
        vars["showLayout"] = True

        vars["displayNavigationBar"] = layout_settings.get(self._conf, 'show_nav_bar')

        # This is basically the same WICalExportBase, but we need some extra
        # logic in order to have the detailed URLs
        apiMode = api_settings.get('security_mode')

        vars["icsIconURL"] = str(Config.getInstance().getSystemIconURL("ical_grey"))
        vars["apiMode"] = apiMode
        vars["signingEnabled"] = apiMode in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED}
        vars["persistentAllowed"] = api_settings.get('allow_persistent')
        user = self._aw.getUser()
        apiKey = user.api_key if user else None

        topURLs = generate_public_auth_request(apiKey, '/export/event/%s.ics' % self._conf.getId())
        urls = generate_public_auth_request(apiKey, '/export/event/%s.ics' % self._conf.getId(),
                                            {'detail': 'contributions'})

        vars["requestURLs"] = {
            'publicRequestURL': topURLs["publicRequestURL"],
            'authRequestURL':  topURLs["authRequestURL"],
            'publicRequestDetailedURL': urls["publicRequestURL"],
            'authRequestDetailedURL':  urls["authRequestURL"]
        }

        vars["persistentUserEnabled"] = apiKey.is_persistent_allowed if apiKey else False
        vars["apiActive"] = apiKey is not None
        vars["userLogged"] = user is not None
        tpl = get_template_module('api/_messages.html')
        vars['apiKeyUserAgreement'] = tpl.get_ical_api_key_msg()
        vars['apiPersistentUserAgreement'] = tpl.get_ical_persistent_msg()

        return vars
Пример #5
0
def validateSignature(ak, signature, timestamp, path, query):
    ttl = api_settings.get('signature_ttl')
    if not timestamp and not (ak.is_persistent_allowed and api_settings.get('allow_persistent')):
        raise HTTPAPIError('Signature invalid (no timestamp)', 403)
    elif timestamp and abs(timestamp - int(time.time())) > ttl:
        raise HTTPAPIError('Signature invalid (bad timestamp)', 403)
    digest = hmac.new(ak.secret, normalizeQuery(path, query), hashlib.sha1).hexdigest()
    if signature != digest:
        raise HTTPAPIError('Signature invalid', 403)
Пример #6
0
 def _process(self):
     key = self.user.api_key
     use_signatures = api_settings.get('security_mode') in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED,
                                                            APIMode.ALL_SIGNED}
     allow_persistent = api_settings.get('allow_persistent')
     old_keys = self.user.old_api_keys
     return WPAPIUserProfile.render_template('user_profile.html', user=self.user, key=key, old_keys=old_keys,
                                             use_signatures=use_signatures, allow_persistent=allow_persistent,
                                             can_modify=(not key or not key.is_blocked or session.user.is_admin))
Пример #7
0
 def _process(self):
     key = self.user.api_key
     use_signatures = api_settings.get('security_mode') in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED,
                                                            APIMode.ALL_SIGNED}
     allow_persistent = api_settings.get('allow_persistent')
     old_keys = self.user.old_api_keys
     return WPAPIUserProfile.render_template('user_profile.html', user=self.user, key=key, old_keys=old_keys,
                                             use_signatures=use_signatures, allow_persistent=allow_persistent,
                                             can_modify=(not key or not key.is_blocked or session.user.is_admin))
Пример #8
0
def validateSignature(ak, signature, timestamp, path, query):
    ttl = api_settings.get('signature_ttl')
    if not timestamp and not (ak.is_persistent_allowed
                              and api_settings.get('allow_persistent')):
        raise HTTPAPIError('Signature invalid (no timestamp)', 403)
    elif timestamp and abs(timestamp - int(time.time())) > ttl:
        raise HTTPAPIError('Signature invalid (bad timestamp)', 403)
    digest = hmac.new(ak.secret, normalizeQuery(path, query),
                      hashlib.sha1).hexdigest()
    if signature != digest:
        raise HTTPAPIError('Signature invalid', 403)
Пример #9
0
def generate_public_auth_request(apiKey, path, params=None):
    apiMode = api_settings.get('security_mode')
    if params is None:
        params = {}
    if apiKey:
        key = apiKey.token
        secret_key = apiKey.secret
        persistent = apiKey.is_persistent_allowed and api_settings.get(
            'allow_persistent')
    else:
        key = secret_key = None
        persistent = False
    if api_settings.get('require_https'):
        baseURL = Config.getInstance().getBaseSecureURL()
    else:
        baseURL = Config.getInstance().getBaseURL()
    publicRequestsURL = None
    authRequestURL = None
    if apiMode == APIMode.KEY:
        publicRequestsURL = build_indico_request(path, params)
        authRequestURL = build_indico_request(path, params,
                                              key) if key else None
    elif apiMode == APIMode.ONLYKEY:
        authRequestURL = build_indico_request(path, params,
                                              key) if key else None
        params["onlypublic"] = "yes"
        publicRequestsURL = build_indico_request(path, params,
                                                 key) if key else None
    elif apiMode == APIMode.SIGNED:
        publicRequestsURL = build_indico_request(path, params)
        authRequestURL = build_indico_request(
            path, params, key, secret_key,
            persistent) if key and secret_key else None
    elif apiMode == APIMode.ONLYKEY_SIGNED:
        publicRequestsURL = build_indico_request(path, params,
                                                 key) if key else None
        authRequestURL = build_indico_request(
            path, params, key, secret_key,
            persistent) if key and secret_key else None
    elif apiMode == APIMode.ALL_SIGNED:
        authRequestURL = build_indico_request(path, params, key, secret_key,
                                              persistent) if key else None
        params["onlypublic"] = "yes"
        publicRequestsURL = build_indico_request(path, params, key, secret_key,
                                                 persistent) if key else None
    return {
        "publicRequestURL":
        (baseURL + publicRequestsURL) if publicRequestsURL else "",
        "authRequestURL": (baseURL + authRequestURL) if authRequestURL else ""
    }
Пример #10
0
 def _process(self):
     quiet = request.form.get('quiet') == '1'
     force = request.form.get('force') == '1'
     persistent = request.form.get('persistent') == '1' and api_settings.get('allow_persistent')
     old_key = self.user.api_key
     if old_key:
         if not force:
             raise BadRequest('There is already an API key for this user')
         if old_key.is_blocked and not session.user.is_admin:
             raise Forbidden
         old_key.is_active = False
         db.session.flush()
     key = APIKey(user=self.user)
     db.session.add(key)
     if persistent:
         key.is_persistent_allowed = persistent
     elif old_key:
         key.is_persistent_allowed = old_key.is_persistent_allowed
     if not quiet:
         if old_key:
             flash(_('Your API key has been successfully replaced.'), 'success')
             if old_key.use_count:
                 flash(_('Please update any applications which use old key.'), 'warning')
         else:
             flash(_('Your API key has been successfully created.'), 'success')
     db.session.flush()
     return redirect_or_jsonify(url_for('api.user_profile'), flash=not quiet,
                                is_persistent_allowed=key.is_persistent_allowed)
Пример #11
0
def checkAK(apiKey, signature, timestamp, path, query):
    apiMode = api_settings.get('security_mode')
    if not apiKey:
        if apiMode in {
                APIMode.ONLYKEY, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED
        }:
            raise HTTPAPIError('API key is missing', 403)
        return None, True
    try:
        UUID(hex=apiKey)
    except ValueError:
        raise HTTPAPIError('Malformed API key', 400)
    ak = APIKey.find_first(token=apiKey, is_active=True)
    if not ak:
        raise HTTPAPIError('Invalid API key', 403)
    if ak.is_blocked:
        raise HTTPAPIError('API key is blocked', 403)
    # Signature validation
    onlyPublic = False
    if signature:
        validateSignature(ak, signature, timestamp, path, query)
    elif apiMode == APIMode.ALL_SIGNED:
        raise HTTPAPIError('Signature missing', 403)
    elif apiMode in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED}:
        onlyPublic = True
    return ak, onlyPublic
Пример #12
0
 def _process(self):
     quiet = request.form.get('quiet') == '1'
     force = request.form.get('force') == '1'
     persistent = request.form.get(
         'persistent') == '1' and api_settings.get('allow_persistent')
     old_key = self.user.api_key
     if old_key:
         if not force:
             raise BadRequest('There is already an API key for this user')
         if old_key.is_blocked and not session.user.is_admin:
             raise Forbidden
         old_key.is_active = False
         db.session.flush()
     key = APIKey(user=self.user)
     db.session.add(key)
     if persistent:
         key.is_persistent_allowed = persistent
     elif old_key:
         key.is_persistent_allowed = old_key.is_persistent_allowed
     if not quiet:
         if old_key:
             flash(_('Your API key has been successfully replaced.'),
                   'success')
             if old_key.use_count:
                 flash(
                     _('Please update any applications which use old key.'),
                     'warning')
         else:
             flash(_('Your API key has been successfully created.'),
                   'success')
     db.session.flush()
     return redirect_or_jsonify(
         url_for('api.user_profile'),
         flash=not quiet,
         is_persistent_allowed=key.is_persistent_allowed)
Пример #13
0
 def _process(self):
     quiet = request.form.get('quiet') == '1'
     key = self.user.api_key
     key.is_persistent_allowed = api_settings.get('allow_persistent') and request.form['enabled'] == '1'
     if not quiet:
         if key.is_persistent_allowed:
             flash(_('You can now use persistent signatures.'), 'success')
         else:
             flash(_('Persistent signatures have been disabled for your API key.'), 'success')
     return redirect_or_jsonify(url_for('api.user_profile'), flash=not quiet, enabled=key.is_persistent_allowed)
Пример #14
0
 def _process(self):
     quiet = request.form.get('quiet') == '1'
     key = self.user.api_key
     key.is_persistent_allowed = api_settings.get('allow_persistent') and request.form['enabled'] == '1'
     if not quiet:
         if key.is_persistent_allowed:
             flash(_('You can now use persistent signatures.'), 'success')
         else:
             flash(_('Persistent signatures have been disabled for your API key.'), 'success')
     return redirect_or_jsonify(url_for('api.user_profile'), flash=not quiet, enabled=key.is_persistent_allowed)
Пример #15
0
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
Пример #16
0
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
Пример #17
0
    def _getIcalExportParams(self, user, url, params=None):
        apiMode = api_settings.get('security_mode')
        apiKey = user.api_key if user else None

        urls = generate_public_auth_request(apiKey, url, params)
        tpl = get_template_module('api/_messages.html')

        return {
            'currentUser': user,
            'icsIconURL': str(Config.getInstance().getSystemIconURL("ical_grey")),
            'apiMode': apiMode,
            'signingEnabled': apiMode in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED},
            'persistentAllowed': api_settings.get('allow_persistent'),
            'requestURLs': urls,
            'persistentUserEnabled': apiKey.is_persistent_allowed if apiKey else False,
            'apiActive': apiKey is not None,
            'userLogged': user is not None,
            'apiKeyUserAgreement': tpl.get_ical_api_key_msg(),
            'apiPersistentUserAgreement': tpl.get_ical_persistent_msg()
        }
Пример #18
0
    def _getIcalExportParams(self, user, url, params=None):
        apiMode = api_settings.get('security_mode')
        apiKey = user.api_key if user else None

        urls = generate_public_auth_request(apiKey, url, params)
        tpl = get_template_module('api/_messages.html')

        return {
            'currentUser': user,
            'icsIconURL':
            str(Config.getInstance().getSystemIconURL("ical_grey")),
            'apiMode': apiMode,
            'signingEnabled': apiMode
            in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED},
            'persistentAllowed': api_settings.get('allow_persistent'),
            'requestURLs': urls,
            'persistentUserEnabled':
            apiKey.is_persistent_allowed if apiKey else False,
            'apiActive': apiKey is not None,
            'userLogged': user is not None,
            'apiKeyUserAgreement': tpl.get_ical_api_key_msg(),
            'apiPersistentUserAgreement': tpl.get_ical_persistent_msg()
        }
Пример #19
0
def get_base_ical_parameters(user, event, detail, session_=None):
    """Returns a dict of all parameters expected by iCal template"""

    from indico.web.http_api.util import generate_public_auth_request

    api_mode = api_settings.get('security_mode')
    persistent_allowed = api_settings.get('allow_persistent')
    api_key = user.api_key if user else None
    persistent_user_enabled = api_key.is_persistent_allowed if api_key else None
    tpl = get_template_module('api/_messages.html')
    persistent_agreement = tpl.get_ical_persistent_msg()
    if session_:
        path = '/export/event/{0}/session/{1}.ics'.format(
            event.id, session_.id)
    else:
        path = '/export/event/{0}.ics'.format(event.id)
    top_urls = generate_public_auth_request(api_key, path)
    urls = generate_public_auth_request(api_key, path, {'detail': detail})
    request_urls = {
        'publicRequestURL': top_urls['publicRequestURL'],
        'authRequestURL': top_urls['authRequestURL'],
        'publicRequestDetailedURL': urls['publicRequestURL'],
        'authRequestDetailedURL': urls['authRequestURL']
    }

    return {
        'api_mode': api_mode,
        'api_key': api_key,
        'persistent_allowed': persistent_allowed,
        'persistent_user_enabled': persistent_user_enabled,
        'api_active': api_key is not None,
        'api_key_user_agreement': tpl.get_ical_api_key_msg(),
        'api_persistent_user_agreement': persistent_agreement,
        'user_logged': user is not None,
        'request_urls': request_urls
    }
Пример #20
0
def get_base_ical_parameters(user, detail, path, params=None):
    """Returns a dict of all parameters expected by iCal template"""

    from indico.web.http_api.util import generate_public_auth_request

    api_mode = api_settings.get('security_mode')
    persistent_allowed = api_settings.get('allow_persistent')
    api_key = user.api_key if user else None
    persistent_user_enabled = api_key.is_persistent_allowed if api_key else None
    tpl = get_template_module('api/_messages.html')
    persistent_agreement = tpl.get_ical_persistent_msg()
    top_urls = generate_public_auth_request(api_key, path, params)
    urls = generate_public_auth_request(api_key, path, dict(params or {}, detail=detail))
    request_urls = {
        'publicRequestURL': top_urls['publicRequestURL'],
        'authRequestURL': top_urls['authRequestURL'],
        'publicRequestDetailedURL': urls['publicRequestURL'],
        'authRequestDetailedURL': urls['authRequestURL']
    }

    return {'api_mode': api_mode, 'api_key': api_key, 'persistent_allowed': persistent_allowed,
            'persistent_user_enabled': persistent_user_enabled, 'api_active': api_key is not None,
            'api_key_user_agreement': tpl.get_ical_api_key_msg(), 'api_persistent_user_agreement': persistent_agreement,
            'user_logged': user is not None, 'request_urls': request_urls}
Пример #21
0
def checkAK(apiKey, signature, timestamp, path, query):
    apiMode = api_settings.get('security_mode')
    if not apiKey:
        if apiMode in {APIMode.ONLYKEY, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED}:
            raise HTTPAPIError('API key is missing', 403)
        return None, True
    try:
        UUID(hex=apiKey)
    except ValueError:
        raise HTTPAPIError('Malformed API key', 400)
    ak = APIKey.find_first(token=apiKey, is_active=True)
    if not ak:
        raise HTTPAPIError('Invalid API key', 403)
    if ak.is_blocked:
        raise HTTPAPIError('API key is blocked', 403)
    # Signature validation
    onlyPublic = False
    if signature:
        validateSignature(ak, signature, timestamp, path, query)
    elif apiMode == APIMode.ALL_SIGNED:
        raise HTTPAPIError('Signature missing', 403)
    elif apiMode in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED}:
        onlyPublic = True
    return ak, onlyPublic
Пример #22
0
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"
    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()
    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, 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"
Пример #23
0
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'
Пример #24
0
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'
Пример #25
0
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'
Пример #26
0
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'
Пример #27
0
    def getVars(self):
        from indico.web.http_api.util import generate_public_auth_request

        vars = WHeader.getVars(self)
        vars["categurl"] = self._conf.as_event.category.url

        vars["conf"] = vars["target"] = self._conf

        vars["imgLogo"] = Config.getInstance().getSystemIconURL("miniLogo")
        vars["MaKaCHomeURL"] = self._conf.as_event.category.url

        # Default values to avoid NameError while executing the template
        styles = theme_settings.get_themes_for("conference")

        vars["viewoptions"] = [{
            'id': theme_id,
            'name': data['title']
        } for theme_id, data in sorted(styles.viewitems(),
                                       key=lambda x: x[1]['title'])]
        vars["SelectedStyle"] = ""
        vars["pdfURL"] = ""
        vars["displayURL"] = str(
            urlHandlers.UHConferenceOtherViews.getURL(self._conf))

        # Setting the buttons that will be displayed in the header menu
        vars["showFilterButton"] = False
        vars["showMoreButton"] = True
        vars["showExportToICal"] = True
        vars["showExportToPDF"] = False
        vars["showDLMaterial"] = True
        vars["showLayout"] = True

        vars["displayNavigationBar"] = layout_settings.get(
            self._conf, 'show_nav_bar')

        # This is basically the same WICalExportBase, but we need some extra
        # logic in order to have the detailed URLs
        apiMode = api_settings.get('security_mode')

        vars["icsIconURL"] = str(
            Config.getInstance().getSystemIconURL("ical_grey"))
        vars["apiMode"] = apiMode
        vars["signingEnabled"] = apiMode in {
            APIMode.SIGNED, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED
        }
        vars["persistentAllowed"] = api_settings.get('allow_persistent')
        user = self._aw.getUser()
        apiKey = user.api_key if user else None

        topURLs = generate_public_auth_request(
            apiKey, '/export/event/%s.ics' % self._conf.getId())
        urls = generate_public_auth_request(
            apiKey, '/export/event/%s.ics' % self._conf.getId(),
            {'detail': 'contributions'})

        vars["requestURLs"] = {
            'publicRequestURL': topURLs["publicRequestURL"],
            'authRequestURL': topURLs["authRequestURL"],
            'publicRequestDetailedURL': urls["publicRequestURL"],
            'authRequestDetailedURL': urls["authRequestURL"]
        }

        vars[
            "persistentUserEnabled"] = apiKey.is_persistent_allowed if apiKey else False
        vars["apiActive"] = apiKey is not None
        vars["userLogged"] = user is not None
        tpl = get_template_module('api/_messages.html')
        vars['apiKeyUserAgreement'] = tpl.get_ical_api_key_msg()
        vars['apiPersistentUserAgreement'] = tpl.get_ical_persistent_msg()

        return vars