diff --git a/inex.py b/inex.py index 42f04ee..7eef49f 100644 --- a/inex.py +++ b/inex.py @@ -13,7 +13,10 @@ import inexSqlquery class Inex: def __init__(self): - """Initilize config, calls functions from inex-connect.py and inex-logging.py""" + """Initilize config, calls functions from inexConnect.py, inexLogging.py + inexDataModel.py, inexDataProcessing.py, inexEncoder.py and inexSqlquery.py + Main logic of the program. Requires a config.toml in the same directory it's + being run from.""" # assign libraries self.db = pyodbc self.il = logging @@ -25,6 +28,7 @@ class Inex: self.e = inexEncoder.Encoder self.sq = inexSqlquery + # Check if local config file exists. if self.os.path.exists('./config.toml'): config_file_path = './config.toml' with open(config_file_path, 'rb') as c: @@ -71,18 +75,20 @@ class Inex: # create the connection to the database self.cursor = self.ic.inexSql.connectDatabase(self, self.db, self.dbDriver, self.dbServer, self.dbDatabase, self.dbUser, self.dbPassword) - + # Query the database self.data = self.ic.inexSql.databaseQuery(self, self.cursor, self.sq.sqlQuerymodel.queryData(self.queryOverride,self.dbQuery, self.queryDaystopull)) + # Modify the data to meet EFC requirements self.modifiedData = processData(self.data, dataTemplate, prd_ext_tenant_name=self.prdExttenantname,product_name=self.productName,\ prd_ext_tenant_id=self.platformConfig["tenant_id"]) + # Push data to EFC. Check for local Auth token -> Authenticate if needed -> push data if self.pushToplatform: inexConnect.fortraEFC.__init__(self) - # TODO: move this to its own function if self.useLog: self.il.warning(f"Writing to '{self.outputFile}'.") + # Write data to json if self.writeJsonfile: with open(self.outputFile, "w") as f: self.j.dump(self.modifiedData, f, indent = 2, cls=self.e) diff --git a/inexConnect.py b/inexConnect.py index b42cbf4..5aa5894 100644 --- a/inexConnect.py +++ b/inexConnect.py @@ -20,6 +20,7 @@ class inexSql: return cursor def databaseQuery(self, cursor, query, args=()): + """Use the database connection to send a query.""" if self.useLog: self.il.debug(f"Query:") self.il.debug(query) @@ -43,7 +44,10 @@ class inexSql: return r class fortraEFC: + """Class to connect to fortra EFC. It will authenticate and push rest payloads. + Writes a .token file to the same directory script was run in.""" def __init__(self): + """This is the logic for how authentication is handled""" # Check if .token file is present if fortraEFC.readToken(self) == 1: # Get fresh token. First run. @@ -57,6 +61,8 @@ class fortraEFC: fortraEFC.pushPayload(self) def readToken(self): + """Looks locally for a .token file. Returns a numeral code + for logic in the init method.""" if self.os.path.exists(self.tokenFilepath): with open(self.tokenFilepath, 'rb') as t: self.tokenData = self.j.load(t) @@ -66,6 +72,7 @@ class fortraEFC: return 1 def getToken(self): + """Gets a token from fortra idp.""" self.tokenData = self.r.post(self.platformConfig["idp"], data={"grant_type":"client_credentials",\ "client_id": self.platformConfig["client_id"],\ "client_secret": self.platformConfig["secret"],}) @@ -73,12 +80,14 @@ class fortraEFC: self.il.debug(f'getToken {self.tokenData["access_token"]}') def writeToken(self): + """Writes a token to a local file named '.token'.""" fortraEFC.getToken(self) with open(self.tokenFilepath, "w") as f: self.j.dump(self.tokenData, f, indent = 2) self.il.debug(f'writeToken {self.tokenData["access_token"]}') def pushPayload(self): + """Sends data to fortra EFC. Requires a token from the idp.""" self.il.debug(f'pushPayload {self.tokenData["access_token"]}') url = f'{self.platformConfig["efc_url"]}/api/v1/unity/data/{self.platformConfig["tenant_id"]}/machine_event' pushPayloadResponse = self.r.post(url, headers={'Authorization': f'Bearer {self.tokenData["access_token"]}'},\ diff --git a/inexDataModel.py b/inexDataModel.py index 12d6ca9..f2d70f9 100644 --- a/inexDataModel.py +++ b/inexDataModel.py @@ -1,4 +1,8 @@ def dataTemplate(transactionType,**kwargs): + """Created templates for use. This function forms json data into an + appropriate model for EFC. It returnes the appropriate template based + on the transaction type passed into the function. The logic to process + this is at the bottom of the function.""" upload = { "bytes" : kwargs.get('bytes'), "dst_endpoint": { diff --git a/inexDataProcessing.py b/inexDataProcessing.py index b38cff4..d3d4719 100644 --- a/inexDataProcessing.py +++ b/inexDataProcessing.py @@ -1,7 +1,8 @@ def processData(data, template, **kwargs): """Translates data from sql query to the appropriate place in the respective template. Accepts data, which is the sql query output, the template function, and finally - additional data to insert into the template.""" + additional data to insert into the template. Uses other functions to further + process row data.""" processedData = [] transactionLoginid = [] @@ -102,6 +103,12 @@ def identifyUserType(obj): return None def parseHomefolder(user, virtualfolder): + """Extract users home folder using the username. Will not work on edge cases + such as when a users home folder does not have the user name. When that occurs + it is impossible to know based on the arm data what the home folder is. + This function is an assumption so it may return the incorrect home folder. + This function finds the user name and takes the path from the left of the folder + as the home folder. There are cases where this may not be accurate.""" if user: userSplit = f'/{user}/' if virtualfolder: diff --git a/inexSqlquery.py b/inexSqlquery.py index f7a080e..5506d33 100644 --- a/inexSqlquery.py +++ b/inexSqlquery.py @@ -1,6 +1,6 @@ class sqlQuerymodel: def queryData(overRideflag, configQuery, daysTopull): - """Embedded query data""" + """Embedded query data. Data is slightly modified to change the amount of days to pull.""" q ="""DECLARE @stopTime DATETIME2 SET @stopTime=DATEADD(DAY, -30, GETDATE()) SELECT p.ProtocolCommandID, t.Time_stamp, p.RemoteIP, p.RemotePort, p.LocalIP, p.LocalPort, p.Protocol, p.SiteName, p.Command, p.FileName, p.PhysicalFolderName, p.VirtualFolderName, p.FileSize, p.TransferTime, p.BytesTransferred, p.Description, p.ResultID, t.TransactionID, p.Actor, t.TransactionObject, t.NodeName, t.TransactionGUID, a.Protocol user_type