Exemple #1
0
    def test_paste_creation(self):
        p = Paste.new("Look, we're testing!", password='******')

        # Pasting succeeded
        assert p is not None
        assert p['id'] == 1

        # Check passwords are being hashed
        # bcrypt outputs 60 bytes
        assert p['password'] != 'hunter2'
        assert len(p['password']) == 60

        # Now check paste creation using the web
        r = self.client.post('/', data=dict(
            paste='test',
            title='',
            password='',
            language='text',
            unlisted=None
        ))

        # Grab the newly made paste
        p = Paste.by_id(2)

        assert p['text'] == 'test'
        assert p['password'] is None
        assert r.status_code == 302
Exemple #2
0
def shortlink_backfill():
    cur = Paste._cursor()
    cur.execute("""
        SELECT * from pastes
        WHERE shortlink is null
        """)
    pastes = cur.fetchall()

    for paste in pastes:
        if paste['unlisted']:
            url = 'https://paste.buttscicl.es/u/' + paste['hash']
        else:
            url = 'https://paste.buttscicl.es/p/' + str(paste['id'])

        shortlink = Paste.get_shortlink(url)
        if shortlink is not None:
            cur.execute(
                """
                UPDATE pastes SET shortlink = %s
                WHERE hash = %s
                """, (shortlink, paste['hash']))
            Paste.conn.commit()
            print 'Done #' + str(paste['id'])

    cur.close()
Exemple #3
0
def shortlink_backfill():
    cur = Paste._cursor()
    cur.execute(
        """
        SELECT * from pastes
        WHERE shortlink is null
        """
    )
    pastes = cur.fetchall()

    for paste in pastes:
        if paste['unlisted']:
            url = 'https://paste.buttscicl.es/u/' + paste['hash']
        else:
            url = 'https://paste.buttscicl.es/p/' + str(paste['id'])

        shortlink = Paste.get_shortlink(url)
        if shortlink is not None:
            cur.execute(
                """
                UPDATE pastes SET shortlink = %s
                WHERE hash = %s
                """, (shortlink, paste['hash'])
            )
            Paste.conn.commit()
            print 'Done #' + str(paste['id'])

    cur.close()
Exemple #4
0
def view_paste(unlisted, attr, raw=None):
    if unlisted:
        paste = Paste.by_hash(attr)
    else:
        paste = Paste.by_id(attr)
        if paste is None or paste['unlisted']:
            abort(404)

    if paste is None:
        abort(404)

    # Check if paste is password protected, and if so,
    # whether the client is allowed to access it or not
    authorised = session.get('authorised_pastes', [])
    if (paste['password'] is not None and paste['hash'] not in authorised):
        return render_template('enter_password.html',
                               paste=paste,
                               form=PastePassword()), 401

    if raw is not None:
        r = make_response(paste['text'])
        r.mimetype = 'text/plain'
        return r

    return render_template(
        'view_paste.html',
        title=paste['title'],
        paste=paste,
    )
Exemple #5
0
def recent():
    if session.get("logged_in"):
        pastes = Paste.recent(include_unlisted=True)
    else:
        pastes = Paste.recent()

    return render_template("recent.html", pastes=pastes, title="recent pastes")
Exemple #6
0
def get():
    p_id = request.args.get('id', None, type=int)
    p_hash = request.args.get('hash', None)
    password = request.args.get('password')

    if p_hash:
        paste = Paste.by_hash(p_hash)
    elif p_id:
        paste = Paste.by_id(p_id)
    else:
        return jsonify(error='no id or hash supplied'), 400

    if paste is None:
        return jsonify(error='paste not found'), 404
    elif not p_hash and paste['unlisted']:
        return jsonify(error='paste is unlisted'), 400

    if paste['password']:
        if not password:
            return jsonify(error='paste is password protected'), 401
        elif not Paste.password_match(paste['hash'], password):
            return jsonify(error='incorrect password'), 401

    return jsonify(create_paste_dict(paste),
                   shorturl=paste['shortlink'],
                   url=create_paste_url(paste))
Exemple #7
0
def recent():
    if session.get('logged_in'):
        pastes = Paste.recent(include_unlisted=True)
    else:
        pastes = Paste.recent()

    return render_template('recent.html', pastes=pastes, title='recent pastes')
Exemple #8
0
    def test_paste_creation(self):
        p = Paste.new("Look, we're testing!", password='******')

        # Pasting succeeded
        assert p is not None
        assert p['id'] == 1

        # Check passwords are being hashed
        # bcrypt outputs 60 bytes
        assert p['password'] != 'hunter2'
        assert len(p['password']) == 60

        # Now check paste creation using the web
        r = self.client.post('/',
                             data=dict(paste='test',
                                       title='',
                                       password='',
                                       language='text',
                                       unlisted=None))

        # Grab the newly made paste
        p = Paste.by_id(2)

        assert p['text'] == 'test'
        assert p['password'] is None
        assert r.status_code == 302
Exemple #9
0
    def test_password_protection(self):
        Paste.new('Test', password='******')

        r = self.client.get('/p/1/')

        # 401 = unauthorised
        assert r.status_code == 401
        assert r.mimetype == 'text/html'
Exemple #10
0
    def test_password_protection(self):
        Paste.new('Test', password='******')

        r = self.client.get('/p/1/')

        # 401 = unauthorised
        assert r.status_code == 401
        assert r.mimetype == 'text/html'
Exemple #11
0
    def test_paste_deletion(self):
        self.add_account()
        p = Paste.new(text='test')

        self.client.post('/a/in',
                         data=dict(username='******', password='******'))

        self.client.post('/a/del/' + p['hash'],
                         data=dict(paste_hash=p['hash']))

        paste = Paste.by_hash(p['hash'])
        assert paste is None
Exemple #12
0
    def test_paste_deletion(self):
        self.add_account()
        p = Paste.new(text='test')

        self.client.post('/a/in', data=dict(
            username='******',
            password='******'
        ))

        self.client.post('/a/del/' + p['hash'], data=dict(
            paste_hash=p['hash']
        ))

        paste = Paste.by_hash(p['hash'])
        assert paste is None
Exemple #13
0
def add():
    form = request.form
    errors = []

    if form.get('unlisted', type=int) in (0, 1):
        unlisted = bool(form.get('unlisted', type=int))
    else:
        unlisted = False

    paste = {
        'text': form.get('contents'),
        'title': form.get('title'),
        'password': form.get('password'),
        'unlisted': unlisted,
        'language': form.get('language', 'text')
    }

    if paste['text'] is None:
        errors.append('No contents specified')
    if paste['unlisted'] not in (True, False):
        errors.append("Invalid value: (unlisted: '{0}')".format(
            paste['unlisted']))

    if errors:
        return jsonify(success=False, url=None, password=None, error=errors)

    p = Paste.new(**paste)
    if p is None:
        return jsonify(success=False, url=None, password=None, error=errors)

    return jsonify(success=True,
                   url=create_paste_url(p),
                   password=paste['password'])
Exemple #14
0
def index():
    form = NewPaste()
    if form.validate_on_submit():
        # WTForms passes '' for empty text values,
        # this lamba switches them to None
        f = lambda s: s if s != "" else None
        vals = {
            "text": form.paste.data,
            "title": f(form.title.data),
            "language": f(form.language.data),
            "password": f(form.password.data),
            "unlisted": f(form.unlisted.data),
        }
        paste = Paste.new(**vals)
        if paste is None:
            return redirect(url_for("pastes.index"))
        else:
            authorise_viewing(paste["hash"])
            if paste["unlisted"]:
                url = url_for("pastes.unlisted", paste_hash=paste["hash"])
            else:
                url = url_for("pastes.public", paste_id=paste["id"])
            return redirect(url)
    elif request.method == "POST":
        # Form submitted but failed validation
        for field, error in form.errors.items():
            errormsg = "{0}: {1}".format(field, error[0])
            flash(errormsg, "error")

    return render_template("index.html", form=form)
Exemple #15
0
def index():
    form = NewPaste()
    if form.validate_on_submit():
        # WTForms passes '' for empty text values,
        # this lambda switches them to None
        f = lambda s: s if s != '' else None
        vals = {
            'text': form.paste.data,
            'title': f(form.title.data),
            'language': f(form.language.data),
            'password': f(form.password.data),
            'unlisted': f(form.unlisted.data)
        }
        paste = Paste.new(**vals)
        if paste is None:
            return redirect(url_for('pastes.index'))
        else:
            authorise_viewing(paste['hash'])
            if paste['unlisted']:
                url = url_for('pastes.unlisted', paste_hash=paste['hash'])
            else:
                url = url_for('pastes.public', paste_id=paste['id'])
            return redirect(url)
    elif request.method == 'POST':
        # Form submitted but failed validation
        for field, error in form.errors.items():
            errormsg = '{0}: {1}'.format(field, error[0])
            flash(errormsg, 'error')

    return render_template('index.html', form=form)
Exemple #16
0
 def tearDown(self):
     # drop the table so we can
     # recreate it for other tests
     cur = Paste._cursor()
     cur.execute('DROP TABLE pastes')
     cur.execute('DROP TABLE users')
     cur.connection.commit()
     cur.close()
Exemple #17
0
    def test_url(self):
        with app.test_request_context():
            p = Paste.new(text='test')
            url = utils.create_paste_url(p)
            assert url == 'http://localhost/p/1/'

            url = utils.create_paste_url(p, relative=True)
            assert url == '/p/1/'
Exemple #18
0
 def tearDown(self):
     # drop the table so we can
     # recreate it for other tests
     cur = Paste._cursor()
     cur.execute('DROP TABLE pastes')
     cur.execute('DROP TABLE users')
     cur.connection.commit()
     cur.close()
Exemple #19
0
    def test_url(self):
        with app.test_request_context():
            p = Paste.new(text='test')
            url = utils.create_paste_url(p)
            assert url == 'http://localhost/p/1/'

            url = utils.create_paste_url(p, relative=True)
            assert url == '/p/1/'
Exemple #20
0
def delete_paste(hash):
    form = DeletePasteForm()
    if form.validate_on_submit():
        if not Paste.delete(form.paste_hash.data):
            flash('Deletion failed', 'error')
            return redirect(request.url)

        return redirect(url_for('pastes.recent'))

    return render_template('delete.html', form=form, hash=hash)
Exemple #21
0
    def test_honeypot(self):
        self.client.post('/',
                         data=dict(text='test',
                                   title='',
                                   password='',
                                   language='text',
                                   unlisted=None,
                                   uid='invalid'))

        assert Paste.by_id(1) is None
Exemple #22
0
def delete_paste(hash):
    form = DeletePasteForm()
    if form.validate_on_submit():
        if not Paste.delete(form.paste_hash.data):
            flash('Deletion failed', 'error')
            return redirect(request.url)

        return redirect(url_for('pastes.recent'))

    return render_template('delete.html', form=form, hash=hash)
Exemple #23
0
    def test_honeypot(self):
        self.client.post('/', data=dict(
            text='test',
            title='',
            password='',
            language='text',
            unlisted=None,
            uid='invalid'
        ))

        assert Paste.by_id(1) is None
Exemple #24
0
    def test_unlisted_paste(self):
        p = Paste.new('Test', unlisted=True)

        id = p['id']
        hash = p['hash']

        # Unlisted pastes should only be
        # accessed via /u/:hash
        r = self.client.get('/p/{0}/'.format(id))
        assert r.status_code == 404

        r = self.client.get('/u/{0}/'.format(hash))
        assert r.status_code == 200
Exemple #25
0
    def test_unlisted_paste(self):
        p = Paste.new('Test', unlisted=True)

        id = p['id']
        hash = p['hash']

        # Unlisted pastes should only be
        # accessed via /u/:hash
        r = self.client.get('/p/{0}/'.format(id))
        assert r.status_code == 404

        r = self.client.get('/u/{0}/'.format(hash))
        assert r.status_code == 200
Exemple #26
0
    def test_password_authentication(self):
        p = Paste.new('Test', password='******')

        with self.client as c:
            r = c.post('/p/authorise', data=dict(
                paste_hash=p['hash'],
                password='******',
                redirect='http://localhost/p/1/',
            ))

            # Check we've got the correct cookie
            # and are being redirected
            assert p['hash'] in session.get('authorised_pastes')
            assert r.status_code == 302
Exemple #27
0
def view_paste(unlisted, attr, raw=None):
    if unlisted:
        paste = Paste.by_hash(attr)
    else:
        paste = Paste.by_id(attr)
        if paste is None or paste["unlisted"]:
            abort(404)

    if paste is None:
        abort(404)

    # Check if paste is password protected, and if so,
    # whether the client is allowed to access it or not
    authorised = session.get("authorised_pastes", [])
    if paste["password"] is not None and paste["hash"] not in authorised:
        return render_template("enter_password.html", paste=paste, form=PastePassword()), 401

    if raw is not None:
        r = make_response(paste["text"])
        r.mimetype = "text/plain"
        return r

    return render_template("view_paste.html", title=paste["title"], paste=paste)
Exemple #28
0
def get():
    p_id = request.args.get("id", None, type=int)
    p_hash = request.args.get("hash", None)
    password = request.args.get("password")

    if p_hash:
        paste = Paste.by_hash(p_hash)
    elif p_id:
        paste = Paste.by_id(p_id)
    else:
        return jsonify(error="no id or hash supplied"), 400

    if paste is None:
        return jsonify(error="paste not found"), 404
    elif not p_hash and paste["unlisted"]:
        return jsonify(error="paste is unlisted"), 400

    if paste["password"]:
        if not password:
            return jsonify(error="paste is password protected"), 401
        elif not Paste.password_match(paste["hash"], password):
            return jsonify(error="incorrect password"), 401

    return jsonify(create_paste_dict(paste), shorturl=paste["shortlink"], url=create_paste_url(paste))
Exemple #29
0
    def test_password_authentication(self):
        p = Paste.new('Test', password='******')

        with self.client as c:
            r = c.post('/p/authorise',
                       data=dict(
                           paste_hash=p['hash'],
                           password='******',
                           redirect='http://localhost/p/1/',
                       ))

            # Check we've got the correct cookie
            # and are being redirected
            assert p['hash'] in session.get('authorised_pastes')
            assert r.status_code == 302
Exemple #30
0
def submit_password():
    form = PastePassword()
    if form.validate_on_submit():
        p_hash = form.paste_hash.data
        password = form.password.data

        if Paste.password_match(p_hash, password):
            # Password correct, add paste hash to authorised_pastes
            authorise_viewing(p_hash)
        else:
            # Todo: log & cap number of incorrect tries
            flash("Incorrect password", "error")

        return redirect(form.redirect.data)
    else:
        return redirect(form.redirect.data)
Exemple #31
0
def submit_password():
    form = PastePassword()
    if form.validate_on_submit():
        p_hash = form.paste_hash.data
        password = form.password.data

        if Paste.password_match(p_hash, password):
            # Password correct, add paste hash to authorised_pastes
            authorise_viewing(p_hash)
        else:
            # Todo: log & cap number of incorrect tries
            flash('Incorrect password', 'error')

        return redirect(form.redirect.data)
    else:
        return redirect(form.redirect.data)
Exemple #32
0
def add():
    form = request.form
    errors = []

    if form.get('unlisted', type=int) in (0, 1):
        unlisted = bool(form.get('unlisted', type=int))
    else:
        unlisted = False

    paste = {
        'text': form.get('contents'),
        'title': form.get('title'),
        'password': form.get('password'),
        'unlisted': unlisted,
        'language': form.get('language', 'text')
    }

    if paste['text'] is None:
        errors.append('No contents specified')
    if paste['unlisted'] not in (True, False):
        errors.append(
            "Invalid value: (unlisted: '{0}')".format(paste['unlisted'])
        )

    if errors:
        return jsonify(
            success=False,
            url=None,
            password=None,
            error=errors
        )

    p = Paste.new(**paste)
    if p is None:
        return jsonify(
            success=False,
            url=None,
            password=None,
            error=errors
        )

    return jsonify(
        success=True,
        url=create_paste_url(p),
        password=paste['password']
    )
Exemple #33
0
def new():
    """
    Endpoint for creating a new paste.
    """
    form = request.form

    text = form.get('text')
    if text is None:
        return jsonify(error='required value missing: text'), 400

    unlisted = form.get('unlisted', 'f')
    if unlisted.lower() in ('1', 'true', 't', 'y'):
        unlisted = True
    else:
        unlisted = False

    paste = {
        'text': text,
        'title': form.get('title'),
        'language': form.get('lang', 'text'),
        'password': form.get('password'),
        'unlisted': unlisted,
    }

    p = Paste.new(**paste)
    if not Paste:
        return internal_server_error()

    response = {
        'url': create_paste_url(p),
        'shorturl': p['shortlink'],
        'paste': create_paste_dict(p),
        'password': paste['password'],
    }

    return jsonify(response)
Exemple #34
0
def new():
    """
    Endpoint for creating a new paste.
    """
    form = request.form

    text = form.get("text")
    if text is None:
        return jsonify(error="required value missing: text"), 400

    unlisted = form.get("unlisted", "f")
    if unlisted.lower() in ("1", "true", "t", "y"):
        unlisted = True
    else:
        unlisted = False

    paste = {
        "text": text,
        "title": form.get("title"),
        "language": form.get("lang", "text"),
        "password": form.get("password"),
        "unlisted": unlisted,
    }

    p = Paste.new(**paste)
    if not Paste:
        return internal_server_error()

    response = {
        "url": create_paste_url(p),
        "shorturl": p["shortlink"],
        "paste": create_paste_dict(p),
        "password": paste["password"],
    }

    return jsonify(response)
Exemple #35
0
 def setUp(self):
     app.testing = True
     app.config['CSRF_ENABLED'] = False
     self.client = app.test_client()
     Paste.init_table()
     User.init_table()
Exemple #36
0
    except:
        return None


app = Flask(__name__)
app.config.from_pyfile('config.py')
app.config['VERSION'] = get_version()

if app.config.get('SENTRY_DSN'):
    from raven.contrib.flask import Sentry
    sentry = Sentry(app)

from PyPaste.models.pastes import Paste
from PyPaste.models.users import User

Paste.init_table()
User.init_table()

from PyPaste.views.errors import errors
from PyPaste.views.pastes import pastes
from PyPaste.views.admin import admin
from PyPaste.views import api

app.register_blueprint(errors)
app.register_blueprint(pastes)
app.register_blueprint(admin)
app.register_blueprint(api.legacy)
app.register_blueprint(api.v1)

# This allows us to enforce the FORCE_SSL config option
# Any redirection should be done at the httpd level
Exemple #37
0
    except:
        return None

app = Flask(__name__)
app.config.from_pyfile('config.py')
app.config['VERSION'] = get_version()

if app.config.get('SENTRY_DSN'):
    from raven.contrib.flask import Sentry
    sentry = Sentry(app)


from PyPaste.models.pastes import Paste
from PyPaste.models.users import User

Paste.init_table()
User.init_table()

from PyPaste.views.errors import errors
from PyPaste.views.pastes import pastes
from PyPaste.views.admin import admin
from PyPaste.views import api

app.register_blueprint(errors)
app.register_blueprint(pastes)
app.register_blueprint(admin)
app.register_blueprint(api.legacy)
app.register_blueprint(api.v1)


# This allows us to enforce the FORCE_SSL config option
Exemple #38
0
 def test_raw_paste(self):
     Paste.new('Hello World!')
     r = self.client.get('/p/1/raw/')
     assert r.status_code == 200
     assert r.mimetype == 'text/plain'
Exemple #39
0
 def setUp(self):
     app.testing = True
     app.config['CSRF_ENABLED'] = False
     self.client = app.test_client()
     Paste.init_table()
     User.init_table()
Exemple #40
0
 def test_raw_paste(self):
     Paste.new('Hello World!')
     r = self.client.get('/p/1/raw/')
     assert r.status_code == 200
     assert r.mimetype == 'text/plain'