🔍 Overview
These Celery tasks work together to verify and manage blocked Links:
check_blocked_links_via_google_task– checks blocked domains via Google Safe Browsing API, scheduled to run every 15 minutes.unblock_link_task– unblocks links deemed safe after revalidation.
📝 Task Definitions
@celery.task
def check_blocked_links_via_google_task():
logger.info("Checking BLOCKED links via Google Safe Browsing API...")
domain_map = Link.get_domains_map(
status=LinkStatuses.BLOCKED.value,
reason_exclude=BlockReasons.DNS_NOT_RESOLVABLE.value
)
total = len(domain_map)
if total == 0:
logger.info("No blocked domains found to check!")
return
# count unique domains
logger.info(f"Found {total} blocked domains to check...")
for chunk_domains in chunked(list(domain_map.keys())):
logger.info(f"Checking BLOCKED domains chunk: {chunk_domains}")
unsafe_domains = GoogleSafeBrowsing.check_links(chunk_domains)
if unsafe_domains is None:
continue
for domain in chunk_domains:
if domain not in unsafe_domains:
for obj in domain_map[domain]:
logger.info(f"Blocked link {obj.link} is safe!")
unblock_link_task.delay(obj.id)
logger.info(f"Processed {len(chunk_domains)} domains, safe domains found: {len(chunk_domains) - len(unsafe_domains)}")
logger.info("Finished checking BLOCKED links via Google Safe Browsing API.")
@celery.task
def unblock_link_task(link_id: int, action_by: str = "system"):
try:
link = Link.objects.get(id=link_id)
except Link.DoesNotExist:
logger.error(f"Link with ID {link_id} does not exist!")
return
if link.status != LinkStatuses.BLOCKED.value:
logger.warning(f"Link {link.link} is not blocked, cannot unblock!")
return
if not is_domain_resolvable(link.domain):
logger.warning(f"Domain {link.domain} is not resolvable, cannot unblock link {link.link}.")
link.set_block(
reason=BlockReasons.DNS_NOT_RESOLVABLE.value,
with_switch=False,
action_by=action_by
)
return
# bypass of incorrect unblocking by Google Safe Browsing
if timezone.now() - link.blocked_at < timezone.timedelta(hours=1):
logger.warning(f"Link {link.link} was blocked less than an hour ago, skipping unblocking.")
return
# if current link has an active link - unblock it with return to work else just unblock
active_link = link.get_main_active_link(search_direction=SearchDirection.FORWARD.value)
link.set_unblock(with_return_to_work=active_link is not None, action_by=action_by)
logger.info(f"Link {link.link} unblocked successfully!")📑 Attributes
This table describes the parameters for unblock_link_task:
| Name | Type | Description |
|---|---|---|
link_id | int | Primary key of the Link to revalidate and unblock. |
action_by | str | Actor requesting the unblock (system by default or other). |
⚙️ Task Behavior & Flow
-
Blocked Links Revalidation
- Retrieves all blocked domains excluding those blocked for DNS resolution issues.
- Splits domains into chunks by 500 domains for batch checking.
- Calls
GoogleSafeBrowsing.check_links()on each chunk. - Enqueues
unblock_link_taskfor every domain not flagged as unsafe.
-
Unblocking Operation
- Fetches the
Linkrecord bylink_id. - If still blocked and blocked for over 1 hour, calls
link.set_unblock(...). - If the domain is not resolvable, it logs a warning and blocks the link again with a DNS resolution reason.
- If the link has an active link, it will return to work; otherwise, it will simply unblock.
- Logs a warning if the link was blocked less than an hour ago or is already unblocked.
- Logs an error if the
Linkrecord does not exist.
- Fetches the