Skip to content

Commit f60522f

Browse files
author
Hela Bot
committed
Added slack msg limits
1 parent 20a7a68 commit f60522f

File tree

3 files changed

+74
-14
lines changed

3 files changed

+74
-14
lines changed

hawk_scanner/commands/slack.py

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import re
1+
import time
2+
from datetime import datetime
23
from slack_sdk import WebClient
34
from slack_sdk.errors import SlackApiError
45
from hawk_scanner.internals import system
@@ -21,32 +22,54 @@ def connect_slack(args, token):
2122
system.print_error(args, f"Failed to connect to Slack with error: {e.response['error']}")
2223
return None
2324

24-
def check_slack_messages(args, client, patterns, profile_name, channel_types, channel_names=None):
25+
def check_slack_messages(args, client, patterns, profile_name, channel_types, channel_ids=None, limit_mins=60):
2526
results = []
2627
try:
2728
team_info = client.team_info()
2829
workspace_url = team_info["team"]["url"].rstrip('/')
30+
31+
# Get the Unix timestamp for 'limit_mins' minutes ago
32+
current_time = time.time()
33+
oldest_time = current_time - (limit_mins * 60)
34+
35+
# Convert to human-readable time for debugging
36+
current_time_readable = datetime.fromtimestamp(current_time).strftime('%Y-%m-%d %H:%M:%S')
37+
oldest_time_readable = datetime.fromtimestamp(oldest_time).strftime('%Y-%m-%d %H:%M:%S')
38+
39+
system.print_info(args, f"Current Time: {current_time_readable}")
40+
system.print_info(args, f"Fetching messages from the last {limit_mins} minutes (Oldest Time: {oldest_time_readable}, Unix: {int(oldest_time)})")
41+
2942
# Get all channels of specified types
30-
channels = client.conversations_list(types=channel_types)["channels"]
43+
channels = []
44+
if not channel_ids:
45+
system.print_info("Getting all channels because no channel_ids provided")
46+
channels = client.conversations_list(types=channel_types)["channels"]
47+
else:
48+
system.print_info(args, "Getting channels by channel_ids")
49+
for channel_id in channel_ids:
50+
try:
51+
channel = client.conversations_info(channel=channel_id)["channel"]
52+
channels.append(channel)
53+
except SlackApiError as e:
54+
system.print_error(args, f"Failed to fetch channel with id {channel_id} with error: {e.response['error']}")
3155

32-
# Filter channels by names if provided
33-
if channel_names:
34-
channels = [channel for channel in channels if channel['name'] in channel_names]
35-
3656
system.print_info(args, f"Found {len(channels)} channels of type {channel_types}")
3757
system.print_info(args, f"Checking messages in channels: {', '.join([channel['name'] for channel in channels])}")
38-
58+
3959
for channel in channels:
4060
channel_name = channel["name"]
4161
channel_id = channel["id"]
4262

43-
# Get messages from the channel
63+
# Get messages from the channel within the time range
4464
system.print_info(args, f"Checking messages in channel {channel_name} ({channel_id})")
45-
messages = client.conversations_history(channel=channel_id)["messages"]
65+
messages = client.conversations_history(channel=channel_id, oldest=oldest_time)["messages"]
4666

4767
for message in messages:
4868
user = message.get("user", "")
4969
text = message.get("text")
70+
message_ts = message.get("ts")
71+
72+
# Check main message for matches
5073
if text:
5174
matches = system.match_strings(args, text)
5275
if matches:
@@ -59,10 +82,42 @@ def check_slack_messages(args, client, patterns, profile_name, channel_types, ch
5982
'matches': list(set(match['matches'])),
6083
'sample_text': match['sample_text'],
6184
'profile': profile_name,
62-
'message_link': workspace_url + f"/archives/{channel_id}/p{message['ts'].replace('.', '')}",
85+
'message_link': workspace_url + f"/archives/{channel_id}/p{message_ts.replace('.', '')}",
6386
'data_source': 'slack'
6487
})
88+
89+
# Check for replies (threads)
90+
if "thread_ts" in message:
91+
thread_ts = message["thread_ts"]
92+
93+
# Fetch replies for the thread
94+
replies = client.conversations_replies(channel=channel_id, ts=thread_ts, oldest=oldest_time)["messages"]
95+
96+
# Exclude parent message and check replies
97+
for reply in replies:
98+
if reply["ts"] != thread_ts: # Skip the parent message
99+
reply_user = reply.get("user", "")
100+
reply_text = reply.get("text")
101+
reply_ts = reply.get("ts")
102+
103+
if reply_text:
104+
reply_matches = system.match_strings(args, reply_text)
105+
if reply_matches:
106+
for match in reply_matches:
107+
results.append({
108+
'channel_id': channel_id,
109+
'channel_name': channel_name,
110+
'user': reply_user,
111+
'pattern_name': match['pattern_name'],
112+
'matches': list(set(match['matches'])),
113+
'sample_text': match['sample_text'],
114+
'profile': profile_name,
115+
'message_link': workspace_url + f"/archives/{channel_id}/p{reply_ts.replace('.', '')}",
116+
'data_source': 'slack'
117+
})
118+
65119
return results
120+
66121
except SlackApiError as e:
67122
system.print_error(args, f"Failed to fetch messages from Slack with error: {e.response['error']}")
68123
return results
@@ -82,7 +137,8 @@ def execute(args):
82137
for key, config in slack_config.items():
83138
token = config.get('token')
84139
channel_types = config.get('channel_types', "public_channel,private_channel")
85-
channel_names = config.get('channel_names', None)
140+
channel_ids = config.get('channel_ids', [])
141+
limit_mins = config.get('limit_mins', 60)
86142

87143
if token:
88144
system.print_info(args, f"Checking Slack Profile {key}")
@@ -92,7 +148,7 @@ def execute(args):
92148

93149
client = connect_slack(args, token)
94150
if client:
95-
results += check_slack_messages(args, client, patterns, key, channel_types, channel_names)
151+
results += check_slack_messages(args, client, patterns, key, channel_types, channel_ids, limit_mins)
96152
else:
97153
system.print_error(args, "No Slack connection details found in connection.yml")
98154
else:

hawk_scanner/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
from collections import defaultdict
1212
from hawk_scanner.internals import system
1313
from rich import print
14+
import ssl
15+
16+
# Disable SSL verification globally
17+
ssl._create_default_https_context = ssl._create_unverified_context
1418

1519
def clear_screen():
1620
os.system('cls' if os.name == 'nt' else 'clear')

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION = "0.3.22"
1+
VERSION = "0.3.23"
22

33
from setuptools import setup, find_packages
44

0 commit comments

Comments
 (0)