Exemplo n.º 1
0
 def _process(self):
     filename = "%s-Categ.atom" % self._target.getName().replace("/", "")
     hook = CategoryEventHook({'from': 'today'}, 'categ', {'idlist': self._target.getId(), 'dformat': 'atom'})
     res = hook(self.getAW())
     resultFossil = {'results': res[0], 'url': str(self._uh.getURL(self._target))}
     serializer = Serializer.create('atom')
     return send_file(filename, StringIO(serializer(resultFossil).encode('utf-8')), 'ATOM')
Exemplo n.º 2
0
 def _process(self):
     filename = "%s-Categ.atom" % self._target.getName().replace("/", "")
     hook = CategoryEventHook({'from': 'today'}, 'categ', {'idlist': self._target.getId(), 'dformat': 'atom'})
     res = hook(self.getAW())
     resultFossil = {'results': res[0], 'url': str(self._uh.getURL(self._target))}
     serializer = Serializer.create('atom')
     return send_file(filename, StringIO(serializer(resultFossil)), 'ATOM')
Exemplo n.º 3
0
    def _process(self):

        if not self._target.isScheduled():
            raise NoReportError(
                _("You cannot export the contribution with id %s because it is not scheduled"
                  ) % self._target.getId())

        filename = "%s-Contribution.ics" % self._target.getTitle()

        hook = ContributionHook({}, 'contribution', {
            'event': self._conf.getId(),
            'idlist': self._contrib.getId(),
            'dformat': 'ics'
        })
        res = hook(self.getAW(), self._req)
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        data = serializer(resultFossil)

        self._req.headers_out["Content-Length"] = "%s" % len(data)
        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType("ICAL")
        self._req.content_type = """%s""" % (mimetype)
        self._req.headers_out[
            "Content-Disposition"] = """inline; filename="%s\"""" % cleanHTMLHeaderFilename(
                filename)
        return data
Exemplo n.º 4
0
    def _process(self):
        filename = "%s-Categ.ics" % self._target.getName().replace("/", "")

        hook = CategoryEventHook({}, 'categ', {'idlist': self._target.getId(), 'dformat': 'ics'})
        res = hook(self.getAW())
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        return send_file(filename, StringIO(serializer(resultFossil)), 'ICAL')
Exemplo n.º 5
0
    def _process(self):
        filename = "%s-Categ.ics" % self._target.getName().replace("/", "")

        hook = CategoryEventHook({}, 'categ', {'idlist': self._target.getId(), 'dformat': 'ics'})
        res = hook(self.getAW())
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        return send_file(filename, StringIO(serializer(resultFossil)), 'ICAL')
Exemplo n.º 6
0
def get_session_ical_file(sess):
    from indico.web.http_api.metadata.serializer import Serializer
    data = {
        'results':
        serialize_session_for_ical(sess)
        if sess.start_dt and sess.end_dt else []
    }
    serializer = Serializer.create('ics')
    return BytesIO(serializer(data))
Exemplo n.º 7
0
    def _process( self ):
        filename = "%s-Session.ics"%self._session.getTitle()

        hook = SessionHook({}, 'session', {'event': self._conf.getId(), 'idlist':self._session.getId(), 'dformat': 'ics'})
        res = hook(self.getAW())
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        return send_file(filename, StringIO(serializer(resultFossil)), 'ICAL')
Exemplo n.º 8
0
    def _process(self):
        filename = "%s-Event.ics" % self._target.getTitle()

        hook = CategoryEventHook({'detail': self._detailLevel}, 'event',
                                 {'idlist': self._conf.getId(), 'dformat': 'ics'})
        res = hook(self.getAW())
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        return send_file(filename, StringIO(serializer(resultFossil)), 'ICAL')
Exemplo n.º 9
0
    def _process(self):
        filename = "%s-Event.ics" % self._target.getTitle()

        hook = CategoryEventHook({'detail': self._detailLevel}, 'event',
                                 {'idlist': self._conf.getId(), 'dformat': 'ics'})
        res = hook(self.getAW())
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        return send_file(filename, StringIO(serializer(resultFossil)), 'ICAL')
Exemplo n.º 10
0
    def _process(self):
        filename = "%s-Session.ics" % self._session.getTitle()

        hook = SessionHook({}, 'session', {
            'event': self._conf.getId(),
            'idlist': self._session.getId(),
            'dformat': 'ics'
        })
        res = hook(self.getAW())
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        return send_file(filename, StringIO(serializer(resultFossil)), 'ICAL')
Exemplo n.º 11
0
    def _process( self ):

        if not self._target.isScheduled():
            raise NoReportError(_("You cannot export the contribution with id %s because it is not scheduled")%self._target.getId())

        filename = "%s-Contribution.ics"%self._target.getTitle()

        hook = ContributionHook({}, 'contribution', {'event': self._conf.getId(), 'idlist':self._contrib.getId(), 'dformat': 'ics'})
        res = hook(self.getAW())
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        return send_file(filename, StringIO(serializer(resultFossil)), 'ICAL')
Exemplo n.º 12
0
    def _process(self):

        hook = CategoryEventHook({"from": ["today"]}, "categ", {"idlist": self._target.getId(), "dformat": "atom"})
        res = hook(self.getAW(), self._req)
        resultFossil = {"results": res[0], "url": str(self._uh.getURL(self._target))}

        serializer = Serializer.create("atom")
        data = serializer(resultFossil)

        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType("ATOM")
        self._req.content_type = """%s""" % (mimetype)

        return data
Exemplo n.º 13
0
    def _process( self ):

        hook = CategoryEventHook({'from': ['today']}, 'categ', {'idlist':self._target.getId(), 'dformat': 'atom'})
        res = hook(self.getAW(), self._req)
        resultFossil = {'results': res[0], 'url': str(self._uh.getURL(self._target))}

        serializer = Serializer.create('atom')
        data = serializer(resultFossil)

        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType( "ATOM" )
        self._req.content_type = """%s"""%(mimetype)

        return data
Exemplo n.º 14
0
    def _process( self ):

        hook = CategoryEventHook({'from': ['today']}, 'categ', {'idlist':self._target.getId(), 'dformat': 'atom'})
        res = hook(self.getAW(), self._req)
        resultFossil = {'results': res[0], 'url': str(self._uh.getURL(self._target))}

        serializer = Serializer.create('atom')
        data = serializer(resultFossil)

        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType( "ATOM" )
        self._req.content_type = """%s"""%(mimetype)

        return data
Exemplo n.º 15
0
    def _process( self ):
        filename = "%s-Session.ics"%self._session.getTitle()

        hook = SessionHook({}, 'session', {'event': self._conf.getId(), 'idlist':self._session.getId(), 'dformat': 'ics'})
        res = hook(self.getAW(), self._req)
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        data = serializer(resultFossil)

        self._req.headers_out["Content-Length"] = "%s"%len(data)
        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType( "ICAL" )
        self._req.content_type = """%s"""%(mimetype)
        self._req.headers_out["Content-Disposition"] = """inline; filename="%s\""""%cleanHTMLHeaderFilename(filename)
        return data
Exemplo n.º 16
0
    def _process( self ):
        filename = "%s-Categ.ics"%self._target.getName().replace("/","")

        hook = CategoryEventHook({}, 'categ', {'idlist':self._target.getId(), 'dformat': 'ics'})
        res = hook(self.getAW(), self._req)
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        data = serializer(resultFossil)

        self._req.headers_out["Content-Length"] = "%s"%len(data)
        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType( "ICAL" )
        self._req.content_type = """%s"""%(mimetype)
        self._req.headers_out["Content-Disposition"] = """inline; filename="%s\""""%cleanHTMLHeaderFilename(filename)

        return data
Exemplo n.º 17
0
    def _process( self ):
        filename = "%s-Categ.ics"%self._target.getName().replace("/","")

        hook = CategoryEventHook({}, 'categ', {'idlist':self._target.getId(), 'dformat': 'ics'})
        res = hook(self.getAW(), self._req)
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        data = serializer(resultFossil)

        self._req.headers_out["Content-Length"] = "%s"%len(data)
        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType( "ICAL" )
        self._req.content_type = """%s"""%(mimetype)
        self._req.headers_out["Content-Disposition"] = """inline; filename="%s\""""%cleanHTMLHeaderFilename(filename)

        return data
Exemplo n.º 18
0
    def _process(self):

        if not self._target.isScheduled():
            raise NoReportError(
                _("You cannot export the contribution with id {0} because it is not scheduled"
                  ).format(self._target.getId()))

        filename = "{0}-Contribution.ics".format(self._target.getTitle())

        hook = ContributionHook({}, 'contribution', {
            'event': self._conf.getId(),
            'idlist': self._contrib.getId(),
            'dformat': 'ics'
        })
        res = hook(self.getAW())
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        return send_file(filename, StringIO(serializer(resultFossil)), 'ICAL')
Exemplo n.º 19
0
    def _process(self):

        if not self._target.isScheduled():
            raise NoReportError(
                _("You cannot export the contribution with id {0} because it is not scheduled").format(
                    self._target.getId()
                )
            )

        filename = "{0}-Contribution.ics".format(self._target.getTitle())

        hook = ContributionHook(
            {}, "contribution", {"event": self._conf.getId(), "idlist": self._contrib.getId(), "dformat": "ics"}
        )
        res = hook(self.getAW())
        resultFossil = {"results": res[0]}

        serializer = Serializer.create("ics")
        return send_file(filename, StringIO(serializer(resultFossil)), "ICAL")
Exemplo n.º 20
0
    def _process( self ):

        if not self._target.isScheduled():
            raise NoReportError(_("You cannot export the contribution with id %s because it is not scheduled")%self._target.getId())

        filename = "%s-Contribution.ics"%self._target.getTitle()

        hook = ContributionHook({}, 'contribution', {'event': self._conf.getId(), 'idlist':self._contrib.getId(), 'dformat': 'ics'})
        res = hook(self.getAW(), self._req)
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        data = serializer(resultFossil)

        self._req.headers_out["Content-Length"] = "%s"%len(data)
        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType( "ICAL" )
        self._req.content_type = """%s"""%(mimetype)
        self._req.headers_out["Content-Disposition"] = """inline; filename="%s\""""%cleanHTMLHeaderFilename(filename)
        return data
Exemplo n.º 21
0
    def _process(self):
        filename = "%s-Session.ics" % self._session.getTitle()

        hook = SessionHook({}, 'session', {
            'event': self._conf.getId(),
            'idlist': self._session.getId(),
            'dformat': 'ics'
        })
        res = hook(self.getAW(), self._req)
        resultFossil = {'results': res[0]}

        serializer = Serializer.create('ics')
        data = serializer(resultFossil)

        self._req.headers_out["Content-Length"] = "%s" % len(data)
        cfg = Config.getInstance()
        mimetype = cfg.getFileTypeMimeType("ICAL")
        self._req.content_type = """%s""" % (mimetype)
        self._req.headers_out[
            "Content-Disposition"] = """inline; filename="%s\"""" % cleanHTMLHeaderFilename(
                filename)
        return data
Exemplo n.º 22
0
def get_session_ical_file(sess):
    from indico.web.http_api.metadata.serializer import Serializer
    data = {'results': serialize_session_for_ical(sess) if sess.start_dt and sess.end_dt else []}
    serializer = Serializer.create('ics')
    return BytesIO(serializer(data))
Exemplo n.º 23
0
        self._attachment = Attachment.get(int(self._pathParams['res']))

        if not self._attachment:
            raise HTTPAPIError("File not found", 404)

    def export_file(self, user):
        if self._attachment.type != AttachmentType.file:
            raise HTTPAPIError("Resource is not a file", 404)

        return self._attachment.file.send()

    def _has_access(self, user):
        return self._attachment.can_access(user)


class FileSerializer(Serializer):

    encapsulate = False
    schemaless = False

    def _execute(self, fdata):
        return fdata

    def get_response_content_type(self):
        # we already have a response with the correct headers
        return None


Serializer.register('bin', FileSerializer)
Exemplo n.º 24
0
                    pass # retry
                else:
                    break
        else:
            # No need to commit stuff if we didn't use an API key
            # (nothing was written)
            if minfo.getRoomBookingModuleActive():
                Factory.getDALManager().rollback()
                Factory.getDALManager().disconnect()
            dbi.endRequest(False)

        # Log successful POST api requests
        if error is None and req.method == 'POST':
            logger.info('API request: %s?%s' % (path, query))

        serializer = Serializer.create(dformat, pretty=pretty, typeMap=typeMap,
                                       **remove_lists(queryParams))
        if error:
            if not serializer.schemaless:
                # if our serializer has a specific schema (HTML, ICAL, etc...)
                # use JSON, since it is universal
                serializer = Serializer.create('json')

            result = fossilize(error)
        else:
            if serializer.encapsulate:
                result = fossilize(HTTPAPIResult(result, path, query, ts, complete, extra), IHTTPAPIExportResultFossil)
                del result['_fossil']

        try:
            data = serializer(result)
            serializer.set_headers(req)
Exemplo n.º 25
0
                    pass  # retry
                else:
                    break
        else:
            # No need to commit stuff if we didn't use an API key
            # (nothing was written)
            if minfo.getRoomBookingModuleActive():
                Factory.getDALManager().rollback()
                Factory.getDALManager().disconnect()
            dbi.endRequest(False)

        # Log successful POST api requests
        if error is None and request.method == 'POST':
            logger.info('API request: %s?%s' % (path, query))

        serializer = Serializer.create(dformat, pretty=pretty, typeMap=typeMap,
                                       **queryParams)
        if error:
            if not serializer.schemaless:
                # if our serializer has a specific schema (HTML, ICAL, etc...)
                # use JSON, since it is universal
                serializer = Serializer.create('json')

            result = fossilize(error)
        else:
            if serializer.encapsulate:
                result = fossilize(HTTPAPIResult(result, path, query, ts, complete, extra), IHTTPAPIExportResultFossil)
                del result['_fossil']

        try:
            data = serializer(result)
            serializer.set_headers(responseUtil)
Exemplo n.º 26
0
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Indico;if not, see <http://www.gnu.org/licenses/>.

"""
json-based fossil serializer
"""
# indico imports
from indico.util import json

# module imports
from indico.web.http_api.metadata.serializer import Serializer


class JSONSerializer(Serializer):

    """
    Does basically direct translation from the fossi
    """

    _mime = "application/json"

    def _execute(self, fossil):
        return json.dumps(fossil, pretty=self.pretty)


Serializer.register("json", JSONSerializer)
Exemplo n.º 27
0
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

"""
json-based fossil serializer
"""
# indico imports
from indico.util import json

# module imports
from indico.web.http_api.metadata.serializer import Serializer


class JSONSerializer(Serializer):

    """
    Does basically direct translation from the fossi
    """

    _mime = 'application/json'

    def _execute(self, fossil):
        return json.dumps(fossil, pretty=self.pretty)


Serializer.register('json', JSONSerializer)
Exemplo n.º 28
0
            uri = to_unicode('?'.join(filter(None, (norm_path, norm_query))))
            ak.register_used(request.remote_addr, uri, not onlyPublic)
            transaction.commit()
        else:
            # No need to commit stuff if we didn't use an API key (nothing was written)
            # XXX do we even need this?
            transaction.abort()

        # Log successful POST api requests
        if error is None and request.method == 'POST':
            logger.info('API request: %s?%s', path, query)
        if is_response:
            return result
        serializer = Serializer.create(dformat,
                                       query_params=queryParams,
                                       pretty=pretty,
                                       typeMap=typeMap,
                                       **hook.serializer_args)
        if error:
            if not serializer.schemaless:
                # if our serializer has a specific schema (HTML, ICAL, etc...)
                # use JSON, since it is universal
                serializer = Serializer.create('json')

            result = fossilize(error)
        else:
            if serializer.encapsulate:
                result = fossilize(
                    HTTPAPIResult(result, path, query, ts, complete, extra),
                    IHTTPAPIExportResultFossil)
                del result['_fossil']
Exemplo n.º 29
0
        if ak and error is None:
            # Commit only if there was an API key and no error
            norm_path, norm_query = normalizeQuery(path, query, remove=('signature', 'timestamp'), separate=True)
            uri = to_unicode('?'.join(filter(None, (norm_path, norm_query))))
            ak.register_used(request.remote_addr, uri, not onlyPublic)
            transaction.commit()
        else:
            # No need to commit stuff if we didn't use an API key (nothing was written)
            # XXX do we even need this?
            transaction.abort()

        # Log successful POST api requests
        if error is None and request.method == 'POST':
            logger.info('API request: %s?%s' % (path, query))

        serializer = Serializer.create(dformat, query_params=queryParams, pretty=pretty, typeMap=typeMap,
                                       **hook.serializer_args)
        if error:
            if not serializer.schemaless:
                # if our serializer has a specific schema (HTML, ICAL, etc...)
                # use JSON, since it is universal
                serializer = Serializer.create('json')

            result = fossilize(error)
        else:
            if serializer.encapsulate:
                result = fossilize(HTTPAPIResult(result, path, query, ts, complete, extra), IHTTPAPIExportResultFossil)
                del result['_fossil']

        try:
            data = serializer(result)
            serializer.set_headers(responseUtil)
Exemplo n.º 30
0
                elif type(v) == dict:
                    elem.append(self._xmlForFossil(v))
                else:
                    txt = self._convert(v)
                    try:
                        elem.text = txt
                    except Exception, e:
                        Logger.get('xmlSerializer').error(
                            'Setting XML text value failed: %s (id: %s)' %
                            (e, id))

        return felement

    def _execute(self, fossil, xml_declaration=True):
        if type(fossil) == list:
            # collection of fossils
            doc = etree.ElementTree(etree.Element("collection"))
            for elem in fossil:
                self._xmlForFossil(elem, doc)
            result = doc
        else:
            result = self._xmlForFossil(fossil)

        return etree.tostring(result,
                              pretty_print=self.pretty,
                              xml_declaration=xml_declaration,
                              encoding='utf-8')


Serializer.register('xml', XMLSerializer)
Exemplo n.º 31
0
                            else:
                                subelem = etree.SubElement(elem, "item")
                                subelem.text = self._convert(subv)
                elif isinstance(v, dict):
                    elem.append(self._xmlForFossil(v))
                else:
                    txt = self._convert(v)
                    try:
                        elem.text = txt
                    except Exception:
                        Logger.get("xmlSerializer").exception(
                            "Setting XML text value failed (id: {}, value {!r})".format(id, txt)
                        )

        return felement

    def _execute(self, fossil, xml_declaration=True):
        if type(fossil) == list:
            # collection of fossils
            doc = etree.ElementTree(etree.Element("collection"))
            for elem in fossil:
                self._xmlForFossil(elem, doc)
            result = doc
        else:
            result = self._xmlForFossil(fossil)

        return etree.tostring(result, pretty_print=self.pretty, xml_declaration=xml_declaration, encoding="utf-8")


Serializer.register("xml", XMLSerializer)
Exemplo n.º 32
0
                            elem.append(self._xmlForFossil(subv))
                        else:
                            subelem = etree.SubElement(elem, 'item')
                            subelem.text = self._convert(subv)
            elif isinstance(v, dict):
                elem.append(self._xmlForFossil(v))
            else:
                txt = self._convert(v)
                try:
                    elem.text = txt
                except Exception:
                    Logger.get('xmlSerializer').exception('Setting XML text value failed (id: %s, value %r)', id, txt)

        return felement

    def _execute(self, fossil, xml_declaration=True):
        if type(fossil) == list:
            # collection of fossils
            doc = etree.ElementTree(etree.Element("collection"))
            for elem in fossil:
                self._xmlForFossil(elem, doc)
            result = doc
        else:
            result = self._xmlForFossil(fossil)

        return etree.tostring(result, pretty_print=self.pretty,
                              xml_declaration=xml_declaration, encoding='utf-8')


Serializer.register('xml', XMLSerializer)
Exemplo n.º 33
0
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.
"""
json-based fossil serializer
"""
# indico imports
from indico.util import json

# module imports
from indico.web.http_api.metadata.serializer import Serializer


class JSONSerializer(Serializer):
    """
    Does basically direct translation from the fossi
    """

    _mime = 'application/json'

    def _execute(self, fossil):
        return json.dumps(fossil, pretty=self.pretty)


Serializer.register('json', JSONSerializer)
Exemplo n.º 34
0
        return self._file.canAccess(aw)

    @classmethod
    def _matchPath(cls, path):
        if not hasattr(cls, '_RE'):
            cls._RE = re.compile(r'/' + cls.PREFIX + '/event/' + cls.RE + r'\.(\w+)$')
        return cls._RE.match(path)


class FileSerializer(Serializer):

    encapsulate = False
    schemaless = False

    def _execute(self, fdata):
        cfg = Config.getInstance()

        self._mime = cfg.getFileTypeMimeType(fdata['ftype'])

        if cfg.getUseXSendFile():
            return ""
        else:
            return fdata['data']

    def set_headers(self, req):
        super(FileSerializer, self).set_headers(req)
        set_file_headers(req, **self._obj)


Serializer.register('bin', FileSerializer)
Exemplo n.º 35
0
def handler(prefix, path):
    path = posixpath.join('/', prefix, path)
    logger = Logger.get('httpapi')
    if request.method == 'POST':
        # Convert POST data to a query string
        queryParams = list(request.form.lists())
        query = 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 = {key: value for key, value in request.args.items()}
        query = request.query_string.decode()

    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'

    oauth_token = None
    if request.headers.get('Authorization', '').lower().startswith('bearer '):
        try:
            oauth_token = require_oauth.acquire_token([scope])
        except OAuth2Error as exc:
            raise BadRequest(f'OAuth error: {exc}')

    # 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 = {}
    status_code = None
    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_token or not used_session:
            auth_token = None
            if not oauth_token:
                # Validate the API key (and its signature)
                ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp,
                                                path, query)
                if enforceOnlyPublic:
                    onlyPublic = True
                # Create an access wrapper for the API key's user
                user = ak.user if ak and not onlyPublic else None
            else:  # Access Token (OAuth)
                user = oauth_token.user if not onlyPublic else None
            # Get rid of API key in cache key if we did not impersonate a user
            if ak and user is None:
                cacheKey = normalizeQuery(
                    path,
                    query,
                    remove=('_', 'ak', 'apiKey', 'signature', 'timestamp',
                            'nc', 'nocache', 'oa', 'onlyauthed',
                            'access_token'))
            else:
                cacheKey = normalizeQuery(
                    path,
                    query,
                    remove=('_', 'signature', 'timestamp', 'nc', 'nocache',
                            'oa', 'onlyauthed', 'access_token'))
                if signature:
                    # in case the request was signed, store the result under a different key
                    cacheKey = 'signed_' + cacheKey
                if auth_token:
                    # if oauth was used, we also make the cache key unique
                    cacheKey = f'oauth-{auth_token.id}_{cacheKey}'
        else:
            # We authenticated using a session cookie.
            # XXX: This is not used anymore within indico and should be removed whenever we rewrite
            # the code here.
            token = request.headers.get(
                'X-CSRF-Token', get_query_parameter(queryParams,
                                                    ['csrftoken']))
            if used_session.csrf_protected and used_session.csrf_token != token:
                raise HTTPAPIError('Invalid CSRF token', 403)
            user = used_session.user if not onlyPublic else None
            cacheKey = normalizeQuery(path,
                                      query,
                                      remove=('_', 'nc', 'nocache', 'ca',
                                              'cookieauth', 'oa', 'onlyauthed',
                                              'csrftoken'))

        if user is not None:
            # We *always* prefix the cache key with the user ID so we never get an overlap between
            # authenticated and unauthenticated requests
            cacheKey = f'user-{user.id}_{cacheKey}'
            sentry_sdk.set_user({
                'id': user.id,
                'email': user.email,
                'name': user.full_name,
                'source': 'http_api'
            })
        else:
            cacheKey = f'public_{cacheKey}'

        # Bail out if the user requires authentication but is not authenticated
        if onlyAuthed and not user:
            raise HTTPAPIError('Not authenticated', 403)

        addToCache = not hook.NO_CACHE
        cacheKey = RE_REMOVE_EXTENSION.sub('', cacheKey)
        if not noCache:
            obj = API_CACHE.get(cacheKey)
            if obj is not None:
                result, extra, ts, complete, typeMap = obj
                addToCache = False
        if result is None:
            g.current_api_user = user
            # Perform the actual exporting
            res = hook(user)
            if isinstance(res, current_app.response_class):
                addToCache = False
                is_response = True
                result, extra, complete, typeMap = res, {}, True, {}
            elif isinstance(res, tuple) and len(res) == 4:
                result, extra, complete, typeMap = res
            else:
                result, extra, complete, typeMap = res, {}, True, {}
        if result is not None and addToCache:
            ttl = api_settings.get('cache_ttl')
            if ttl > 0:
                API_CACHE.set(cacheKey, (result, extra, ts, complete, typeMap),
                              ttl)
    except HTTPAPIError as e:
        error = e
        if e.code:
            status_code = e.code

    if result is None and error is None:
        raise NotFound
    else:
        if ak and error is None:
            # Commit only if there was an API key and no error
            norm_path, norm_query = normalizeQuery(path,
                                                   query,
                                                   remove=('signature',
                                                           'timestamp'),
                                                   separate=True)
            uri = '?'.join(_f for _f in (norm_path, norm_query) if _f)
            ak.register_used(request.remote_addr, uri, not onlyPublic)
            db.session.commit()
        else:
            # No need to commit stuff if we didn't use an API key (nothing was written)
            # XXX do we even need this?
            db.session.rollback()

        # Log successful POST api requests
        if error is None and request.method == 'POST':
            logger.info('API request: %s?%s', path, query)
        if is_response:
            return result
        serializer = Serializer.create(dformat,
                                       query_params=queryParams,
                                       pretty=pretty,
                                       typeMap=typeMap,
                                       **hook.serializer_args)
        if error:
            if not serializer.schemaless:
                # if our serializer has a specific schema (HTML, ICAL, etc...)
                # use JSON, since it is universal
                serializer = Serializer.create('json')

            result = {'message': error.message}
        elif serializer.encapsulate:
            result = HTTPAPIResultSchema().dump(
                HTTPAPIResult(result, path, query, ts, extra))

        try:
            data = serializer(result)
            response = current_app.make_response(data)
            content_type = serializer.get_response_content_type()
            if content_type:
                response.content_type = content_type
            if status_code:
                response.status_code = status_code
            return response
        except Exception:
            logger.exception('Serialization error in request %s?%s', path,
                             query)
            raise
Exemplo n.º 36
0
def get_contribution_ical_file(contrib):
    data = {'results': serialize_contribution_for_ical(contrib)}
    serializer = Serializer.create('ics')
    return BytesIO(serializer(data))
Exemplo n.º 37
0
def get_contribution_ical_file(contrib):
    data = {'results': serialize_contribution_for_ical(contrib)}
    serializer = Serializer.create('ics')
    return BytesIO(serializer(data))
Exemplo n.º 38
0
def handler(prefix, path):
    path = posixpath.join('/', prefix, path)
    clearCache()  # init fossil cache
    logger = Logger.get('httpapi')
    if request.method == 'POST':
        # Convert POST data to a query string
        queryParams = [(key, [x.encode('utf-8') for x in values])
                       for key, values in request.form.iterlists()]
        query = urllib.urlencode(queryParams, doseq=1)
        # we only need/keep multiple values so we can properly validate the signature.
        # the legacy code below expects a dict with just the first value.
        # if you write a new api endpoint that needs multiple values get them from
        # ``request.values.getlist()`` directly
        queryParams = {key: values[0] for key, values in queryParams}
    else:
        # Parse the actual query string
        queryParams = dict((key, value.encode('utf-8'))
                           for key, value in request.args.iteritems())
        query = request.query_string

    apiKey = get_query_parameter(queryParams, ['ak', 'apikey'], None)
    cookieAuth = get_query_parameter(queryParams, ['ca', 'cookieauth'],
                                     'no') == 'yes'
    signature = get_query_parameter(queryParams, ['signature'])
    timestamp = get_query_parameter(queryParams, ['timestamp'],
                                    0,
                                    integer=True)
    noCache = get_query_parameter(queryParams, ['nc', 'nocache'],
                                  'no') == 'yes'
    pretty = get_query_parameter(queryParams, ['p', 'pretty'], 'no') == 'yes'
    onlyPublic = get_query_parameter(queryParams, ['op', 'onlypublic'],
                                     'no') == 'yes'
    onlyAuthed = get_query_parameter(queryParams, ['oa', 'onlyauthed'],
                                     'no') == 'yes'
    scope = 'read:legacy_api' if request.method == 'GET' else 'write:legacy_api'

    if not request.headers.get('Authorization',
                               '').lower().startswith('basic '):
        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
    else:
        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 = {}
    status_code = None
    is_response = False
    try:
        used_session = None
        if cookieAuth:
            used_session = session
            if not used_session.user:  # ignore guest sessions
                used_session = None

        if apiKey or oauth_valid or not used_session:
            if not oauth_valid:
                # Validate the API key (and its signature)
                ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp,
                                                path, query)
                if enforceOnlyPublic:
                    onlyPublic = True
                # Create an access wrapper for the API key's user
                user = ak.user if ak and not onlyPublic else None
            else:  # Access Token (OAuth)
                at = load_token(oauth_request.access_token.access_token)
                user = at.user if at and not onlyPublic else None
            # Get rid of API key in cache key if we did not impersonate a user
            if ak and user is None:
                cacheKey = normalizeQuery(
                    path,
                    query,
                    remove=('_', 'ak', 'apiKey', 'signature', 'timestamp',
                            'nc', 'nocache', 'oa', 'onlyauthed'))
            else:
                cacheKey = normalizeQuery(path,
                                          query,
                                          remove=('_', 'signature',
                                                  'timestamp', 'nc', 'nocache',
                                                  'oa', 'onlyauthed'))
                if signature:
                    # in case the request was signed, store the result under a different key
                    cacheKey = 'signed_' + cacheKey
        else:
            # We authenticated using a session cookie.
            token = request.headers.get(
                'X-CSRF-Token', get_query_parameter(queryParams,
                                                    ['csrftoken']))
            if used_session.csrf_protected and used_session.csrf_token != token:
                raise HTTPAPIError('Invalid CSRF token', 403)
            user = used_session.user if not onlyPublic else None
            userPrefix = 'user-{}_'.format(used_session.user.id)
            cacheKey = userPrefix + normalizeQuery(
                path,
                query,
                remove=('_', 'nc', 'nocache', 'ca', 'cookieauth', 'oa',
                        'onlyauthed', 'csrftoken'))

        # Bail out if the user requires authentication but is not authenticated
        if onlyAuthed and not user:
            raise HTTPAPIError('Not authenticated', 403)

        addToCache = not hook.NO_CACHE
        cache = GenericCache('HTTPAPI')
        cacheKey = RE_REMOVE_EXTENSION.sub('', cacheKey)
        if not noCache:
            obj = cache.get(cacheKey)
            if obj is not None:
                result, extra, ts, complete, typeMap = obj
                addToCache = False
        if result is None:
            g.current_api_user = user
            # Perform the actual exporting
            res = hook(user)
            if isinstance(res, current_app.response_class):
                addToCache = False
                is_response = True
                result, extra, complete, typeMap = res, {}, True, {}
            elif isinstance(res, tuple) and len(res) == 4:
                result, extra, complete, typeMap = res
            else:
                result, extra, complete, typeMap = res, {}, True, {}
        if result is not None and addToCache:
            ttl = api_settings.get('cache_ttl')
            if ttl > 0:
                cache.set(cacheKey, (result, extra, ts, complete, typeMap),
                          ttl)
    except HTTPAPIError as e:
        error = e
        if e.getCode():
            status_code = e.getCode()

    if result is None and error is None:
        # TODO: usage page
        raise NotFound
    else:
        if ak and error is None:
            # Commit only if there was an API key and no error
            norm_path, norm_query = normalizeQuery(path,
                                                   query,
                                                   remove=('signature',
                                                           'timestamp'),
                                                   separate=True)
            uri = to_unicode('?'.join(filter(None, (norm_path, norm_query))))
            ak.register_used(request.remote_addr, uri, not onlyPublic)
            db.session.commit()
        else:
            # No need to commit stuff if we didn't use an API key (nothing was written)
            # XXX do we even need this?
            db.session.rollback()

        # Log successful POST api requests
        if error is None and request.method == 'POST':
            logger.info('API request: %s?%s', path, query)
        if is_response:
            return result
        serializer = Serializer.create(dformat,
                                       query_params=queryParams,
                                       pretty=pretty,
                                       typeMap=typeMap,
                                       **hook.serializer_args)
        if error:
            if not serializer.schemaless:
                # if our serializer has a specific schema (HTML, ICAL, etc...)
                # use JSON, since it is universal
                serializer = Serializer.create('json')

            result = fossilize(error)
        else:
            if serializer.encapsulate:
                result = fossilize(
                    HTTPAPIResult(result, path, query, ts, complete, extra),
                    IHTTPAPIExportResultFossil)
                del result['_fossil']

        try:
            data = serializer(result)
            response = current_app.make_response(data)
            content_type = serializer.get_response_content_type()
            if content_type:
                response.content_type = content_type
            if status_code:
                response.status_code = status_code
            return response
        except Exception:
            logger.exception('Serialization error in request %s?%s', path,
                             query)
            raise
Exemplo n.º 39
0
                except ConflictError:
                    pass  # retry
                else:
                    break
        else:
            # No need to commit stuff if we didn't use an API key
            # (nothing was written)
            dbi.endRequest(False)

        LDAPConnector.destroy()

        # Log successful POST api requests
        if error is None and request.method == 'POST':
            logger.info('API request: %s?%s' % (path, query))

        serializer = Serializer.create(dformat, pretty=pretty, typeMap=typeMap,
                                       **hook.serializer_args)
        if error:
            if not serializer.schemaless:
                # if our serializer has a specific schema (HTML, ICAL, etc...)
                # use JSON, since it is universal
                serializer = Serializer.create('json')

            result = fossilize(error)
        else:
            if serializer.encapsulate:
                result = fossilize(HTTPAPIResult(result, path, query, ts, complete, extra), IHTTPAPIExportResultFossil)
                del result['_fossil']

        try:
            data = serializer(result)
            serializer.set_headers(responseUtil)