def create_list(account: Account, user_input: Dict) -> Dict[str, Any]: expected_keys = [ 'id', 'name', 'enable_scans', 'scan_type', 'automated_scan_frequency', 'scheduled_next_scan' ] if sorted(user_input.keys()) != sorted(expected_keys): return operation_response(error=True, message="Missing settings.") frequency = validate_list_automated_scan_frequency( user_input['automated_scan_frequency']) data = { 'account': account, 'name': validate_list_name(user_input['name']), 'enable_scans': bool(user_input['enable_scans']), 'scan_type': validate_list_scan_type(user_input['scan_type']), 'automated_scan_frequency': frequency, 'scheduled_next_scan': UrlList.determine_next_scan_moment(frequency) } urllist = UrlList(**data) urllist.save() # make sure the account is serializable. data['account'] = account.id # adding the ID makes it possible to add new urls to a new list. data['id'] = urllist.pk # give a hint if it can be scanned: data['scan_now_available'] = urllist.is_scan_now_available() return operation_response(success=True, message="List created.", data=data)
def update_list_settings(account: Account, user_input: Dict) -> Dict[str, Any]: """ This cannot update the urls, as that would increase complexity too much. :param account: :param user_input: { 'id': int, 'name': str, 'enable_scans': bool, 'scan_type': str, # todo: Who should set this? Should this be set by admins? How can we avoid permission hell? # Probably as long as the settings are not too detailed / too frequently. 'automated_scan_frequency': str, } :return: """ expected_keys = [ 'id', 'name', 'enable_scans', 'scan_type', 'automated_scan_frequency', 'scheduled_next_scan' ] if check_keys(expected_keys, user_input): return operation_response(error=True, message="Missing settings.") prefetch_last_scan = Prefetch( 'accountinternetnlscan_set', queryset=AccountInternetNLScan.objects.order_by('-id').select_related( 'scan'), to_attr='last_scan') last_report_prefetch = Prefetch( 'urllistreport_set', # filter(pk=UrlListReport.objects.latest('id').pk). queryset=UrlListReport.objects.order_by('-id').only('id', 'at_when'), to_attr='last_report') urllist = UrlList.objects.all().filter(account=account, id=user_input['id'], is_deleted=False).prefetch_related( prefetch_last_scan, last_report_prefetch).first() if not urllist: return operation_response(error=True, message="No list of urls found.") # Yes, you can try and set any value. Values that are not recognized do not result in errors / error messages, # instead they will be overwritten with the default. This means less interaction with users / less annoyance over # errors on such simple forms. frequency = validate_list_automated_scan_frequency( user_input['automated_scan_frequency']) data = { 'id': urllist.id, 'account': account, 'name': validate_list_name(user_input['name']), 'enable_scans': bool(user_input['enable_scans']), 'scan_type': validate_list_scan_type(user_input['scan_type']), 'automated_scan_frequency': frequency, 'scheduled_next_scan': UrlList.determine_next_scan_moment(frequency), } updated_urllist = UrlList(**data) updated_urllist.save() # make sure the account is serializable. data['account'] = account.id # inject the last scan information. data['last_scan_id'] = None if not len( urllist.last_scan) else urllist.last_scan[0].scan.id data['last_scan'] = None if not len( urllist.last_scan) else urllist.last_scan[0].scan.started_on.isoformat( ) data['last_scan_finished'] = None if not len( urllist.last_scan) else urllist.last_scan[0].scan.finished data['last_report_id'] = None if not len( urllist.last_report) else urllist.last_report[0].id data['last_report_date'] = None if not len( urllist.last_report) else urllist.last_report[0].at_when data['scan_now_available'] = updated_urllist.is_scan_now_available() log.debug(data) return operation_response(success=True, message="Updated list settings", data=data)