Skip to content

Commit

Permalink
Merge pull request #29 from splunk-soar-connectors/next
Browse files Browse the repository at this point in the history
Merging next to main for release 2.6.2
  • Loading branch information
rgil-splunk authored May 22, 2023
2 parents dfa5908 + 0e1d229 commit 49a3531
Show file tree
Hide file tree
Showing 16 changed files with 53 additions and 85 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Slack

Publisher: Splunk
Connector Version: 2.6.1
Connector Version: 2.6.2
Product Vendor: Slack Technologies
Product Name: Slack
Product Version Supported (regex): ".\*"
Expand Down
1 change: 1 addition & 0 deletions release_notes/2.6.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Add log rotation for bot log files [PAPP-30433]
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
beautifulsoup4==4.10.0
Django==3.2.16
idna==3.3
requests==2.27.1
sh==1.14.2
Expand Down
54 changes: 9 additions & 45 deletions slack.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"type": "information",
"license": "Copyright (c) 2016-2023 Splunk Inc.",
"main_module": "slack_connector.py",
"app_version": "2.6.1",
"utctime_updated": "2023-04-21T23:58:08.000000Z",
"app_version": "2.6.2",
"utctime_updated": "2023-05-11T00:32:21.000000Z",
"product_vendor": "Slack Technologies",
"product_name": "Slack",
"product_version_regex": ".*",
Expand Down Expand Up @@ -4280,21 +4280,13 @@
],
"pip_dependencies": {
"wheel": [
{
"module": "Django",
"input_file": "wheels/py3/Django-3.2.16-py3-none-any.whl"
},
{
"module": "asgiref",
"input_file": "wheels/py3/asgiref-3.4.1-py3-none-any.whl"
},
{
"module": "beautifulsoup4",
"input_file": "wheels/py3/beautifulsoup4-4.10.0-py3-none-any.whl"
},
{
"module": "certifi",
"input_file": "wheels/py3/certifi-2022.12.7-py3-none-any.whl"
"input_file": "wheels/py3/certifi-2023.5.7-py3-none-any.whl"
},
{
"module": "charset_normalizer",
Expand All @@ -4304,10 +4296,6 @@
"module": "idna",
"input_file": "wheels/py3/idna-3.3-py3-none-any.whl"
},
{
"module": "pytz",
"input_file": "wheels/shared/pytz-2022.7.1-py2.py3-none-any.whl"
},
{
"module": "requests",
"input_file": "wheels/shared/requests-2.27.1-py2.py3-none-any.whl"
Expand All @@ -4330,23 +4318,15 @@
},
{
"module": "slack_sdk",
"input_file": "wheels/shared/slack_sdk-3.20.0-py2.py3-none-any.whl"
"input_file": "wheels/shared/slack_sdk-3.21.3-py2.py3-none-any.whl"
},
{
"module": "soupsieve",
"input_file": "wheels/py3/soupsieve-2.3.2.post1-py3-none-any.whl"
},
{
"module": "sqlparse",
"input_file": "wheels/py3/sqlparse-0.4.3-py3-none-any.whl"
},
{
"module": "typing_extensions",
"input_file": "wheels/py3/typing_extensions-4.1.1-py3-none-any.whl"
},
{
"module": "urllib3",
"input_file": "wheels/shared/urllib3-1.26.14-py2.py3-none-any.whl"
"input_file": "wheels/shared/urllib3-1.26.15-py2.py3-none-any.whl"
},
{
"module": "websocket_client",
Expand All @@ -4356,21 +4336,13 @@
},
"pip39_dependencies": {
"wheel": [
{
"module": "Django",
"input_file": "wheels/py3/Django-3.2.16-py3-none-any.whl"
},
{
"module": "asgiref",
"input_file": "wheels/py3/asgiref-3.6.0-py3-none-any.whl"
},
{
"module": "beautifulsoup4",
"input_file": "wheels/py3/beautifulsoup4-4.10.0-py3-none-any.whl"
},
{
"module": "certifi",
"input_file": "wheels/py3/certifi-2022.12.7-py3-none-any.whl"
"input_file": "wheels/py3/certifi-2023.5.7-py3-none-any.whl"
},
{
"module": "charset_normalizer",
Expand All @@ -4380,10 +4352,6 @@
"module": "idna",
"input_file": "wheels/py3/idna-3.3-py3-none-any.whl"
},
{
"module": "pytz",
"input_file": "wheels/shared/pytz-2022.7.1-py2.py3-none-any.whl"
},
{
"module": "requests",
"input_file": "wheels/shared/requests-2.27.1-py2.py3-none-any.whl"
Expand All @@ -4406,19 +4374,15 @@
},
{
"module": "slack_sdk",
"input_file": "wheels/shared/slack_sdk-3.20.0-py2.py3-none-any.whl"
"input_file": "wheels/shared/slack_sdk-3.21.3-py2.py3-none-any.whl"
},
{
"module": "soupsieve",
"input_file": "wheels/py3/soupsieve-2.4-py3-none-any.whl"
},
{
"module": "sqlparse",
"input_file": "wheels/py3/sqlparse-0.4.3-py3-none-any.whl"
"input_file": "wheels/py3/soupsieve-2.4.1-py3-none-any.whl"
},
{
"module": "urllib3",
"input_file": "wheels/shared/urllib3-1.26.14-py2.py3-none-any.whl"
"input_file": "wheels/shared/urllib3-1.26.15-py2.py3-none-any.whl"
},
{
"module": "websocket_client",
Expand Down
80 changes: 42 additions & 38 deletions slack_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions
# and limitations under the License.
import logging
import logging.handlers
import os
import re
import shlex
import sys
import tempfile
from argparse import ArgumentParser
from datetime import datetime
from pathlib import Path

import encryption_helper
import pytz
import requests
import simplejson as json
import six
Expand Down Expand Up @@ -131,19 +132,6 @@
"""


def tmp_log(msg):
log_dir = "/tmp"
log_path = Path(log_dir) / "slack.log"
log_path.touch()

tz_Denver = pytz.timezone('America/Denver')
now = datetime.now(tz_Denver)
current_time = now.strftime("%Y-%m-%d %H:%M:%S")

with log_path.open('a') as bubbly:
bubbly.write(current_time + ": " + msg + "\n")


def _load_app_state(asset_id):
""" This function is used to load the current state file.
Expand Down Expand Up @@ -1116,7 +1104,7 @@ def interactive_message_handler(ack, body, respond):

answer_filename = '{0}.json'.format(qid)
answer_path = "{0}/{1}".format(state_dir, answer_filename)
tmp_log('**going to put answer file here: {}'.format(answer_path))
logging.debug('**going to put answer file here: {}'.format(answer_path))

final_payload = process_payload(body, answer_path)

Expand All @@ -1136,17 +1124,17 @@ def mention_handler(body, say):
is mentioned in the cat. It receives a json body which contains the data of the event. The command and
channel name are parsed from the body and passed to command handler to further process the command.
"""
tmp_log('**app_mention handler hit')
logging.info('**app_mention handler hit')
if body:
# tmp_log('**body from app mention: {}'.format(body))
# logging.debug('**body from app mention: {}'.format(body))
user = body.get("event", {}).get("user")
tmp_log('**user that spawned bot command is {}'.format(user))
logging.info('**user that spawned bot command is {}'.format(user))
if not self._check_user_authorization(user):
say('`User {} is not authorized to use this bot`'.format(user))
return

out_text = body.get("event", {}).get("text")
tmp_log('**body exists, app_mention text: {}'.format(out_text))
logging.debug('**body exists, app_mention text: {}'.format(out_text))

if out_text and out_text.startswith(self.cmd_start):
if out_text.strip() == self.cmd_start:
Expand Down Expand Up @@ -1178,54 +1166,54 @@ def mention_handler(body, say):
handler.start()

def _check_user_authorization(self, user):
tmp_log('**Checking authorization for user "{}"'.format(user))
logging.info('**Checking authorization for user "{}"'.format(user))
permitted_users = self.permitted_users

if not permitted_users:
tmp_log('**No permitted users specified. falling back to allow all')
logging.info('**No permitted users specified. falling back to allow all')
return True

else:
user_list = permitted_users.split(",")
tmp_log('**Permitted_users: {}'.format(user_list))
logging.debug('**Permitted_users: {}'.format(user_list))
if user in user_list:
tmp_log('**User "{}" is permitted to use bot'.format(user))
logging.info('**User "{}" is permitted to use bot'.format(user))
return True
else:
tmp_log('**User "{}" is not permitted to use bot'.format(user))
logging.info('**User "{}" is not permitted to use bot'.format(user))
return False

def _check_command_authorization(self, cmd_type):
if cmd_type == "act":
if self.permit_act:
tmp_log('**Command: "{}" is permitted'.format(cmd_type))
logging.info('**Command: "{}" is permitted'.format(cmd_type))
return True
else:
tmp_log('**Command:"{}" is not permitted'.format(cmd_type))
logging.info('**Command:"{}" is not permitted'.format(cmd_type))
return False

if cmd_type == "run_playbook":
if self.permit_playbook:
tmp_log('**Command: "{}" is permitted'.format(cmd_type))
logging.info('**Command: "{}" is permitted'.format(cmd_type))
return True
else:
tmp_log('**Command: "{}" is not permitted'.format(cmd_type))
logging.info('**Command: "{}" is not permitted'.format(cmd_type))
return False

if cmd_type == "get_container":
if self.permit_container:
tmp_log('**Command:" {}" is permitted'.format(cmd_type))
logging.info('**Command:" {}" is permitted'.format(cmd_type))
return True
else:
tmp_log('**Command: "{}" is not permitted'.format(cmd_type))
logging.info('**Command: "{}" is not permitted'.format(cmd_type))
return False

if cmd_type == "list":
if self.permit_list:
tmp_log('**Command: "{}" is permitted'.format(cmd_type))
logging.info('**Command: "{}" is permitted'.format(cmd_type))
return True
else:
tmp_log('**Command: "{}" is not permitted'.format(cmd_type))
logging.info('**Command: "{}" is not permitted'.format(cmd_type))
return False
else:
return False
Expand All @@ -1250,27 +1238,27 @@ def _handle_command(self, command, channel):
return

if cmd_type == "act":
tmp_log("**permit_bot_act: {}".format(self.permit_act))
logging.info("**permit_bot_act: {}".format(self.permit_act))
status, result = self._parse_action(args[1:])
if (status):
msg = self._action_run_request(result, channel)
else:
msg = result

elif cmd_type == "run_playbook":
tmp_log("**permit_bot_playbook: {}".format(self.permit_playbook))
logging.info("**permit_bot_playbook: {}".format(self.permit_playbook))
status, result = self._parse_playbook(args[1:])
if (status):
msg = self._playbook_request(result, channel)
else:
msg = result

elif cmd_type == "get_container":
tmp_log("**permit_bot_container: {}".format(self.permit_container))
logging.info("**permit_bot_container: {}".format(self.permit_container))
status, msg = self._parse_container(args[1:])

elif cmd_type == "list":
tmp_log("**permit_bot_list: {}".format(self.permit_list))
logging.info("**permit_bot_list: {}".format(self.permit_list))
status, msg = self._parse_list(args[1:])

else:
Expand All @@ -1279,9 +1267,25 @@ def _handle_command(self, command, channel):
self._post_message(msg, channel)


def set_up_logging():
""" Set up logging for the bot. """
log_file = Path(tempfile.gettempdir()) / 'slack.log'
max_bytes = 5 * 1024 * 1024 # 5MB
log_formatter = logging.Formatter('[%(process)d][%(asctime)s][%(levelname)s] %(message)s')

log_handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=max_bytes, backupCount=4)
log_handler.setFormatter(log_formatter)

logger = logging.getLogger()
logger.addHandler(log_handler)
logger.setLevel(logging.DEBUG)
return logger


if __name__ == '__main__': # noqa: C901
set_up_logging()

tmp_log('**Spawning slack_bot.py...')
logging.info('**Spawning slack_bot.py...')
if (not os.path.exists('./bot_config.py')):
if (len(sys.argv) != 3):
print("Please create a bot_config.py file, and place it in this directory")
Expand Down
Binary file removed wheels/py3/Django-3.2.16-py3-none-any.whl
Binary file not shown.
Binary file removed wheels/py3/asgiref-3.4.1-py3-none-any.whl
Binary file not shown.
Binary file removed wheels/py3/asgiref-3.6.0-py3-none-any.whl
Binary file not shown.
Binary file not shown.
Binary file removed wheels/py3/soupsieve-2.4-py3-none-any.whl
Binary file not shown.
Binary file added wheels/py3/soupsieve-2.4.1-py3-none-any.whl
Binary file not shown.
Binary file removed wheels/py3/sqlparse-0.4.3-py3-none-any.whl
Binary file not shown.
Binary file removed wheels/py3/typing_extensions-4.1.1-py3-none-any.whl
Binary file not shown.
Binary file removed wheels/shared/pytz-2022.7.1-py2.py3-none-any.whl
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 49a3531

Please sign in to comment.