Skip to content

Commit

Permalink
Merge pull request #2 from egnyte/release/1.0.7
Browse files Browse the repository at this point in the history
Release/1.0.7
  • Loading branch information
kcieslak-eg authored Nov 29, 2023
2 parents 2f13902 + 53d370f commit fa63e1f
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 8 deletions.
2 changes: 1 addition & 1 deletion TA-egnyte-connect/app.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"id": {
"group": null,
"name": "TA-egnyte-connect",
"version": "1.0.6"
"version": "1.0.7"
},
"author": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"meta": {
"name": "TA-egnyte-connect",
"displayName": "Egnyte Collaborate Add-on for Splunk",
"version": "1.0.3",
"version": "1.0.7",
"apiVersion": "3.0.0",
"restRoot": "TA_egnyte_connect"
},
Expand Down
25 changes: 20 additions & 5 deletions TA-egnyte-connect/bin/input_module_egnyte_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import time
import datetime
import json
from solnlib.splunkenv import get_splunkd_uri
from solnlib.credentials import (CredentialManager, CredentialNotExistException)
from datetime import datetime, timedelta
from ta_egnyte_connect_utility import *
import ta_egnyte_connect_constants as tec
import splunk.rest as rest
APP_NAME = os.path.abspath(__file__).split(os.sep)[-3]

import splunklib.client as client

'''
IMPORTANT
Edit only the validate_input and collect_events functions.
Expand Down Expand Up @@ -82,12 +82,15 @@ def collect_events(helper, ew):
auth_url = str(egnyte_domain_url) + "/puboauth/token"
mapping_data_type={"FILE_AUDIT": "file", "PERMISSION_AUDIT": "permission", "LOGIN_AUDIT": "login", "USER_AUDIT": "user", "WG_SETTINGS_AUDIT": "wg_settings", "GROUP_AUDIT": "group", "WORKFLOW_AUDIT": "workflow"}
checkpoint = get_checkpoint(helper, key=account_name, start_date=start_date) or dict()

service = client.connect(host='localhost', port=8089,
username='admin', password='admin123')

# Going to take access/refresh token if it is not available in the checkpoint
if not checkpoint or str(checkpoint.get("code")) != str(code):
helper.log_info("Checkpoint is not available or code changed from setup page. Hence requesting new access token.")
try:
response = generate_or_refresh_token(helper=helper, auth_url=auth_url, clientid=clientid, client_secret=client_secret, code=code, redirect_uri=REDIRECT_URI)
helper.log_info("Checkpoint is not available or code changed from setup page. Hence requested new access token.")
if response.status_code == 400:
helper.log_error("Error while getting access/refresh token error")
helper.log_error("Please generate new code and update the input with new code.")
Expand All @@ -101,9 +104,17 @@ def collect_events(helper, ew):
return
else:
response = response.json()
checkpoint["access_token"] = response.get("access_token")
checkpoint["code"] = code
set_checkpoint(helper, key=account_name, checkpoint=checkpoint)

storage_passwords = service.storage_passwords
try:
# Retrieve existing password. This is safeguard in case of any racing condition.
# updating token is not necessary as it is deterministic based on client_id, secret & domain
body = storage_passwords.get(account_name + "/" + code)["body"]
except HTTPError:
storage_passwords.create(response.get("access_token"), account_name + "/" + code)
helper.log_debug("New storage password entry created for {}".format(response.get("access_token")))
except Exception as e:
raise e

Expand All @@ -116,6 +127,9 @@ def collect_events(helper, ew):
params = {}
if checkpoint_for_input.get("nextCursor"):
params['nextCursor']=checkpoint_for_input.get("nextCursor")

token = get_token_from_secure_password(account_name, code, service, helper, checkpoint, checkpoint_for_input)

while start_date_done:
try:
# collecting issues from the Egnyte server
Expand All @@ -126,7 +140,8 @@ def collect_events(helper, ew):
params.pop("startDate")
params.pop("endDate")
data_url = str(egnyte_domain_url) + "/pubapi/v2/audit/stream"
data, response_text = collect_issues(helper, checkpoint.get('access_token'), data_url, params)

data, response_text = collect_issues(helper, token, data_url, params)

if data == 401:
helper.log_error("Please generate new code and update the input with new code.")
Expand Down
42 changes: 42 additions & 0 deletions TA-egnyte-connect/bin/ta_egnyte_connect_utility.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import requests
from splunklib.binding import HTTPError, ResponseReader
import xml.etree.ElementTree as ET


def generate_or_refresh_token(helper=None, auth_url=None, clientid=None, client_secret=None, code=None, refresh_token=None, redirect_uri=None):
if code:
payload = {"client_id": clientid, "client_secret": client_secret, "grant_type": "authorization_code",
Expand All @@ -13,6 +17,44 @@ def generate_or_refresh_token(helper=None, auth_url=None, clientid=None, client_
return response


def get_token_from_secure_password(account_name, code, service, helper, checkpoint, checkpoint_for_input):
storage_passwords = service.storage_passwords
try:
response = storage_passwords.get(account_name + "/" + code)
reader: ResponseReader = ResponseReader(response["body"])

xml_response_str: str = reader.read().decode("UTF-8")
start_tag = "<s:key name=\"clear_password\">"
end_tag = "</s:key>"
# getting index of substrings
idx1 = xml_response_str.index(start_tag)

xml_data_substr = xml_response_str[idx1:]
idx2_from_substring = xml_data_substr.index(end_tag)
idx2 = idx1 + idx2_from_substring

token: str = ''
# getting elements in between
for idx in range(idx1 + len(start_tag), idx2):
token = token + xml_response_str[idx]

helper.log_debug("Access token in StoragePassword already exist. Erasing eventual access token from checkpoint.")
checkpoint_for_input.pop("access_token", None)

return token

except HTTPError:
helper.log_debug("Unable to find access token in StoragePassword engine. Performing one time "
"migration from checkpoint.")
token = checkpoint.get('access_token')
try:
storage_passwords.create(token, account_name + "/" + code)
helper.log_debug("Access token migrated.")
except HTTPError:
helper.log_debug("Access token already exist. Erasing access token from checkpoint.")
checkpoint_for_input.pop("access_token", None)


def collect_issues(helper, access_token, data_url, params):
headers = {"Authorization": "Bearer " + str(access_token)}
response_data = helper.send_http_request(data_url, "GET", parameters=params, payload=None,
Expand Down
2 changes: 1 addition & 1 deletion TA-egnyte-connect/default/app.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ state = enabled
build = 1

[launcher]
version = 1.0.6
version = 1.0.7
author = Egnyte Inc
description = This TA provides interface to ingest events from Egnyte Collaborate into Splunk.

Expand Down

0 comments on commit fa63e1f

Please sign in to comment.