Beispiel #1
0
def create_app(config_file=None):
    app = Flask(__name__)
    auth = HTTPDigestAuth()
    app.config.setdefault('PYGMENTS_STYLE', 'friendly')
    app.config.setdefault('PYGMENTS_LINENOS', True)
    app.config.setdefault('PER_PAGE', 20)
    app.config.setdefault('SQLALCHEMY_DATABASE_URI',
                          'sqlite:////tmp/ownpaste.db')
    app.config.setdefault('REALM', 'ownpaste')
    app.config.setdefault('USERNAME', 'ownpaste')
    app.config.setdefault('PASSWORD', auth.a1('test', app.config['USERNAME'],
                                              app.config['REALM']))
    app.config.setdefault('IP_BLOCK_HITS', 10)
    app.config.setdefault('IP_BLOCK_TIMEOUT', 60)  # in minutes
    app.config.setdefault('TIMEZONE', 'UTC')
    app.config.from_envvar('OWNPASTE_SETTINGS', True)
    if config_file is not None:
        app.config.from_pyfile(config_file)
    db.init_app(app)

    # register default error handler
    # based on: http://flask.pocoo.org/snippets/15/
    for _exc in default_exceptions:
        app.error_handler_spec[None][_exc] = error_handler
    del _exc
    app.error_handler_spec[None][401] = auth.challenge

    app.register_blueprint(views)

    @app.before_first_request
    def before_first_request():
        if (not app.debug) and app.config['PASSWORD'] == auth.a1('test'):
            raise RuntimeError('You should provide a password!!')

    return app
Beispiel #2
0
 def run(self):
     auth = HTTPDigestAuth()
     p1 = prompt_pass('Password')
     p2 = prompt_pass('Retype password')
     if p1 != p2:
         print >> sys.stderr, 'Passwords didn\'t match.'
         return
     print
     print 'Add this to your configuration file:'
     print 'PASSWORD = \'%s\'' % auth.a1(p1)
Beispiel #3
0
 def __init__(self, *args, **kwargs):
     self.auth = HTTPDigestAuth()
     MethodView.__init__(self, *args, **kwargs)
Beispiel #4
0
class PasteAPI(MethodView):
    def __init__(self, *args, **kwargs):
        self.auth = HTTPDigestAuth()
        MethodView.__init__(self, *args, **kwargs)

    def get(self, paste_id=None, action=None):

        # paste listing
        if paste_id is None:

            page = int(request.args.get("page", 1))
            per_page = current_app.config["PER_PAGE"]

            # private mode
            if request.args.get("private", "0") == "1":
                self.auth.required()
                query = Paste.all(hide_private=False)

            # normal mode
            else:
                query = Paste.all()

            pagination = query.paginate(page or 1, per_page)
            kwargs = dict(
                page=pagination.page, pages=pagination.pages, per_page=pagination.per_page, total=pagination.total
            )

            # json api
            if request_wants_json():
                return jsonify(dict(pastes=[i.to_json(True) for i in pagination.items], **kwargs))

            # html output
            return render_template("pastes.html", pagination=pagination)

        # paste rendering
        else:

            paste = Paste.get(paste_id)

            # if private ask for authentication
            if paste.private and paste_id.isdigit():
                self.auth.required()

            # guess output by browser's accept header
            if action is None:

                # json api
                if request_wants_json():
                    return jsonify(paste.to_json())

                # html output
                return render_template("paste.html", paste=paste)

            # browser goodies

            # plain text output
            if action == "raw":
                response = make_response(paste.file_content)
                response.headers["Content-Type"] = 'text/plain; charset="utf-8"'
                return response

            # force download
            if action == "download":
                content_type = "application/octet-stream"
                if len(paste.lexer.mimetypes):
                    content_type = paste.lexer.mimetypes[0]
                file_name = "untitled.txt"
                if paste.file_name is not None:
                    file_name = os.path.basename(paste.file_name)
                response = make_response(paste.file_content)
                response.headers["Content-Type"] = content_type
                response.headers["Content-Disposition"] = 'attachment; filename="%s"' % file_name
                return response

            # no render found
            abort(404)

    def post(self):
        self.auth.required()

        try:
            data = request.json
        except:
            abort(400)

        if data is None:
            abort(415)

        file_name = data.get("file_name")
        language = data.get("language")
        private = data.get("private", False)
        if not isinstance(private, bool):
            abort(400)
        try:
            file_content = data["file_content"]
        except KeyError:
            abort(400)

        # create object
        paste = Paste(file_content, file_name, language, private)

        db.session.add(paste)
        db.session.commit()

        # this api method isn't intended to be used in browsers, then we will
        # return json for everybody.
        return jsonify(paste.to_json(True))

    def delete(self, paste_id):
        self.auth.required()

        paste = paste = Paste.get(paste_id)
        db.session.delete(paste)
        db.session.commit()

        # this api method isn't intended to be used in browsers, then we will
        # return json for everybody.
        return jsonify()

    def patch(self, paste_id):
        self.auth.required()

        try:
            data = request.json
        except:
            abort(400)

        if data is None:
            abort(415)

        file_name = data.get("file_name")
        language = data.get("language")
        private = data.get("private")
        file_content = data.get("file_content")

        paste = Paste.get(paste_id)
        if file_name is not None:
            paste.file_name = file_name
        if language is not None:
            paste.language = language
        if private is not None:
            if not isinstance(private, bool):
                abort(400)
            paste.private = private
        if file_content is not None:
            if not isinstance(file_content, basestring):
                abort(400)
            paste.set_file_content(file_content)
        db.session.commit()

        # this api method isn't intended to be used in browsers, then we will
        # return json for everybody.
        return jsonify(paste.to_json(True))