Example #1
0
    def handle_exception(self, e, request):
        """
        handle_exception is a callback that decorators all deferreds in render

        It responds to properly handled GL Exceptions by pushing the error msgs
        to the client and it spools a mail in the case the exception is unknown
        and unhandled.

        :param e: A `Twisted.python.Failure` instance that wraps a `GLException`
                  or a normal `Exception`
        :param request: A `twisted.web.Request`
        """
        if isinstance(e, NoResultFound):
            e = errors.ResourceNotFound()
        elif isinstance(e, errors.GLException):
            pass
        elif isinstance(e.value, errors.GLException):
            e = e.value
        else:
            e.tid = request.tid
            e.url = request.hostname + request.path
            extract_exception_traceback_and_schedule_email(e)
            e = errors.InternalServerError('Unexpected')

        request.setResponseCode(e.status_code)
        request.setHeader(b'content-type', b'application/json')

        response = json.dumps({
            'error_message': e.reason,
            'error_code': e.error_code,
            'arguments': getattr(e, 'arguments', [])
        })

        request.write(response.encode())
Example #2
0
    def get(self):
        """
        Get the sitemap.xml
        """
        if not GLSettings.memory_copy.allow_indexing:
            raise errors.ResourceNotFound()

        site = 'https://' + GLSettings.memory_copy.hostname

        self.request.setHeader('Content-Type', 'text/xml')

        data = "<?xml version='1.0' encoding='UTF-8' ?>\n" + \
               "<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9' xmlns:xhtml='http://www.w3.org/1999/xhtml'>\n"

        for url in ['/#/', '/#/submission']:
            data += "  <url>\n" + \
                    "    <loc>" + site + url + "</loc>\n" + \
                    "    <changefreq>weekly</changefreq>\n" + \
                    "    <priority>1.00</priority>\n"

            for lang in sorted(GLSettings.memory_copy.languages_enabled):
                if lang != GLSettings.memory_copy.default_language:
                    l = lang.lower()
                    l = l.replace('_', '-')
                    data += "<xhtml:link rel='alternate' hreflang='" + l + "' href='" + site + "/#/?lang=" + lang + "' />\n"

            data += "  </url>\n"

        data += "</urlset>"

        return data
Example #3
0
    def get(self):
        """
        Get the sitemap.xml
        """
        if not State.tenant_cache[self.request.tid].allow_indexing:
            raise errors.ResourceNotFound()

        self.request.setHeader(b'Content-Type', b'text/xml')

        data = "<?xml version='1.0' encoding='UTF-8' ?>\n" + \
               "<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9' xmlns:xhtml='http://www.w3.org/1999/xhtml'>\n"

        if State.tenant_cache[self.request.tid].hostname:
            site = 'https://' + State.tenant_cache[self.request.tid].hostname

            data += "  <url>\n" + \
                    "    <loc>" + site + "/#/</loc>\n" + \
                    "    <changefreq>weekly</changefreq>\n" + \
                    "    <priority>1.00</priority>\n"

            for lang in sorted(
                    State.tenant_cache[self.request.tid].languages_enabled):
                if lang != State.tenant_cache[
                        self.request.tid].default_language:
                    hreflang = lang.lower().replace('_', '-')
                    data += "    <xhtml:link rel='alternate' hreflang='" + hreflang + "' href='" + site + "/#/?lang=" + lang + "' />\n"

            data += "  </url>\n"

        data += "</urlset>"

        return data
Example #4
0
def translate_shorturl(session, tid, shorturl):
    shorturl = session.query(models.ShortURL).filter(
        models.ShortURL.shorturl == shorturl,
        models.ShortURL.tid == tid).one_or_none()
    if shorturl is None:
        raise errors.ResourceNotFound()

    return shorturl.longurl
Example #5
0
    def write_file(self, filepath):
        if not os.path.exists(filepath) or not os.path.isfile(filepath):
            raise errors.ResourceNotFound()

        mime_type, encoding = mimetypes.guess_type(filepath)
        if mime_type:
            self.request.setHeader("Content-Type", mime_type)

        return StaticFileProducer(self.request, filepath).start()
Example #6
0
    def force_file_download(self, filename, filepath):
        if not os.path.exists(filepath) or not os.path.isfile(filepath):
            raise errors.ResourceNotFound()

        self.request.setHeader('X-Download-Options', 'noopen')
        self.request.setHeader('Content-Type', 'application/octet-stream')
        self.request.setHeader('Content-Disposition', 'attachment; filename=\"%s\"' % filename)

        return FileProducer(self.request, filepath).start()
Example #7
0
    def get(self, filename):
        if not filename:
            filename = 'index.html'

        abspath = os.path.abspath(os.path.join(self.root, filename))

        directory_traversal_check(self.root, abspath)

        if os.path.exists(abspath) and os.path.isfile(abspath):
            return self.write_file(filename, abspath)

        raise errors.ResourceNotFound()
Example #8
0
    def write_file(self, filename, filepath):
        if not os.path.exists(filepath) or not os.path.isfile(filepath):
            raise errors.ResourceNotFound()

        if filename.endswith('.gz'):
            self.request.setHeader("Content-encoding", "gzip")
            filename = filename[:-3]

        mime_type, _ = mimetypes.guess_type(filename)
        if mime_type:
            self.request.setHeader("Content-Type", mime_type)

        return FileProducer(self.request, filepath).start()
Example #9
0
    def download_wbfile(self, session, tid, file_id):
        wbfile, wbtip = db_get(
            session, (models.WhistleblowerFile, models.WhistleblowerTip),
            (models.WhistleblowerFile.id == file_id,
             models.WhistleblowerFile.receivertip_id == models.ReceiverTip.id,
             models.ReceiverTip.internaltip_id == models.WhistleblowerTip.id))

        if not self.user_can_access(session, tid, wbfile):
            raise errors.ResourceNotFound()

        self.access_wbfile(session, wbfile)

        return serializers.serialize_wbfile(session, wbfile), base64.b64decode(
            wbtip.crypto_tip_prv_key)
Example #10
0
    def download_wbfile(self, session, tid, file_id):
        wbfile, wbtip, = db_get(
            session, (models.WhistleblowerFile, models.WhistleblowerTip),
            (models.WhistleblowerFile.id == file_id,
             models.WhistleblowerFile.receivertip_id == models.ReceiverTip.id,
             models.ReceiverTip.internaltip_id == models.WhistleblowerTip.id))

        rtip = session.query(models.ReceiverTip) \
                      .filter(models.ReceiverTip.receiver_id == self.current_user.user_id,
                              models.ReceiverTip.internaltip_id == wbtip.id).one_or_none()
        if not rtip:
            raise errors.ResourceNotFound()

        self.access_wbfile(session, wbfile)

        return serializers.serialize_wbfile(session, wbfile), base64.b64decode(
            rtip.crypto_tip_prv_key)
Example #11
0
def get_l10n(session, tid, lang):
    path = langfile_path(lang)
    directory_traversal_check(Settings.client_path, path)

    if not os.path.exists(path):
        raise errors.ResourceNotFound()

    texts = read_json_file(path)

    custom_texts = session.query(models.CustomTexts).filter(
        models.CustomTexts.lang == lang,
        models.CustomTexts.tid == tid).one_or_none()
    custom_texts = custom_texts.texts if custom_texts is not None else {}

    texts.update(custom_texts)

    return texts
Example #12
0
    def get(self):
        """
        Get the sitemap.xml
        """
        if not State.tenant_cache[self.request.tid].allow_indexing:
            raise errors.ResourceNotFound()

        self.request.setHeader(b'Content-Type', b'text/xml')

        data = "<?xml version='1.0' encoding='UTF-8' ?>\n" + \
               "<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9' xmlns:xhtml='http://www.w3.org/1999/xhtml'>\n"

        tids = [self.request.tid]
        if self.request.tid == 1:
            tids = State.tenant_cache.keys()

        for tid in tids:
            urls = ['/#/']

            site = 'https://' + State.tenant_cache[tid].hostname

            if tid == 1 and State.tenant_cache[1].enable_signup:
                urls.append('/#/signup')
            else:
                urls.append('/#/submission')

            for url in urls:
                data += "  <url>\n" + \
                        "    <loc>" + site + url + "</loc>\n" + \
                        "    <changefreq>weekly</changefreq>\n" + \
                        "    <priority>1.00</priority>\n"

                for lang in sorted(State.tenant_cache[tid].languages_enabled):
                    if lang != State.tenant_cache[tid].default_language:
                        l = lang.lower()
                        l = l.replace('_', '-')
                        data += "<xhtml:link rel='alternate' hreflang='" + l + "' href='" + site + url + "?lang=" + lang + "' />\n"

                data += "  </url>\n"

        data += "</urlset>"

        return data
Example #13
0
def get_l10n(session, tid, lang):
    if tid != 1:
        config = ConfigFactory(session, 1)

        if config.get_val(u'mode') == u'whistleblowing.it':
            tid = 1

    path = langfile_path(lang)
    directory_traversal_check(Settings.client_path, path)

    if not os.path.exists(path):
        raise errors.ResourceNotFound()

    texts = read_json_file(path)

    custom_texts = session.query(models.CustomTexts).filter(models.CustomTexts.lang == lang, models.CustomTexts.tid == tid).one_or_none()
    custom_texts = custom_texts.texts if custom_texts is not None else {}

    texts.update(custom_texts)

    return texts
Example #14
0
    def render(self, request):
        """
        :param request: `twisted.web.Request`

        :return: empty `str` or `NOT_DONE_YET`
        """
        request_finished = [False]

        def _finish(ret):
            request_finished[0] = True

        request.notifyFinish().addBoth(_finish)

        self.preprocess(request)

        if request.tid is None:
            # Tentative domain correction in relation to presence / absence of 'www.' prefix
            if not request.hostname.startswith(b'www.'):
                tentative_hostname = b'www.' + request.hostname
            else:
                tentative_hostname = request.hostname[4:]

            if tentative_hostname in State.tenant_hostname_id_map:
                request.tid = State.tenant_hostname_id_map[tentative_hostname]
                if State.tenant_cache[request.tid].https_enabled:
                    request.redirect(b'https://' + tentative_hostname + b'/')
                else:
                    request.redirect(b'http://' + tentative_hostname + b'/')
            else:
                # Fallback on root tenant with error 400
                request.tid = 1
                request.setResponseCode(400)

            self.set_headers(request)
            return b''

        self.set_headers(request)

        if self.should_redirect_tor(request):
            self.redirect_tor(request)
            return b''

        if self.should_redirect_https(request):
            self.redirect_https(request)
            return b''

        request_path = request.path.decode()

        if request_path in State.tenant_cache[request.tid]['redirects']:
            request.redirect(
                State.tenant_cache[request.tid]['redirects'][request_path])
            return b''

        match = None
        for regexp, handler, args in self._registry:
            try:
                match = regexp.match(request_path)
            except UnicodeDecodeError:
                match = None
            if match:
                break

        if match is None:
            self.handle_exception(errors.ResourceNotFound(), request)
            return b''

        method = request.method.lower().decode()

        if method == 'head':
            method = 'get'
        elif method == 'options':
            request.setResponseCode(200)
            return b''

        if method not in self.method_map.keys() or not hasattr(
                handler, method):
            self.handle_exception(errors.MethodNotImplemented(), request)
            return b''

        f = getattr(handler, method)
        groups = match.groups()

        self.handler = handler(State, request, **args)

        request.setResponseCode(self.method_map[method])

        if self.handler.root_tenant_only and request.tid != 1:
            self.handle_exception(errors.ForbiddenOperation(), request)
            return b''

        if self.handler.upload_handler and method == 'post':
            self.handler.process_file_upload()
            if self.handler.uploaded_file is None:
                return b''

        @defer.inlineCallbacks
        def concludeHandlerFailure(err):
            self.handle_exception(err, request)

            yield self.handler.execution_check()

            if not request_finished[0]:
                request.finish()

        @defer.inlineCallbacks
        def concludeHandlerSuccess(ret):
            """
            Concludes successful execution of a `BaseHandler` instance

            :param ret: A `dict`, `list`, `str`, `None` or something unexpected
            """
            yield self.handler.execution_check()

            if not request_finished[0]:
                if ret is not None:
                    if isinstance(ret, (dict, list)):
                        ret = json.dumps(ret,
                                         cls=JSONEncoder,
                                         separators=(',', ':'))
                        request.setHeader(b'content-type', b'application/json')

                    if isinstance(ret, str):
                        ret = ret.encode()

                    request.write(ret)

                request.finish()

        defer.maybeDeferred(f, self.handler,
                            *groups).addCallbacks(concludeHandlerSuccess,
                                                  concludeHandlerFailure)

        return NOT_DONE_YET
Example #15
0
    def render(self, request):
        """
        @param request: `twisted.web.Request`

        @return: empty `str` or `NOT_DONE_YET`
        """

        self.set_default_headers(request)

        request_finished = [False]

        def _finish(_):
            request_finished[0] = True

        request.notifyFinish().addBoth(_finish)

        match = None
        for regexp, handler, args in self._registry:
            match = regexp.match(request.path)
            if match:
                break

        if match is None:
            self.handle_exception(errors.ResourceNotFound(), request)
            return b''

        method = request.method.lower()
        if not method in ['get', 'post', 'put', 'delete'] or not hasattr(
                handler, method):
            self.handle_exception(errors.MethodNotImplemented(), request)
            return b''

        f = getattr(handler, method)

        groups = [unicode(g) for g in match.groups()]
        h = handler(request, **args)
        d = defer.maybeDeferred(f, h, *groups)

        @defer.inlineCallbacks
        def concludeHandlerFailure(err):
            yield h.execution_check()

            self.handle_exception(err, request)

            if not request_finished[0]:
                request.finish()

        @defer.inlineCallbacks
        def concludeHandlerSuccess(ret):
            """Concludes successful execution of a `BaseHandler` instance

            @param ret: A `dict`, `str`, `None` or something unexpected
            """
            yield h.execution_check()

            if not ret is None:
                h.write(ret)

            if not request_finished[0]:
                request.finish()

        d.addErrback(concludeHandlerFailure)
        d.addCallback(concludeHandlerSuccess)
        return NOT_DONE_YET
Example #16
0
    def render(self, request):
        """
        @param request: `twisted.web.Request`

        @return: empty `str` or `NOT_DONE_YET`
        """
        request_finished = [False]

        def _finish(ret):
            request_finished[0] = True

        request.notifyFinish().addBoth(_finish)

        self.preprocess(request)

        self.set_headers(request)

        if request.tid is None:
            self.handle_exception(errors.ResourceNotFound(), request)
            return b''

        if self.should_redirect_tor(request):
            self.redirect_tor(request)
            return b''

        if self.should_redirect_https(request):
            self.redirect_https(request)
            return b''

        request.path = request.path.decode('utf-8')

        if request.tid == 1:
            match = re.match(r'^/t/([0-9]+)(/.*)', request.path)
            if match is not None:
                groups = match.groups()
                request.tid, request.path = int(groups[0]), groups[1]

        match = None
        for regexp, handler, args in self._registry:
            try:
                match = regexp.match(request.path)
            except UnicodeDecodeError:
                match = None
            if match:
                break

        if match is None:
            self.handle_exception(errors.ResourceNotFound(), request)
            return b''

        method = request.method.lower().decode('utf-8')

        if method == 'head':
            # HEAD method is not really implemented
            # as trick we use the same approch of Twisted of
            # mapping the HEAD method on the GET method.
            method = 'get'

        if method not in self.method_map.keys() or not hasattr(handler, method):
            self.handle_exception(errors.MethodNotImplemented(), request)
            return b''

        f = getattr(handler, method)
        groups = [text_type(g) for g in match.groups()]

        self.handler = handler(State, request, **args)

        request.setResponseCode(self.method_map[method])

        if self.handler.root_tenant_only and request.tid != 1:
            self.handle_exception(errors.ForbiddenOperation(), request)
            return b''

        if self.handler.upload_handler and method == 'post':
            self.handler.process_file_upload()
            if self.handler.uploaded_file is None:
                return b''

        @defer.inlineCallbacks
        def concludeHandlerFailure(err):
            yield self.handler.execution_check()

            self.handle_exception(err, request)

            if not request_finished[0]:
                request.finish()

        @defer.inlineCallbacks
        def concludeHandlerSuccess(ret):
            """
            Concludes successful execution of a `BaseHandler` instance

            @param ret: A `dict`, `list`, `str`, `None` or something unexpected
            """
            yield self.handler.execution_check()

            if not request_finished[0]:
                if ret is not None:
                    if isinstance(ret, (dict, list)):
                        ret = json.dumps(ret, separators=(',', ':'))
                        request.setHeader(b'content-type', b'application/json')

                    if isinstance(ret, text_type):
                        ret = ret.encode()

                    request.write(ret)

                request.finish()

        defer.maybeDeferred(f, self.handler, *groups).addCallbacks(concludeHandlerSuccess, concludeHandlerFailure)

        return NOT_DONE_YET
Example #17
0
 def check_file_presence(self, filepath):
     if not os.path.exists(filepath) or not os.path.isfile(filepath):
         raise errors.ResourceNotFound()
Example #18
0
    def render(self, request):
        """
        @param request: `twisted.web.Request`

        @return: empty `str` or `NOT_DONE_YET`
        """
        request_finished = [False]

        def _finish(ret):
            request_finished[0] = True

        request.notifyFinish().addBoth(_finish)

        self.preprocess(request)

        if self.should_redirect_tor(request):
            self.redirect_tor(request)
            return b''

        if self.should_redirect_https(request):
            self.redirect_https(request)
            return b''

        match = None
        for regexp, handler, args in self._registry:
            match = regexp.match(request.path)
            if match:
                break

        if match is None:
            self.handle_exception(errors.ResourceNotFound(), request)
            return b''

        method = request.method.lower()
        if not method in self.method_map or not hasattr(handler, method):
            self.handle_exception(errors.MethodNotImplemented(), request)
            return b''
        else:
            request.setResponseCode(self.method_map[method])

        f = getattr(handler, method)

        groups = [unicode(g) for g in match.groups()]
        h = handler(State, request, **args)

        d = defer.maybeDeferred(f, h, *groups)

        @defer.inlineCallbacks
        def concludeHandlerFailure(err):
            yield h.execution_check()

            self.handle_exception(err, request)

            if not request_finished[0]:
                request.finish()

        @defer.inlineCallbacks
        def concludeHandlerSuccess(ret):
            """
            Concludes successful execution of a `BaseHandler` instance

            @param ret: A `dict`, `list`, `str`, `None` or something unexpected
            """
            yield h.execution_check()

            if not request_finished[0]:
                if ret is not None:
                    if isinstance(ret, (types.DictType, types.ListType)):
                        ret = json.dumps(ret, separators=(',', ':'))
                        request.setHeader(b'content-type', b'application/json')

                    request.write(bytes(ret))

                request.finish()

        d.addErrback(concludeHandlerFailure)
        d.addCallback(concludeHandlerSuccess)

        return NOT_DONE_YET