def modules(): ''' Return a list of module names available for MultiScanner to use, and whether or not they are enabled in the config. ''' files = multiscanner.parseDir(multiscanner.MODULEDIR, True) filenames = [os.path.splitext(os.path.basename(f)) for f in files] module_names = [m[0] for m in filenames if m[1] == '.py'] ms_config = configparser.SafeConfigParser() ms_config.optionxform = str ms_config.read(multiscanner.CONFIG) modules = {} for module in module_names: try: modules[module] = ms_config.get(module, 'ENABLED') except (configparser.NoSectionError, configparser.NoOptionError): pass return jsonify({'Modules': modules})
def create_task(): ''' Create a new task for a submitted file. Save the submitted file to UPLOAD_FOLDER, optionally unzipping it. Return task id and 201 status. ''' file_ = request.files['file'] if request.form.get('upload_type', None) == 'import': try: task_id = import_task(file_) except KeyError: return make_response( jsonify({'Message': 'Cannot import report missing \'Scan Time\' field!'}), HTTP_BAD_REQUEST) except InvalidScanTimeFormatError: return make_response( jsonify({'Message': 'Cannot import report with \'Scan Time\' of invalid format!'}), HTTP_BAD_REQUEST) except (UnicodeDecodeError, ValueError): return make_response( jsonify({'Message': 'Cannot import non-JSON files!'}), HTTP_BAD_REQUEST) return make_response( jsonify({'Message': {'task_ids': [task_id]}}), HTTP_CREATED ) original_filename = file_.filename metadata = {} task_id_list = [] extract_dir = None rescan = False for key in request.form.keys(): if key in ['file_id', 'archive-password', 'upload_type'] or request.form[key] == '': continue elif key == 'duplicate': if request.form[key] == 'latest': rescan = False elif request.form[key] == 'rescan': rescan = True elif key == 'modules': module_names = request.form[key] files = multiscanner.parseDir(multiscanner.MODULEDIR, True) modules = [] for f in files: split = os.path.splitext(os.path.basename(f)) if split[0] in module_names and split[1] == '.py': modules.append(f) elif key == 'archive-analyze' and request.form[key] == 'true': extract_dir = api_config['api']['upload_folder'] if not os.path.isdir(extract_dir): return make_response( jsonify({'Message': "'upload_folder' in API config is not " "a valid folder!"}), HTTP_BAD_REQUEST) # Get password if present if 'archive-password' in request.form: password = request.form['archive-password'] if PY3: password = bytes(password, 'utf-8') else: password = '' else: metadata[key] = request.form[key] if extract_dir: # Extract a zip if zipfile.is_zipfile(file_): z = zipfile.ZipFile(file_) try: # NOTE: zipfile module prior to Py 2.7.4 is insecure! # https://docs.python.org/2/library/zipfile.html#zipfile.ZipFile.extract z.extractall(path=extract_dir, pwd=password) for uzfile in z.namelist(): unzipped_file = open(os.path.join(extract_dir, uzfile)) f_name, full_path = save_hashed_filename(unzipped_file, True) tid = queue_task(uzfile, f_name, full_path, metadata, rescan=rescan) task_id_list.append(tid) except RuntimeError as e: msg = "ERROR: Failed to extract " + str(file_) + ' - ' + str(e) return make_response( jsonify({'Message': msg}), HTTP_BAD_REQUEST) # Extract a rar elif rarfile.is_rarfile(file_): r = rarfile.RarFile(file_) try: r.extractall(path=extract_dir, pwd=password) for urfile in r.namelist(): unrarred_file = open(os.path.join(extract_dir, urfile)) f_name, full_path = save_hashed_filename(unrarred_file, True) tid = queue_task(urfile, f_name, full_path, metadata, rescan=rescan) task_id_list.append(tid) except RuntimeError as e: msg = "ERROR: Failed to extract " + str(file_) + ' - ' + str(e) return make_response( jsonify({'Message': msg}), HTTP_BAD_REQUEST) else: # File was not an archive to extract f_name, full_path = save_hashed_filename(file_) tid = queue_task(original_filename, f_name, full_path, metadata, rescan=rescan) task_id_list = [tid] msg = {'task_ids': task_id_list} return make_response( jsonify({'Message': msg}), HTTP_CREATED )