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
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()
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()
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, )
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")
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))
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')
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
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'
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
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
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'])
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)
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)
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()
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/'
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)
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
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
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
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
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)
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))
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)
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)
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'] )
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)
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)
def setUp(self): app.testing = True app.config['CSRF_ENABLED'] = False self.client = app.test_client() Paste.init_table() User.init_table()
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
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
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'