Exemple #1
0
    def list_backups_for_server(self, server_id):
        # Grab our backup path from the DB
        backup_list = Backups.get(Backups.server_id == int(server_id))

        # Join into a full path
        backup_folder = self.get_backup_folder_for_server(server_id)
        server_backup_dir = os.path.join(backup_list.storage_location,
                                         backup_folder)

        #helper.ensure_dir_exists(server_backup_dir)

        svr_obj = multi.get_server_obj(server_id)
        return svr_obj.list_backups()
Exemple #2
0
    def post(self):
        token = self.get_argument('token')
        user = self.authenticate_user(token)

        if user is None:
            self.access_denied('unknown')

        if not check_role_permission(
                user, 'api_access') and not check_role_permission(
                    user, 'svr_control'):
            self.access_denied(user)

        server_id = self.get_argument('id')
        server = multi.get_server_obj(server_id)

        server.restart_threaded_server()
        self.return_response(200, {}, {'code': 'SER_RESTART_CALLED'}, {})
Exemple #3
0
    def post(self):
        token = self.get_argument('token')
        user = self.authenticate_user(token)

        if user is None:
            self.access_denied('unknown')

        if not check_role_permission(
                user, 'api_access') and not check_role_permission(
                    user, 'backups'):
            self.access_denied(user)

        server_id = self.get_argument('id')
        server = multi.get_server_obj(server_id)

        backup_thread = threading.Thread(name='backup',
                                         target=server.backup_server,
                                         daemon=False)
        backup_thread.start()

        self.return_response(200, {}, {'code': 'SER_BAK_CALLED'}, {})
    def do_start(self, line):
        if line == '':
            self.help_start()
            return 0

        try:
            int(line)
        except ValueError:
            console.error("Server ID must be a number")
            self.help_start()
            return 0

        try:
            server = MC_settings.get_by_id(line)

        except Exception as e:
            console.help("Unable to find a server with that ID: {}".format(e))
            return 0

        server = int(line)

        if helper.is_setup_complete():

            srv_obj = multi.get_server_obj(server)

            if srv_obj.check_running():
                console.warning("Server already running")
            else:
                console.info("Starting Minecraft Server in background")

                Remote.insert({
                    Remote.command: 'start_mc_server',
                    Remote.server_id: server,
                    Remote.command_source: "localhost"
                }).execute()

        else:
            console.warning(
                "Unable to start server, please complete setup in the web GUI first"
            )
    def do_stop(self, line):
        if line == '':
            self.help_stop()
            return 0

        try:
            int(line)
        except ValueError:
            console.error("Server ID must be a number")
            self.help_stop()
            return 0

        try:
            server = MC_settings.get_by_id(line)

        except Exception as e:
            console.help("Unable to find a server with that ID: {}".format(e))
            return 0

        server = int(line)

        if helper.is_setup_complete():

            srv_obj = multi.get_server_obj(server)

            if not srv_obj.check_running():
                console.warning("Server already stopped")
            else:
                console.info("Stopping Minecraft Server")
                multi.stop_server(server)
                '''
                Remote.insert({
                    Remote.command: 'stop_mc_server'
                }).execute()
                '''
        else:
            console.warning(
                "Unable to stop server, please complete setup in the web GUI first"
            )
Exemple #6
0
    def post(self):
        token = self.get_argument('token')
        user = self.authenticate_user(token)

        if user is None:
            self.access_denied('unknown')

        if not check_role_permission(
                user, 'api_access') and not check_role_permission(
                    user, 'svr_control'):
            self.access_denied(user)

        command = self.get_body_argument('command', default=None, strip=True)
        server_id = self.get_argument('id')
        if command:
            server = multi.get_server_obj(server_id)
            if server.check_running:
                server.send_command(command)
                self.return_response(200, '', {"run": True}, '')
            else:
                self.return_response(200, {'error': 'SER_NOT_RUNNING'}, {}, {})
        else:
            self.return_response(200, {'error': 'NO_COMMAND'}, {}, {})
Exemple #7
0
    def post(self):
        token = self.get_argument('token')
        user = self.authenticate_user(token)

        if user is None:
            self.access_denied('unknown')

        if not check_role_permission(
                user, 'api_access') and not check_role_permission(
                    user, 'svr_control'):
            self.access_denied(user)

        server_id = self.get_argument('id')
        server = multi.get_server_obj(server_id)

        if not server.check_running():
            Remote.insert({
                Remote.command: 'start_mc_server',
                Remote.server_id: server_id,
                Remote.command_source: "localhost"
            }).execute()
            self.return_response(200, {}, {'code': 'SER_START_CALLED'}, {})
        else:
            self.return_response(500, {'error': 'SER_RUNNING'}, {}, {})
Exemple #8
0
    def get(self):
        token = self.get_argument('token')
        user = self.authenticate_user(token)

        if user is None:
            self.access_denied('unknown')

        if not check_role_permission(
                user, 'api_access') and not check_role_permission(
                    user, 'logs'):
            self.access_denied(user)

        server_id = self.get_argument('id')
        server = multi.get_server_obj(server_id)

        logfile = os.path.join(server.server_path, 'logs', 'latest.log')
        data = helper.search_file(logfile, '')
        line_list = []

        if data:
            for line in data:
                line_list.append({'line_num': line[0], 'message': line[1]})

        self.return_response(200, {}, line_list, {})
    def do_revert_server_jar(self, line):
        if line == '':
            self.help_update_server_jar()
            return 0

        try:
            int(line)
        except ValueError:
            console.error("Server ID must be a number")
            self.help_update_server_jar()
            return 0

        try:
            server = MC_settings.get_by_id(line)

        except Exception as e:
            console.help("Unable to find a server with that ID: {}".format(e))
            return 0

        server = int(line)

        if helper.is_setup_complete():

            srv_obj = multi.get_server_obj(server)

            console.info("Reverting updated Server Jar in background")

            Remote.insert({
                Remote.command: 'revert_server_jar_console',
                Remote.server_id: server,
                Remote.command_source: "localhost"
            }).execute()
        else:
            console.warning(
                "Unable to update server jar, please complete setup in the web GUI first"
            )
Exemple #10
0
    def backup_all_servers(self):
        logger.warning(
            "All server backup called. This may load your server massively!")
        # List all servers
        servers = multi.list_servers()

        # Iterate over them
        for server in servers:
            server_id = server['id']

            # Grab the server object
            server_obj = multi.get_server_obj(server_id)

            # Start the backup thread
            logger.info("Backing up server %s", server_id)
            backup_thread = threading.Thread(
                name='backup_server_{}'.format(server_id),
                target=server_obj.backup_server,
                daemon=False)
            backup_thread.start()
            logger.info("Backup thread running for server %s", server_id)

            # Slow down the process creation for older systems
            sleep(1)
    def handle_command(self, command, server_id):

        if command == "exit_crafty":
            logger.info("Sending Stop Command To Crafty")

            # stop the ftp server...
            if ftp_svr_object.check_running():
                ftp_svr_object.stop_threaded_ftp_server()

            # kill all mc servers gracefully
            try:
                multi.stop_all_servers()
            except:
                pass

            logger.info("***** Crafty Stopped ***** \n")
            webhookmgr.run_command_webhooks(
                command,
                webhookmgr.payload_formatter(
                    200, {}, {"code": "CWEB_STOP"},
                    {"info": "Crafty is shutting down"}))
            os._exit(0)

        srv_obj = multi.get_server_obj(server_id)
        running = srv_obj.check_running()
        server_name = srv_obj.get_mc_server_name()

        if command == 'restart_web_server':
            self.tornado_obj.stop_web_server()
            time.sleep(1)
            self.tornado_obj.start_web_server(True)
            webhookmgr.run_command_webhooks(
                command,
                webhookmgr.payload_formatter(
                    200, {}, {"code": "WEBSRV_RESTART"},
                    {"info": "Crafty Web Interface action has completed"}))
            self.clear_all_commands()

        elif command == "reload_mc_settings":
            any_srv_obj = multi.get_first_server_object()
            any_srv_obj.reload_settings()

        elif command == 'restart_mc_server':
            if running:
                try:
                    logger.info("Stopping MC Server")
                    srv_obj.stop_threaded_server()

                except:
                    logger.exception("Unable to stop server %s. Traceback: ",
                                     server_name)
                    webhookmgr.run_command_webhooks(
                        command,
                        webhookmgr.payload_formatter(500, {
                            "error": "TRACEBACK"
                        }, {
                            "server": {
                                "id": server_id,
                                "name": server_name,
                                "running": running
                            }
                        }, {
                            "info":
                            "A Traceback occured while restarting the MC server"
                        }))

                while True:
                    server_up = srv_obj.is_server_pingable()
                    if server_up:
                        logger.info("%s still pingable, waiting...",
                                    server_name)
                        time.sleep(.5)
                    else:
                        logger.info("Server %s has stopped", server_name)
                        break

                srv_obj.run_threaded_server()
            else:
                logger.info("%s not running, starting it now", server_name)
                srv_obj.run_threaded_server()
                webhookmgr.run_command_webhooks(
                    command,
                    webhookmgr.payload_formatter(
                        200, {}, {
                            "code": "SER_RESTART_DONE",
                            "server": {
                                "id": server_id,
                                "name": server_name,
                                "running": running
                            }
                        }, {"info": "Server restart action has completed"}))

        elif command == 'start_mc_server':
            srv_obj.run_threaded_server()
            time.sleep(2)
            multi.do_stats_for_servers()
            webhookmgr.run_command_webhooks(
                command,
                webhookmgr.payload_formatter(
                    200, {}, {
                        "code": "SER_START_DONE",
                        "server": {
                            "id": server_id,
                            "name": server_name,
                            "running": running
                        }
                    }, {"info": "Server start action has completed"}))

        elif command == 'stop_mc_server':
            if running:
                logger.info("Stopping MC server %s", server_name)
                srv_obj.stop_threaded_server()
                time.sleep(2)
                multi.do_stats_for_servers()
                webhookmgr.run_command_webhooks(
                    command,
                    webhookmgr.payload_formatter(
                        200, {}, {
                            "code": "SER_STOP_DONE",
                            "server": {
                                "id": server_id,
                                "name": server_name,
                                "running": running
                            }
                        }, {"info": "Server stop action has completed"}))
            else:
                logger.info("Stop halted! Server %s is not running!",
                            server_name)
                webhookmgr.run_command_webhooks(
                    command,
                    webhookmgr.payload_formatter(
                        500, {"error": "SER_NOT_RUNNING"}, {
                            "server": {
                                "id": server_id,
                                "name": server_name,
                                "running": running
                            }
                        }, {"info": "Server is not running"}))

        elif command == 'update_server_jar':
            srv_obj.update_server_jar(False)

        elif command == 'revert_server_jar':
            srv_obj.revert_updated_server_jar(False)

        elif command == 'update_server_jar_console':
            srv_obj.update_server_jar(True)

        elif command == 'revert_server_jar_console':
            srv_obj.revert_updated_server_jar(True)

        elif command == "exit_crafty":
            logger.info("Sending Stop Command To Crafty")

            # stop the ftp server...
            if ftp_svr_object.check_running():
                ftp_svr_object.stop_threaded_ftp_server()

            # kill all mc servers gracefully
            multi.stop_all_servers()

            logger.info("***** Crafty Stopped ***** \n")
            webhookmgr.run_command_webhooks(
                command,
                webhookmgr.payload_formatter(
                    200, {}, {"code": "CWEB_STOP"},
                    {"info": "Crafty is shutting down"}))
            os._exit(0)

        elif command == 'start_ftp':
            settings = MC_settings.get_by_id(server_id)

            if ftp_svr_object.check_running():
                logger.warning(
                    "The FTP server is already running - please stop it before starting again"
                )
                webhookmgr.run_command_webhooks(
                    command,
                    webhookmgr.payload_formatter(
                        500, {"error": "FTP_RUNNING"}, {},
                        {"info": "FTP is already running"}))
                return False

            if helper.check_directory_exist(settings.server_path):
                logger.info("Setting FTP root path to {}".format(
                    settings.server_path))
                ftp_svr_object.set_root_dir(settings.server_path)
            else:
                logger.error("Path: {} not found!".format(
                    settings.server_path))
                webhookmgr.run_command_webhooks(
                    command,
                    webhookmgr.payload_formatter(
                        200, {"error": "PATH_NONEXISTANT"},
                        {"path": settings.server_path},
                        {"info": "Home path for FTP server not found"}))
                return False

            logger.info("Starting FTP Server")
            ftp_svr_object.run_threaded_ftp_server(server_id)
            webhookmgr.run_command_webhooks(
                command,
                webhookmgr.payload_formatter(
                    200, {}, {}, {"info": "FTP server successfully started"}))

        elif command == 'stop_ftp':
            ftp_svr_object.stop_threaded_ftp_server()
            webhookmgr.run_command_webhooks(
                command,
                webhookmgr.payload_formatter(
                    200, {}, {}, {"info": "FTP server successfully stopped"}))

        elif command == 'destroy_world':
            logger.info("Destroying World for Server: {} - {}".format(
                server_id, server_name))
            srv_obj.destroy_world()
Exemple #12
0
    def get(self, page):

        name = tornado.escape.json_decode(self.current_user)
        user_data = get_perms_for_user(name)

        context = {
            'user_data':
            user_data,
            'version_data':
            helper.get_version(),
            'servers_defined':
            multi.list_servers(),
            'managed_server':
            self.session.get_data(self.current_user, 'managed_server'),
            'servers_running':
            multi.list_running_servers(),
            'mc_servers_data':
            multi.get_stats_for_servers()
        }

        if page == 'unauthorized':
            template = "admin/denied.html"

        elif page == "reload_web":
            template = "admin/reload_web_settings.html"

            web_data = Webserver.get()
            context['user_data'] = user_data
            context['web_settings'] = model_to_dict(web_data)

            self.render(template, data=context)
            # reload web server
            Remote.insert({
                Remote.command: 'restart_web_server',
                Remote.server_id:
                1,  # this doesn't really matter as we are not tying to a server
                Remote.command_source: 'local'
            }).execute()

        elif page == 'reload_mc_settings':
            Remote.insert({
                Remote.command: 'reload_mc_settings',
                Remote.server_id:
                1,  # this doesn't really matter as we are not tying to a server
                Remote.command_source: 'local'
            }).execute()

            self.redirect("/admin/config")

        elif page == 'dashboard':
            errors = bleach.clean(self.get_argument('errors', ''))
            context['errors'] = errors
            context['host_stats'] = multi.get_host_status()

            template = "admin/dashboard.html"

        elif page == 'change_password':
            template = "admin/change_pass.html"

        elif page == 'virtual_console':
            if not check_role_permission(user_data['username'], 'svr_console'):
                self.redirect('/admin/unauthorized')

            context['server_id'] = bleach.clean(self.get_argument('id', ''))

            mc_data = MC_settings.get_by_id(context['server_id'])

            context['server_name'] = mc_data.server_name

            template = "admin/virt_console.html"

        elif page == "backups":
            if not check_role_permission(user_data['username'], 'backups'):
                self.redirect('/admin/unauthorized')

            server_id = bleach.clean(self.get_argument('id', ''))
            mc_data = MC_settings.get_by_id(server_id)

            template = "admin/backups.html"

            backup_data = Backups.get_by_id(server_id)

            backup_data = model_to_dict(backup_data)

            backup_path = backup_data['storage_location']
            backup_dirs = json.loads(backup_data['directories'])

            context['backup_data'] = json.loads(backup_data['directories'])
            context['backup_config'] = backup_data

            # get a listing of directories in the server path.
            context['directories'] = helper.scan_dirs_in_path(
                mc_data.server_path)

            context['server_root'] = mc_data.server_path

            context['server_name'] = mc_data.server_name
            context['server_id'] = mc_data.id
            context['backup_paths'] = backup_dirs
            context['backup_path'] = backup_path
            context['current_backups'] = backupmgr.list_backups_for_server(
                server_id)

            context['saved'] = False
            context['invalid'] = False

        elif page == "all_backups":
            if not check_role_permission(user_data['username'], 'backups'):
                self.redirect('/admin/unauthorized')

            template = "admin/backups.html"
            # END

            backup_list = Backups.get()
            backup_data = model_to_dict(backup_list)
            backup_path = backup_data['storage_location']
            backup_dirs = json.loads(backup_data['directories'])

            context['backup_paths'] = backup_dirs
            context['backup_path'] = backup_path
            context['current_backups'] = backupmgr.list_all_backups()
            context['server_name'] = "All Servers"

        elif page == "schedules":
            if not check_role_permission(user_data['username'], 'schedules'):
                self.redirect('/admin/unauthorized')

            saved = bleach.clean(self.get_argument('saved', ''))
            server_id = int(bleach.clean(self.get_argument('id', 1)))

            db_data = Schedules.select().where(
                Schedules.server_id == server_id)

            template = "admin/schedules.html"
            context['db_data'] = db_data
            context['saved'] = saved
            context['server_id'] = server_id

        elif page == "schedule_disable":
            if not check_role_permission(user_data['username'], 'schedules'):
                self.redirect('/admin/unauthorized')

            schedule_id = self.get_argument('taskid', 1)
            server_id = self.get_argument('id', 1)

            q = Schedules.update(enabled=0).where(Schedules.id == schedule_id)
            q.execute()

            self._reload_schedules()

            self.redirect("/admin/schedules?id={}".format(server_id))

        elif page == "schedule_enable":
            if not check_role_permission(user_data['username'], 'schedules'):
                self.redirect('/admin/unauthorized')

            schedule_id = self.get_argument('taskid', 1)
            server_id = self.get_argument('id', 1)

            q = Schedules.update(enabled=1).where(Schedules.id == schedule_id)
            q.execute()

            self._reload_schedules()

            self.redirect("/admin/schedules?id={}".format(server_id))

        elif page == 'config':
            if not check_role_permission(user_data['username'], 'config'):
                self.redirect('/admin/unauthorized')

            saved = bleach.clean(self.get_argument('saved', ''))
            invalid = bleach.clean(self.get_argument('invalid', ''))

            template = "admin/config.html"
            crafty_data = Crafty_settings.get()
            # ftp_data = Ftp_Srv.get()
            web_data = Webserver.get()
            users = Users.select()
            roles = Roles.select()

            # context['ftp_user'] = ftp_data.user
            # context['ftp_pass'] = ftp_data.password
            # context['ftp_port'] = ftp_data.port

            context['saved'] = saved
            context['invalid'] = invalid

            context['crafty_settings'] = model_to_dict(crafty_data)
            context['web_settings'] = model_to_dict(web_data)

            context['users'] = users
            context['users_count'] = len(users)
            context['roles'] = roles

        elif page == 'server_config':
            if not check_role_permission(user_data['username'], 'config'):
                self.redirect('/admin/unauthorized')

            saved = bleach.clean(self.get_argument('saved', ''))
            invalid = bleach.clean(self.get_argument('invalid', ''))
            server_id = bleach.clean(self.get_argument('id', 1))
            errors = bleach.clean(self.get_argument('errors', ''))

            context['errors'] = errors

            if server_id is None:
                self.redirect("/admin/dashboard")

            template = "admin/server_config.html"

            mc_data = MC_settings.get_by_id(server_id)

            page_data = {}
            context['saved'] = saved
            context['invalid'] = invalid
            context['mc_settings'] = model_to_dict(mc_data)

            context['server_root'] = context['mc_settings']['server_path']

            srv_obj = multi.get_server_obj(server_id)
            context['server_running'] = srv_obj.check_running()

            host_data = Host_Stats.get()
            context['max_memory'] = host_data.mem_total

        elif page == 'downloadbackup':
            if not check_role_permission(user_data['username'], 'backups'):
                self.redirect('/admin/unauthorized')

            path = bleach.clean(self.get_argument("file", None, True))
            server_id = bleach.clean(self.get_argument("id", None, True))

            # only allow zip files
            if path[-3:] != "zip":
                self.redirect("/admin/backups?id={}".format(server_id))

            backup_folder = backupmgr.get_backup_folder_for_server(server_id)

            # Grab our backup path from the DB
            backup_list = Backups.get(Backups.server_id == int(server_id))
            base_folder = backup_list.storage_location

            # get full path of our backups
            server_backup_folder = os.path.join(base_folder, backup_folder)
            server_backup_file = os.path.join(server_backup_folder, path)

            # get list of zip files in the backup directory
            files = [f for f in glob.glob(server_backup_folder + "**/*.zip")]

            # for each file, see if it matches the file we are trying to download
            for f in files:

                # if we find a match
                if f == server_backup_file and helper.check_file_exists(
                        server_backup_file):

                    file_name = os.path.basename(server_backup_file)
                    self.set_header('Content-Type', 'application/octet-stream')
                    self.set_header('Content-Disposition',
                                    'attachment; filename=' + file_name)

                    with open(server_backup_file, 'rb') as f:
                        while 1:
                            data = f.read(
                                16384)  # or some other nice-sized chunk
                            if not data:
                                break
                            self.write(data)
                    self.finish()

            self.redirect("/admin/backups?id={}".format(server_id))

        elif page == "server_control":
            if not check_role_permission(user_data['username'], 'svr_control'):
                self.redirect('/admin/unauthorized')

            server_id = bleach.clean(self.get_argument('id', 1))

            if server_id is None:
                self.redirect("/admin/dashboard")

            template = "admin/server_control.html"
            logfile = helper.get_crafty_log_file()

            mc_data = MC_settings.get_by_id(server_id)

            srv_obj = multi.get_server_obj(server_id)
            context['server_running'] = srv_obj.check_running()
            context['mc_settings'] = model_to_dict(mc_data)
            context['server_updating'] = self.mcserver.check_updating()
            context['players'] = context['mc_servers_data'][int(
                server_id)]['players'].split(',')
            context['players_online'] = context['mc_servers_data'][int(
                server_id)]['online_players']
            context['world_info'] = srv_obj.get_world_info()

        elif page == 'commands':
            if not check_role_permission(user_data['username'], 'svr_console'):
                self.redirect('/admin/unauthorized')

            command = bleach.clean(self.get_argument("command", None, True))
            id = self.get_argument("id", None, True)

            # grab any defined server object and reload the settings
            any_serv_obj = multi.get_first_server_object()
            any_serv_obj.reload_settings()

            if command == "server_stop":
                Remote.insert({
                    Remote.command: 'stop_mc_server',
                    Remote.server_id: id,
                    Remote.command_source: "localhost"
                }).execute()
                next_page = "/admin/virtual_console?id={}".format(id)

            elif command == "server_start":
                Remote.insert({
                    Remote.command: 'start_mc_server',
                    Remote.server_id: id,
                    Remote.command_source: "localhost"
                }).execute()
                next_page = "/admin/virtual_console?id={}".format(id)

            elif command == "server_restart":
                Remote.insert({
                    Remote.command: 'restart_mc_server',
                    Remote.server_id: id,
                    Remote.command_source: "localhost"
                }).execute()
                next_page = "/admin/virtual_console?id={}".format(id)

            elif command == "ftp_server_start":
                Remote.insert({
                    Remote.command: 'start_ftp',
                    Remote.server_id: id,
                    Remote.command_source: 'localhost'
                }).execute()
                time.sleep(2)
                next_page = "/admin/files?id={}".format(id)

            elif command == 'ftp_server_stop':
                Remote.insert({
                    Remote.command: 'stop_ftp',
                    Remote.server_id: id,
                    Remote.command_source: 'localhost'
                }).execute()
                time.sleep(2)
                next_page = "/admin/files?id={}".format(id)

            elif command == "backup":
                backupmgr.backup_server(id)
                time.sleep(4)
                next_page = '/admin/backups?id={}'.format(id)

            elif command == "backup_all":
                backupmgr.backup_all_servers()
                time.sleep(4)
                next_page = '/admin/backups'

            elif command == 'update_jar':
                Remote.insert({
                    Remote.command: 'update_server_jar',
                    Remote.server_id: id,
                    Remote.command_source: 'localhost'
                }).execute()
                time.sleep(2)
                next_page = "/admin/server_control?id={}".format(id)

            elif command == 'revert_jar':
                Remote.insert({
                    Remote.command: 'revert_server_jar',
                    Remote.server_id: id,
                    Remote.command_source: 'localhost'
                }).execute()
                time.sleep(2)
                next_page = "/admin/server_control?id={}".format(id)

            elif command == 'destroy_world':
                Remote.insert({
                    Remote.command: 'destroy_world',
                    Remote.server_id: id,
                    Remote.command_source: "localhost"
                }).execute()
                next_page = "/admin/virtual_console?id={}".format(id)

            self.redirect(next_page)

        elif page == 'get_logs':
            if not check_role_permission(user_data['username'], 'logs'):
                self.redirect('/admin/unauthorized')

            server_id = bleach.clean(self.get_argument('id', None))
            mc_data = MC_settings.get_by_id(server_id)

            context['server_name'] = mc_data.server_name
            context['server_id'] = server_id

            srv_object = multi.get_server_obj(server_id)

            data = []

            server_log = os.path.join(mc_data.server_path, 'logs',
                                      'latest.log')

            if server_log is not None:
                data = helper.tail_file(server_log, 500)
                data.insert(0,
                            "Lines trimmed to ~500 lines for speed sake \n ")
            else:
                data.insert(
                    0, "Unable to find {} \n ".format(
                        os.path.join(mc_data.server_path, 'logs',
                                     'latest.log')))

            crafty_data = helper.tail_file(helper.crafty_log_file, 100)
            crafty_data.insert(
                0, "Lines trimmed to ~100 lines for speed sake \n ")

            scheduler_data = helper.tail_file(
                os.path.join(helper.logs_dir, 'schedule.log'), 100)
            scheduler_data.insert(
                0, "Lines trimmed to ~100 lines for speed sake \n ")

            access_data = helper.tail_file(
                os.path.join(helper.logs_dir, 'tornado-access.log'), 100)
            access_data.insert(
                0, "Lines trimmed to ~100 lines for speed sake \n ")

            ftp_data = helper.tail_file(
                os.path.join(helper.logs_dir, 'ftp.log'), 100)
            ftp_data.insert(0,
                            "Lines trimmed to ~100 lines for speed sake \n ")

            errors = srv_object.search_for_errors()
            template = "admin/logs.html"

            context['log_data'] = data
            context['errors'] = errors
            context['crafty_log'] = crafty_data
            context['scheduler'] = scheduler_data
            context['access'] = access_data
            context['ftp'] = ftp_data

        elif page == "files":
            if not check_role_permission(user_data['username'], 'files'):
                self.redirect('/admin/unauthorized')

            template = "admin/files.html"

            server_id = bleach.clean(self.get_argument('id', 1))
            context['server_id'] = server_id

            srv_object = multi.get_server_obj(server_id)
            context['pwd'] = srv_object.server_path

            context['listing'] = helper.scan_dirs_in_path(context['pwd'])
            context['parent'] = None

            context['ext_list'] = [
                ".txt", ".yml", "ties", "json", '.conf', 'cfg'
            ]

        else:
            # 404
            template = "public/404.html"
            context = {}

        self.render(template, data=context)
Exemple #13
0
    def get(self, page):

        if page == 'server_log':
            server_id = bleach.clean(self.get_argument('id'))

            if server_id is None:
                logger.warning("Server ID not found in server_log ajax call")
                return False

            server_path = multi.get_server_root_path(server_id)

            server_log = os.path.join(server_path, 'logs', 'latest.log')
            data = helper.tail_file(server_log, 40)

            for d in data:
                self.write(d.encode("utf-8"))

        elif page == 'history':
            server_id = bleach.clean(self.get_argument("server_id", ''))

            db_data = History.select().where(History.server_id == server_id)
            return_data = []
            for d in db_data:
                row_data = {
                    'time': d.time.strftime("%m/%d/%Y %H:%M:%S"),
                    'cpu': d.cpu,
                    'mem': d.memory,
                    'players': d.players
                }
                return_data.append(row_data)

            self.write(json.dumps(return_data))

        elif page == 'update_check':

            context = {
                'master': helper.check_version('master'),
                'beta': helper.check_version('beta'),
                'snaps': helper.check_version('snapshot'),
                'current': helper.get_version()
            }

            self.render('ajax/version.html', data=context)

        elif page == 'host_cpu_infos':

            name = tornado.escape.json_decode(self.current_user)
            user_data = get_perms_for_user(name)

            context = {'host_stats': multi.get_host_status()}

            self.render('ajax/host_cpu_infos.html', data=context)

        elif page == 'host_ram_infos':

            name = tornado.escape.json_decode(self.current_user)
            user_data = get_perms_for_user(name)

            context = {'host_stats': multi.get_host_status()}

            self.render('ajax/host_ram_infos.html', data=context)

        elif page == 'host_disk_infos':

            name = tornado.escape.json_decode(self.current_user)
            user_data = get_perms_for_user(name)

            context = {'host_stats': multi.get_host_status()}

            self.render('ajax/host_disk_infos.html', data=context)

        elif page == 'host_running_servers':

            name = tornado.escape.json_decode(self.current_user)
            user_data = get_perms_for_user(name)

            context = {
                'servers_running': multi.list_running_servers(),
                'servers_defined': multi.list_servers(),
            }

            self.render('ajax/host_running_servers.html', data=context)

        elif page == 'server_status':

            name = tornado.escape.json_decode(self.current_user)
            user_data = get_perms_for_user(name)

            context = {
                'user_data': user_data,
                'mc_servers_data': multi.get_stats_for_servers()
            }

            server_id = bleach.clean(self.get_argument('id'))
            srv_obj = multi.get_server_obj(server_id)

            context['srv'] = {
                'id': srv_obj.server_id,
                'name': srv_obj.get_mc_server_name(),
                'running': srv_obj.check_running(),
                'crashed': srv_obj.check_crashed(),
                'auto_start': srv_obj.settings.auto_start_server
            }

            self.render('ajax/server_status.html', data=context)

        elif page == 'server_infos':

            name = tornado.escape.json_decode(self.current_user)
            user_data = get_perms_for_user(name)

            context = {
                'user_data': user_data,
                'mc_servers_data': multi.get_stats_for_servers()
            }

            server_id = bleach.clean(self.get_argument('id', 1))
            srv_obj = multi.get_server_obj(server_id)

            context['srv'] = {
                'id': srv_obj.server_id,
                'name': srv_obj.get_mc_server_name(),
                'running': srv_obj.check_running(),
                'crashed': srv_obj.check_crashed(),
                'auto_start': srv_obj.settings.auto_start_server
            }

            self.render('ajax/server_infos.html', data=context)

        elif page == 'get_file':
            file_path = bleach.clean(self.get_argument('file_name'))
            server_id = bleach.clean(self.get_argument('server_id'))

            mc_data = MC_settings.get_by_id(server_id)
            mc_settings = model_to_dict(mc_data)

            mc_settings['server_path'] = str(
                mc_settings['server_path']).replace("\\", '/')

            # let's remove the server directory from the path...
            asked_for_path = file_path.replace(mc_settings['server_path'], '')
            built_path = mc_settings['server_path'] + asked_for_path

            # if the server directory plus the path asked for doesn't exits...
            # this must be an attempt to do path traversal...so we bomb out.
            if not helper.check_file_exists(built_path):
                raise Exception(
                    "possible file traversal detected {}".format(file_path))

            else:
                f = open(file_path, "r")
                file_data = f.read()
                context = {
                    "file_data": file_data,
                    "file_path": file_path,
                    "server_id": server_id
                }

                self.render('ajax/edit_file.html', data=context)
Exemple #14
0
    def post(self, page):

        name = tornado.escape.json_decode(self.current_user)
        user_data = get_perms_for_user(name)

        if page == "send_command":
            command = bleach.clean(
                self.get_body_argument('command', default=None, strip=True))
            server_id = bleach.clean(self.get_argument('id'))

            if server_id is None:
                logger.warning("Server ID not found in send_command ajax call")

            srv_obj = multi.get_server_obj(server_id)

            if command:
                if srv_obj.check_running():
                    srv_obj.send_command(command)

        elif page == 'del_file':
            file_to_del = bleach.clean(
                self.get_body_argument('file_name', default=None, strip=True))
            server_id = bleach.clean(
                self.get_argument('server_id', default=None, strip=True))

            # let's make sure this path is in the backup directory and not somewhere else
            # we don't want someone passing a path like /etc/passwd in the raw, so we are only passing the filename
            # to this function, and then tacking on the storage location in front of the filename.

            backup_folder = backupmgr.get_backup_folder_for_server(server_id)

            # Grab our backup path from the DB
            backup_list = Backups.get(Backups.server_id == int(server_id))
            server_backup_file = os.path.join(backup_list.storage_location,
                                              backup_folder, file_to_del)

            if server_backup_file and helper.check_file_exists(
                    server_backup_file):
                helper.del_file(server_backup_file)

        elif page == 'del_schedule':
            id_to_del = bleach.clean(
                self.get_body_argument('id', default=None, strip=True))

            if id_to_del:
                logger.info("Got command to del schedule {}".format(id_to_del))
                q = Schedules.delete().where(Schedules.id == id_to_del)
                q.execute()

            multi.reload_user_schedules()

        elif page == 'search_logs':
            search_string = bleach.clean(
                self.get_body_argument('search', default=None, strip=True))
            server_id = bleach.clean(
                self.get_body_argument('id', default=None, strip=True))

            data = MC_settings.get_by_id(server_id)
            logfile = os.path.join(data.server_path, 'logs', 'latest.log')
            data = helper.search_file(logfile, search_string)
            if data:
                temp_data = ""
                for d in data:
                    line = "Line Number: {} {}".format(d[0], d[1])
                    temp_data = "{}\n{}".format(temp_data, line)
                return_data = temp_data

            else:
                return_data = "Unable to find your string: {}".format(
                    search_string)
            self.write(return_data)

        elif page == 'add_user':
            if not user_data['config']:
                logger.warning(
                    "User: {} with Role: {} Attempted Access to: {} and was denied"
                    .format(user_data['username'], user_data['role_name'],
                            "Add User"))
                self.redirect('/admin/unauthorized')

            new_username = bleach.clean(
                self.get_argument("username", None, True))

            if new_username:
                new_pass = helper.random_string_generator()
                api_token = helper.random_string_generator(32)

                result = Users.insert({
                    Users.username:
                    new_username,
                    Users.role:
                    'Mod',
                    Users.api_token:
                    api_token,
                    Users.password:
                    helper.encode_pass(new_pass)
                }).execute()

                self.write(new_pass)

        elif page == "edit_user_role":
            if not user_data['config']:
                logger.warning(
                    "User: {} with Role: {} Attempted Access to: {} and was denied"
                    .format(user_data['username'], user_data['role_name'],
                            "Delete User"))
                self.redirect('/admin/unauthorized')

            username = bleach.clean(self.get_argument("username", None, True))
            role = bleach.clean(self.get_argument("role", None, True))

            if username == 'Admin':
                self.write("Not Allowed")
            else:
                if username and role:
                    Users.update({
                        Users.role: role
                    }).where(Users.username == username).execute()

                    self.write('updated')

        elif page == "change_password":
            if not user_data['config']:
                logger.warning(
                    "User: {} with Role: {} Attempted Access to: {} and was denied"
                    .format(user_data['username'], user_data['role_name'],
                            "Delete User"))
                self.redirect('/admin/unauthorized')

            username = bleach.clean(self.get_argument("username", None, True))
            newpassword = bleach.clean(
                self.get_argument("password", None, True))

            if username and newpassword:
                Users.update({
                    Users.password: helper.encode_pass(newpassword)
                }).where(Users.username == username).execute()

            self.write(newpassword)

        elif page == 'del_user':
            if not user_data['config']:
                logger.warning(
                    "User: {} with Role: {} Attempted Access to: {} and was denied"
                    .format(user_data['username'], user_data['role_name'],
                            "Delete User"))
                self.redirect('/admin/unauthorized')

            username = bleach.clean(self.get_argument("username", None, True))

            if username == 'Admin':
                self.write("Not Allowed")
            else:
                if username:
                    Users.delete().where(Users.username == username).execute()
                    self.write("{} deleted".format(username))

        elif page == 'add_role':
            if not user_data['config']:
                logger.warning(
                    "User: {} with Role: {} Attempted Access to: {} and was denied"
                    .format(user_data['username'], user_data['role_name'],
                            "Add Role"))
                self.redirect('/admin/unauthorized')

            new_rolename = bleach.clean(
                self.get_argument("rolename", None, True))

            if new_rolename:

                result = Roles.insert({
                    Roles.name: new_rolename,
                    Roles.svr_control: False,
                    Roles.svr_console: False,
                    Roles.logs: False,
                    Roles.backups: False,
                    Roles.schedules: False,
                    Roles.config: False,
                    Roles.files: False,
                    Roles.api_access: False,
                }).execute()

                self.write("{}".format(new_rolename))

        elif page == 'edit_role':
            if not user_data['config']:
                logger.warning(
                    "User: {} with Role: {} Attempted Access to: {} and was denied"
                    .format(user_data['username'], user_data['role_name'],
                            "Add Role"))
                self.redirect('/admin/unauthorized')

            rolename = bleach.clean(self.get_argument("rolename", None, True))

            new_svr_control = 'True' == bleach.clean(
                self.get_argument("svr_control", False, True))
            new_svr_console = 'True' == bleach.clean(
                self.get_argument("svr_console", False, True))
            new_logs = 'True' == bleach.clean(
                self.get_argument("logs", False, True))
            new_backups = 'True' == bleach.clean(
                self.get_argument("backups", False, True))
            new_schedules = 'True' == bleach.clean(
                self.get_argument("schedules", False, True))
            new_config = 'True' == bleach.clean(
                self.get_argument("config", False, True))
            new_files = 'True' == bleach.clean(
                self.get_argument("files", False, True))
            new_api_access = 'True' == bleach.clean(
                self.get_argument("api_access", False, True))

            if rolename:
                result = Roles.update({
                    Roles.svr_control: new_svr_control,
                    Roles.svr_console: new_svr_console,
                    Roles.logs: new_logs,
                    Roles.backups: new_backups,
                    Roles.schedules: new_schedules,
                    Roles.config: new_config,
                    Roles.files: new_files,
                    Roles.api_access: new_api_access,
                }).where(Roles.name == rolename).execute()

                self.write("{} edited".format(rolename))

        elif page == 'del_role':
            if not user_data['config']:
                logger.warning(
                    "User: {} with Role: {} Attempted Access to: {} and was denied"
                    .format(user_data['username'], user_data['role_name'],
                            "Delete Role"))
                self.redirect('/admin/unauthorized')

            rolename = bleach.clean(self.get_argument("rolename", None, True))

            if rolename == 'Admin':
                self.write("Not Allowed")
            else:
                if rolename:
                    Roles.delete().where(Roles.name == rolename).execute()
                    self.write("{} deleted".format(rolename))

        elif page == 'save_file':
            file_data = self.get_argument('file_contents')
            file_path = bleach.clean(self.get_argument("file_path"))
            server_id = bleach.clean(self.get_argument("server_id"))

            mc_data = MC_settings.get_by_id(server_id)
            mc_settings = model_to_dict(mc_data)

            mc_settings['server_path'] = str(
                mc_settings['server_path']).replace("\\", '/')

            # let's remove the server directory from the path...
            asked_for_path = file_path.replace(mc_settings['server_path'], '')
            built_path = mc_settings['server_path'] + asked_for_path

            # if the server directory plus the path asked for doesn't exits...
            # this must be an attempt to do path traversal...so we bomb out.
            if not helper.check_file_exists(built_path):
                raise Exception(
                    "possible file traversal detected {}".format(file_path))

            try:
                file = open(file_path, 'w')
                file.write(file_data)
                file.close()
                logger.info("File {} saved with new content".format(file_path))
            except Exception as e:
                logger.error("Unable to save {} due to {} error".format(
                    file_path, e))
            self.redirect("/admin/files?id={}".format(server_id))

        elif page == "del_server_file":
            file_path = bleach.clean(self.get_argument("file_name"))
            server_id = bleach.clean(self.get_argument("server_id"))

            mc_data = MC_settings.get_by_id(server_id)
            mc_settings = model_to_dict(mc_data)

            mc_settings['server_path'] = str(
                mc_settings['server_path']).replace("\\", '/')

            # let's remove the server directory from the path...
            asked_for_path = file_path.replace(mc_settings['server_path'], '')
            built_path = mc_settings['server_path'] + asked_for_path

            if helper.check_directory_exist(built_path):
                try:
                    shutil.rmtree(built_path)
                    logger.info("Deleting {}".format(built_path))
                except Exception as e:
                    logger.error("Unable to delete {} due to {} error".format(
                        file_path, e))

            if helper.check_file_exists(built_path):
                try:
                    os.remove(file_path)
                    logger.info("File {} deleted".format(file_path))
                except Exception as e:
                    logger.error("Unable to delete {} due to {} error".format(
                        file_path, e))

            self.redirect("/admin/files?id={}".format(server_id))

        elif page == "new_file_folder":
            type = bleach.clean(self.get_argument("type"))
            server_id = bleach.clean(self.get_argument("server_id"))
            pwd = bleach.clean(self.get_argument("pwd"))
            name = bleach.clean(self.get_argument("name"))

            mc_data = MC_settings.get_by_id(server_id)
            mc_settings = model_to_dict(mc_data)

            mc_settings['server_path'] = str(
                mc_settings['server_path']).replace("\\", '/')

            # let's remove the server directory from the path...
            asked_for_path = pwd.replace(mc_settings['server_path'], '')
            built_path = mc_settings['server_path'] + asked_for_path

            path = os.path.join(pwd, name)

            if type == "folder":
                logger.info("Creating folder at {}".format(path))
                try:
                    os.mkdir(path)
                except Exception as e:
                    logger.error(
                        "Unable to create folder at {} due to {}".format(
                            path, e))
            else:
                logger.info("Creating File at {}".format(path))

                try:
                    with open(path, "w") as fobject:
                        fobject.close()
                except Exception as e:
                    logger.error(
                        "Unable to create file at {} due to {}".format(
                            path, e))

        elif page == "unzip_server_file":
            file_path = bleach.clean(self.get_argument("file_name"))
            server_id = bleach.clean(self.get_argument("server_id"))
            pwd = bleach.clean(self.get_argument("pwd"))

            mc_data = MC_settings.get_by_id(server_id)
            mc_settings = model_to_dict(mc_data)

            mc_settings['server_path'] = str(
                mc_settings['server_path']).replace("\\", '/')

            # let's remove the server directory from the path...
            asked_for_path = file_path.replace(mc_settings['server_path'], '')
            built_path = mc_settings['server_path'] + asked_for_path

            # if the server directory plus the path asked for doesn't exits...
            # this must be an attempt to do path traversal...so we bomb out.
            if not helper.check_file_exists(built_path):
                raise Exception(
                    "possible file traversal detected {}".format(file_path))

            try:
                with ZipFile(file_path, "r") as zipObj:
                    logger.info("Exctracting file: {} to dir {}".format(
                        file_path, pwd))
                    zipObj.extractall(pwd)

            except Exception as e:
                logger.error("Unable to extract: {} due to error: {}".format(
                    file_path, e))

            self.redirect("/admin/files?id={}".format(server_id))

        elif page == "destroy_server":
            server_id = bleach.clean(
                self.get_body_argument('server_id', default=None, strip=True))

            if server_id is not None:

                # stop any server stats going on...
                schedule.clear('server_stats')

                # remove it from multi
                multi.remove_server_object(server_id)

                # reschedule the things
                multi.reload_scheduling()

                self.write("Success")