Beispiel #1
0
    def test_thread(self):
        self.assertEqual(parse.thread("asdf"), (None, 'Untitled.'))

        self.assertEqual(
            parse.thread("""
            <html>
            <head>
                <title>Foo!</title>
            </head>
            <body>
                <header>
                    <h1>generic website title.</h1>
                    <h2>subtile title.</h2>
                </header>
                <article>
                    <header>
                        <h1>Can you find me?</h1>
                    </header>
                    <section id="isso-thread">
                    </section>
                </article>
            </body>
            </html>"""), (None, 'Can you find me?'))

        self.assertEqual(
            parse.thread("""
            <html>
            <body>
            <h1>I'm the real title!1
            <section data-title="No way%21" id="isso-thread">
            """), (None, 'No way!'))

        self.assertEqual(
            parse.thread("""
            <section id="isso-thread" data-title="Test" data-isso-id="test">
            """), ('test', 'Test'))

        self.assertEqual(
            parse.thread('<section id="isso-thread" data-isso-id="Fuu.">'),
            ('Fuu.', 'Untitled.'))
Beispiel #2
0
    def test_thread(self):
        self.assertEqual(parse.thread("asdf"), (None, 'Untitled.'))

        self.assertEqual(parse.thread("""
            <html>
            <head>
                <title>Foo!</title>
            </head>
            <body>
                <header>
                    <h1>generic website title.</h1>
                    <h2>subtile title.</h2>
                </header>
                <article>
                    <header>
                        <h1>Can you find me?</h1>
                    </header>
                    <section id="isso-thread">
                    </section>
                </article>
            </body>
            </html>"""), (None, 'Can you find me?'))

        self.assertEqual(parse.thread("""
            <html>
            <body>
            <h1>I'm the real title!1
            <section data-title="No way%21" id="isso-thread">
            """), (None, 'No way!'))

        self.assertEqual(parse.thread("""
            <section id="isso-thread" data-title="Test" data-isso-id="test">
            """), ('test', 'Test'))

        self.assertEqual(parse.thread('<section id="isso-thread" data-isso-id="Fuu.">'),
                                      ('Fuu.', 'Untitled.'))
Beispiel #3
0
    def new(self, environ, request, uri):

        data = request.get_json()

        for field in set(data.keys()) - API.ACCEPT:
            data.pop(field)

        for key in ("author", "email", "website", "parent"):
            data.setdefault(key, None)

        valid, reason = API.verify(data)
        if not valid:
            return BadRequest(reason)

        for field in ("author", "email"):
            if data.get(field) is not None:
                data[field] = cgi.escape(data[field])

        data['mode'] = 2 if self.moderated else 1
        data['remote_addr'] = utils.anonymize(str(request.remote_addr))

        with self.isso.lock:
            if uri not in self.threads:
                with http.curl('GET', local("origin"), uri) as resp:
                    if resp and resp.status == 200:
                        uri, title = parse.thread(resp.read(), id=uri)
                    else:
                        return NotFound('URI does not exist')

                thread = self.threads.new(uri, title)
                self.signal("comments.new:new-thread", thread)
            else:
                thread = self.threads[uri]

        # notify extensions that the new comment is about to save
        self.signal("comments.new:before-save", thread, data)

        valid, reason = self.guard.validate(uri, data)
        if not valid:
            self.signal("comments.new:guard", reason)
            raise Forbidden(reason)

        with self.isso.lock:
            rv = self.comments.add(uri, data)

        # notify extension, that the new comment has been successfully saved
        self.signal("comments.new:after-save", thread, rv)

        cookie = functools.partial(dump_cookie,
            value=self.isso.sign([rv["id"], sha1(rv["text"])]),
            max_age=self.conf.getint('max-age'))

        rv["text"] = self.isso.render(rv["text"])
        rv["hash"] = pbkdf2(rv['email'] or rv['remote_addr'], self.isso.salt, 1000, 6).decode("utf-8")

        self.cache.set('hash', (rv['email'] or rv['remote_addr']).encode('utf-8'), rv['hash'])

        for key in set(rv.keys()) - API.FIELDS:
            rv.pop(key)

        # success!
        self.signal("comments.new:finish", thread, rv)

        resp = JSON(rv, 202 if rv["mode"] == 2 else 201)
        resp.headers.add("Set-Cookie", cookie(str(rv["id"])))
        resp.headers.add("X-Set-Cookie", cookie("isso-%i" % rv["id"]))
        return resp
Beispiel #4
0
    def new(self, environ, request, uri):

        data = request.get_json()

        for field in set(data.keys()) - API.ACCEPT:
            data.pop(field)

        for key in ("author", "email", "website", "parent"):
            data.setdefault(key, None)

        valid, reason = API.verify(data)
        if not valid:
            return BadRequest(reason)

        for field in ("author", "email", "website"):
            if data.get(field) is not None:
                data[field] = cgi.escape(data[field])

        if data.get("website"):
            data["website"] = normalize(data["website"])

        data['mode'] = 2 if self.moderated else 1
        data['remote_addr'] = utils.anonymize(str(request.remote_addr))

        with self.isso.lock:
            if uri not in self.threads:
                if 'title' not in data:
                    with http.curl('GET', local("origin"), uri) as resp:
                        if resp and resp.status == 200:
                            uri, title = parse.thread(resp.read(), id=uri)
                        else:
                            return NotFound('URI does not exist %s')
                else:
                    title = data['title']

                thread = self.threads.new(uri, title)
                self.signal("comments.new:new-thread", thread)
            else:
                thread = self.threads[uri]

        # notify extensions that the new comment is about to save
        self.signal("comments.new:before-save", thread, data)

        valid, reason = self.guard.validate(uri, data)
        if not valid:
            self.signal("comments.new:guard", reason)
            raise Forbidden(reason)

        with self.isso.lock:
            rv = self.comments.add(uri, data)

        # notify extension, that the new comment has been successfully saved
        self.signal("comments.new:after-save", thread, rv)

        cookie = functools.partial(dump_cookie,
                                   value=self.isso.sign(
                                       [rv["id"], sha1(rv["text"])]),
                                   max_age=self.conf.getint('max-age'))

        rv["text"] = self.isso.render(rv["text"])
        rv["hash"] = self.hash(rv['email'] or rv['remote_addr'])

        self.cache.set(
            'hash', (rv['email'] or rv['remote_addr']).encode('utf-8'), rv['hash'])

        rv = self._add_gravatar_image(rv)

        for key in set(rv.keys()) - API.FIELDS:
            rv.pop(key)

        # success!
        self.signal("comments.new:finish", thread, rv)

        resp = JSON(rv, 202 if rv["mode"] == 2 else 201)
        resp.headers.add("Set-Cookie", cookie(str(rv["id"])))
        resp.headers.add("X-Set-Cookie", cookie("isso-%i" % rv["id"]))
        return resp
Beispiel #5
0
    def new(self, environ, request, uri, key):
        data = request.get_json()

        # check access keys
        rv = self.db.execute(['SELECT uri FROM access WHERE key = ? ;'],
                             (key, )).fetchall()
        if not rv or rv[0][0] != uri:
            raise Forbidden

        for field in set(data.keys()) - API.ACCEPT:
            data.pop(field)

        for key in ("author", "parent"):
            data.setdefault(key, None)

        if data['parent'] is not None:
            data.setdefault('place', None)

        valid, reason = API.verify(data)
        if not valid:
            return BadRequest(reason)

        escaped = dict((key, cgi.escape(value) if value is not None else None)
                       for key, value in data.items())

        added = {}
        if escaped.get("website") is not None:
            added["website"] = normalize(escaped["website"])

        added['mode'] = 2 if self.moderated else 1

        prepared = dict(escaped)
        prepared.update(added)

        with self.isso.lock:
            if uri in self._threads:
                thread = self._threads[uri]
            else:
                if 'title' in prepared:
                    title = prepared['title']
                else:
                    with http.curl('GET', local("origin"), uri) as resp:
                        if resp and resp.status == 200:
                            uri, title = parse.thread(resp.read(), id=uri)
                        else:
                            return NotFound('URI does not exist %s')

                thread = self._threads.new(uri, title)
                self.signal("comments.new:new-thread", thread)
        # notify extensions that the new comment is about to save
        self.signal("comments.new:before-save", thread, prepared)

        valid, reason = self.guard.validate(uri, prepared)
        if not valid:
            self.signal("comments.new:guard", reason)
            raise Forbidden(reason)

        with self.isso.lock:
            rv = self.comments.add(uri, prepared)

        # notify extension, that the new comment has been successfully saved
        self.signal("comments.new:after-save", thread, rv)

        cookie = functools.partial(dump_cookie,
                                   value=self.isso.sign(
                                       [rv["id"], sha1(rv["text"])]),
                                   max_age=self.conf.getint('max-age'))

        rv["text"] = self.isso.render(rv["text"])
        rv["hash"] = self.hash(rv['remote_addr'])

        self.cache.set('hash', (rv['remote_addr']).encode('utf-8'), rv['hash'])

        for key in set(rv.keys()) - API.FIELDS:
            rv.pop(key)

        # success!
        self.signal("comments.new:finish", thread, rv)

        resp = JSON(rv, 202 if rv["mode"] == 2 else 201)
        resp.headers.add("Set-Cookie", cookie(str(rv["id"])))
        resp.headers.add("X-Set-Cookie", cookie("isso-%i" % rv["id"]))
        return resp
Beispiel #6
0
    def new(self, environ, request, uri):

        logger.debug("got uri :%s" % uri)
        logger.debug("got eviron :%s" % str(environ))
        logger.debug("got request :%s" % pprint.pformat(request.__dict__))
                
        data = request.get_json()

        logger.debug("got data :%s" % data)

        
        for field in set(data.keys()) - API.ACCEPT:
            f = data.pop(field)
            logger.debug("skip data %s:%s" % (field, f ))

        for key in ("author", "email", "website", "parent"):
            data.setdefault(key, None)

        valid, reason = API.verify(data)
        if not valid:
            return BadRequest(reason)

        for field in ("author", "email", "website"):
            if data.get(field) is not None:
                data[field] = cgi.escape(data[field])

        if data.get("website"):
            data["website"] = normalize(data["website"])

        data['mode'] = 2 if self.moderated else 1

        logger.debug("request.remote_addr %s" % (request.remote_addr ))
                    
        data['remote_addr'] = utils.anonymize(str(request.remote_addr))

        with self.isso.lock:
            if uri not in self.threads:
                org = str(local("origin"))
                if org == '<LocalProxy unbound>':
                    org = environ['HTTP_ORIGIN']

                logger.debug("got origin %s" % (org))
                
                with http.curl('GET', org, uri) as resp:
                    if resp and resp.status == 200:
                        uri, title = parse.thread(resp.read(), id=uri)
                    else:
                        return NotFound('URI does not exist')

                thread = self.threads.new(uri, title)
                self.signal("comments.new:new-thread", thread)
            else:
                thread = self.threads[uri]

        # notify extensions that the new comment is about to save
        self.signal("comments.new:before-save", thread, data)

        valid, reason = self.guard.validate(uri, data)
        if not valid:
            self.signal("comments.new:guard", reason)
            raise Forbidden(reason)

        with self.isso.lock:
            rv = self.comments.add(uri, data)

        # notify extension, that the new comment has been successfully saved
        self.signal("comments.new:after-save", thread, rv)

        cookie = functools.partial(dump_cookie,
            value=self.isso.sign([rv["id"], sha1(rv["text"])]),
            max_age=self.conf.getint('max-age'))

        rv["text"] = self.isso.render(rv["text"])
        rv["hash"] = self.hash(rv['email'] or rv['remote_addr'])

        self.cache.set('hash', (rv['email'] or rv['remote_addr']).encode('utf-8'), rv['hash'])

        for key in set(rv.keys()) - API.FIELDS:
            rv.pop(key)

        # success!
        self.signal("comments.new:finish", thread, rv)

        resp = JSON(rv, 202 if rv["mode"] == 2 else 201)
        resp.headers.add("Set-Cookie", cookie(str(rv["id"])))
        resp.headers.add("X-Set-Cookie", cookie("isso-%i" % rv["id"]))
        return resp