def create_app(): cork = get_cork_instance() cork.require( role="user", fail_redirect="/?error=You are not authorized to access this page.") current_user = get_current_user(cork) name = bottle.request.forms.get('name') if not name: bottle.redirect("/dashboard?error={}".format("App must have a name.")) return if "/" in name or ".." in name: error = "Invalid app name: cannot contain .. or /" bottle.redirect("/dashboard?error={}".format(error)) upload = bottle.request.files.get('upload') if upload.content_length > 1000000: #cap uploads to 1Mb error = "Failed to upload app: exceeded maximum of 1Mb" app_settings.logger.info("user attempted large upload", extra={ "actor": current_user, "action": "created file", "object": name }) bottle.redirect("/dashboard?error={}".format(error)) db = FileDBOMongo(app_settings.get_database()) success = db.add_file(upload.file.read(), name, current_user, "app") if not success: error = "Failed to upload app." app_settings.logger.error("error uploading app", extra={ "actor": current_user, "action": "created app", "object": name }) bottle.redirect("/dashboard?error={}".format(error)) else: for xx in range(0, int(app_settings.BIGCGI_TOTAL_INSTANCES)): sync_file.apply_async(args=[name, current_user, "app"], kwargs={}, queue='bigcgi_instance_' + str(xx)) flash = "Successfully uploaded app." db = AppDBOMongo(app_settings.get_database()) db.create(name, current_user) app_settings.logger.info("file created", extra={ "actor": current_user, "action": "created app", "object": name }) bottle.redirect("/dashboard?flash={}".format(flash))
def del_file(filename): cork = get_cork_instance() cork.require( role="user", fail_redirect="/?error=You are not authorized to access this page.") current_user = get_current_user(cork) db = FileDBOMongo(app_settings.get_database()) success = db.delete_file(filename, current_user, "file") if not success: error = "Failed to delete file." app_settings.logger.error("error deleteing file", extra={ "actor": current_user, "action": "delete file", "object": filename }) bottle.redirect("/dashboard?error={}".format(error)) else: for xx in range(0, int(app_settings.BIGCGI_TOTAL_INSTANCES)): delete_file.apply_async(args=[current_user, filename, "file"], kwargs={}, queue='bigcgi_instance_' + str(xx)) app_settings.logger.info("file deleted", extra={ "actor": current_user, "action": "delete file", "object": filename }) bottle.redirect("/dashboard?flash={}".format("Successful delete."))
def sync_files(user): try: username = user["username"] except KeyError: print("invalid user: "******"name"], username, "app") print("synced app: " + username + " -> " + app["name"]) #sync files files_db = FileDBOMongo(app_settings.get_database()) user_files = files_db.get_user_files(username) for fil in user_files: sync_file.run(fil, username, "file") print("synced file: " + username + " -> " + fil)
def test_secure_app(): with boddle(params={}): response = secure_app("app1", 1) client = app_settings.get_database() result = client[app_settings.DATABASE_MAIN]["apps"].find_one({"name":"app1", "username": "******"}) assert int(result["security"]) == 1 response = secure_app("app1", 0) result = client[app_settings.DATABASE_MAIN]["apps"].find_one({"name":"app1", "username": "******"}) assert int(result["security"]) == 0
def test_delete_app(): with boddle(params={}): response = delete_app("app1") client = app_settings.get_database() result = client[app_settings.DATABASE_MAIN]["apps"].find_one({"name":"app1", "username":"******"}) assert result == None #for app in AppDBOMongoMock.APPS: # assert not (app["name"] != "app1" and app["username"] != "testuser") bottle.redirect.assert_called_with("/dashboard?flash=Successful delete.")
def dashboard(): cork = get_cork_instance() cork.require( role="user", fail_redirect='/?error=You are not authorized to access this page.') flash, error = set_flash_and_error() current_user = get_current_user(cork) db = AppDBOMongo(app_settings.get_database()) apps = db.get_summary(current_user) file_db = FileDBOMongo(app_settings.get_database()) files = file_db.get_user_files(current_user) return bottle.template( "dashboard", { "title": "Dashboard", "current_user": current_user, "apps": apps, "files": files, "flash": flash, "error": error, "csrf": get_csrf_token() })
def secure_app(appname, security_setting): cork = get_cork_instance() cork.require( role="user", fail_redirect="/?error=You are not authorized to access this page.") current_user = get_current_user(cork) db = AppDBOMongo(app_settings.get_database()) db.secure_app(current_user, appname, security_setting) if security_setting == 1: bottle.redirect("/dashboard?flash=Secured app {}.".format(appname)) else: bottle.redirect("/dashboard?flash=Unsecured app {}.".format(appname))
def get_app_logs(appname): cork = get_cork_instance() cork.require( role="user", fail_redirect="/?error=You are not authorized to access this page.") current_user = get_current_user(cork) db = AppDBOMongo(app_settings.get_database()) logs = db.get_app_logs(current_user, appname) return bottle.template("app-logs", { "title": "Logs for " + appname, "current_user": current_user, "logs": logs })
def bigcgi_run(username, appname): db = AppDBOMongo(app_settings.get_database()) if db.app_secure(username, appname): try: creds = parse_basic_auth(bottle.request.headers) except AccessDeniedException as e: bottle.abort(401, str(e)) if not authorize(username, creds): bottle.abort(401, "Authorization failed.") else: creds = None start_time = time.time() output, error, return_value = util.cgi.run_cgi( appname, username, bottle.request.method, bottle.request.path, bottle.request.query_string, bottle.request.remote_addr, creds, bottle.request.content_type, bottle.request.body.read().decode("utf-8"), bottle.request.content_length, bottle.request.headers) elapsed = time.time() - start_time db.inc_hits(username, appname) db.inc_millisecs(username, appname, elapsed * 1000) if return_value == 1: output = bottle.template("app-error", { "output": output, "error": error }) headers = {"Status": 500} else: headers, output = util.cgi.parse_output(output) error_logs = error.split("\n") error_logs = [e for e in error_logs if e] if error_logs: db.app_log(username, appname, error_logs) content_type = headers.get("Content-Type", "text/html") access_control_allow_origin = headers.get("Access-Control-Allow-Origin", "*") status_code = headers.get("Status", 200) return bottle.HTTPResponse( status=status_code, body=output, headers=None, Content_Type=content_type, Access_Control_Allow_Origin=access_control_allow_origin, )
def sync_file(filename, username, kind): success = filesys.check_user_directories(username) if not success: return db = FileDBOMongo(app_settings.get_database()) sync_file = db.get_file(filename, username, kind) if sync_file: filesys.move_file_contents(filename, username, kind, sync_file) else: #file could have been deleted before task executed app_settings.logger.warning("filed to sync file: does not exist in db", extra={ "actor": "INSTANCE " + app_settings.BIGCGI_INSTANCE_ID, "action": "sync file", "object": username + "/" + filename })
def test_create_app(): with boddle(params={}): response = create_app() bottle.redirect.assert_called_with("/dashboard?error=App must have a name.") with boddle(params={"name":"app3"}): with patch('bottle.BaseRequest.files') as mock_files: mock_upload = MagicMock() mock_upload.content_length = 1000 mock_upload.file.read.return_value = b"file contents" mock_files.get.return_value = mock_upload response = create_app() bottle.redirect.assert_called_with("/dashboard?flash=Successfully uploaded app.") client = app_settings.get_database() last_inserted = client[app_settings.DATABASE_MAIN].apps.find_one({"name":"app3"}) assert last_inserted != None assert last_inserted["username"] == "testuser"
def create_test_app(): setup_func() #this tells the mock to default to having an app """ db.mongodbo.AppDBOMongo.APPS = [ {"name":"app1", "username":"******", "stats":{"hits":4, "total_millisecs":12}}, {"name":"app1", "username":"******", "stats":{"hits":4, "total_millisecs":12}}, {"name":"app2", "username":"******", "stats":{"hits":5, "total_millisecs":10}}, ] """ client = app_settings.get_database() client[app_settings.DATABASE_MAIN]["apps"].insert_one({"name":"app1", "username":"******", "stats":{"hits":4, "total_millisecs":12}}) client[app_settings.DATABASE_MAIN]["apps"].insert_one({"name":"app1", "username":"******", "stats":{"hits":4, "total_millisecs":12}}) client[app_settings.DATABASE_MAIN]["apps"].insert_one({"name":"app2", "username":"******", "stats":{"hits":5, "total_millisecs":10}})
def generate_monthly_report(): r = ReportingDBOMongo(app_settings.get_database()) r.create_monthly_hits_report() return True
def all_users(callback, *args): db = UserDBOMongo(app_settings.get_database()) users = db.get_all_users() for user in users: callback(user)
def remove_test_app(): client = app_settings.get_database() client[app_settings.DATABASE_MAIN]["apps"].remove({})