offlinesec-client 1.1.45__tar.gz → 1.1.47__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/PKG-INFO +1 -1
  2. offlinesec_client-1.1.47/offlinesec_client/__init__.py +1 -0
  3. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/agr_cfg_read.py +112 -67
  4. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/func.py +1 -1
  5. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_roles_report.py +17 -3
  6. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/resolve_report.py +1 -2
  7. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/sap_table.py +24 -98
  8. offlinesec_client-1.1.47/offlinesec_client/sap_table_def.py +91 -0
  9. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/yaml_cfg_read.py +11 -6
  10. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/yaml_cfg_rfc.py +0 -5
  11. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/PKG-INFO +1 -1
  12. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/SOURCES.txt +1 -0
  13. offlinesec_client-1.1.45/offlinesec_client/__init__.py +0 -1
  14. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/README.md +0 -0
  15. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/__main__.py +0 -0
  16. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/abap_system.py +0 -0
  17. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/agr_1251.py +0 -0
  18. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/api_sec_notes.py +0 -0
  19. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/bo_system.py +0 -0
  20. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/config.py +0 -0
  21. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/const.py +0 -0
  22. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/cwbntcust.py +0 -0
  23. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/exclude_params.py +0 -0
  24. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/get_reports.py +0 -0
  25. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/java_system.py +0 -0
  26. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/masking.py +0 -0
  27. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/multi_systems.py +0 -0
  28. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_abap_review.py +0 -0
  29. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_bo_notes.py +0 -0
  30. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_java_notes.py +0 -0
  31. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_notes_report.py +0 -0
  32. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_param_report.py +0 -0
  33. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_patch_day.py +0 -0
  34. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_rfc_report.py +0 -0
  35. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_sec_notes.py +0 -0
  36. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/rfcdes.py +0 -0
  37. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/rsparam.py +0 -0
  38. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/sap_gui.py +0 -0
  39. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/sap_system.py +0 -0
  40. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/dependency_links.txt +0 -0
  41. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/entry_points.txt +0 -0
  42. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/requires.txt +0 -0
  43. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/top_level.txt +0 -0
  44. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/setup.cfg +0 -0
  45. {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: offlinesec_client
3
- Version: 1.1.45
3
+ Version: 1.1.47
4
4
  Summary: Offline Security Client
5
5
  Home-page: https://offlinesec.com
6
6
  Author: Offline Security
@@ -0,0 +1 @@
1
+ __version__ = "1.1.47"
@@ -8,6 +8,9 @@ from offlinesec_client.sap_table import SAPTable
8
8
  from offlinesec_client.yaml_cfg_read import YamlCfgFile
9
9
  from offlinesec_client.masking import Masking, ROLE_MASK, SAPSID_MASK
10
10
 
11
+ FF_MASK_KEY = "ff_mask"
12
+
13
+
11
14
  class RolesCfgFile:
12
15
  def __init__(self,
13
16
  file_name,
@@ -26,15 +29,15 @@ class RolesCfgFile:
26
29
  yaml_file = YamlCfgFile(file_name=self.file_name)
27
30
 
28
31
  if not yaml_file.check_class_item():
29
- print("\n".join(yaml_file.err_list))
32
+ self.err_list.extend(yaml_file.err_list)
30
33
  self.err_flag = True
31
34
  return
32
35
 
33
- if "ff_masks" in yaml_file.content:
34
- if isinstance(yaml_file.content["ff_masks"], list):
35
- self.ff_masks = yaml_file.content["ff_masks"]
36
+ if FF_MASK_KEY in yaml_file.content:
37
+ if isinstance(yaml_file.content[FF_MASK_KEY], list):
38
+ self.ff_masks = yaml_file.content[FF_MASK_KEY]
36
39
  else:
37
- self.ff_masks.append(yaml_file.content["ff_masks"])
40
+ self.ff_masks.append(yaml_file.content[FF_MASK_KEY])
38
41
 
39
42
  outdict = dict()
40
43
  for system in yaml_file:
@@ -42,15 +45,15 @@ class RolesCfgFile:
42
45
 
43
46
  agr_users = dict()
44
47
  if "agr_users" in system:
45
- agr_users = RolesCfgFile.read_agr_users(system["agr_users"])
48
+ agr_users = self.read_agr_users(system["agr_users"], sys_name=name)
46
49
 
47
50
  usr02 = dict()
48
51
  if "usr02" in system:
49
- usr02 = RolesCfgFile.read_usr02(system["usr02"])
52
+ usr02 = self.read_usr02(system["usr02"], sys_name=name)
50
53
 
51
54
  agr_1251 = dict()
52
55
  if "agr_1251" in system:
53
- agr_1251 = RolesCfgFile.read_agr_1251(system["agr_1251"])
56
+ agr_1251 = self.read_agr_1251(system["agr_1251"], sys_name=name)
54
57
 
55
58
  if name not in outdict:
56
59
  # add ff flag
@@ -59,12 +62,14 @@ class RolesCfgFile:
59
62
  usr02=usr02,
60
63
  agr_1251=agr_1251,
61
64
  ff_masks=self.ff_masks
62
- )
65
+ )
63
66
  else:
64
- print(" * [Warning] Duplicated name %s. Repeated definitions are ignored" % (name,))
67
+ self.err_list.append(" * [WARNING] Duplicated name %s. Repeated definitions are ignored" % (name,))
68
+
69
+ if len(outdict):
70
+ #Exclude not assigned roles, ff roles
71
+ self.filter_roles(outdict)
65
72
 
66
- #Exclude not assigned roles, ff roles
67
- self.filter_roles(outdict)
68
73
  return outdict
69
74
 
70
75
  def filter_roles(self, outdict):
@@ -150,21 +155,59 @@ class RolesCfgFile:
150
155
  assigned_to_active_npa_users)
151
156
  return temp_list
152
157
 
153
- @staticmethod
154
- def read_agr_users(tables):
155
- if not isinstance(tables,list):
158
+
159
+ def read_one_table(self, table_name, file_name, sys_name=None):
160
+ if not os.path.isfile(file_name):
161
+ if sys_name:
162
+ self.err_list.append(
163
+ " * [WARNING] File %s not found (the %s table in %s)" % (file_name, table_name, sys_name))
164
+ else:
165
+ self.err_list.append(" * [WARNING] File %s not found (the %s table)" % (file_name, table_name))
166
+ return
167
+ try:
168
+ tbl = SAPTable(table_name=table_name,
169
+ file_name=file_name,
170
+ sys_name=sys_name)
171
+ except Exception as err:
172
+ if sys_name:
173
+ self.err_list.append(
174
+ " * [WARNING] Can't read the table from file %s due to %s (the %s table in %s)" % (
175
+ file_name, str(err), table_name, sys_name))
176
+ else:
177
+ self.err_list.append(" * [WARNING] Can't read the table from file %s due to %s (the %s table)" % (
178
+ file_name, str(err), table_name))
179
+ return
180
+ else:
181
+ if tbl is None:
182
+ if sys_name:
183
+ self.err_list.append(
184
+ " * [WARNING] Unknown error in the file %s (the %s table in %s)" % (file_name, table_name, sys_name))
185
+ else:
186
+ self.err_list.append(" * [WARNING] Unknown error in the file %s (the %s table)" % (file_name, table_name))
187
+ return
188
+
189
+ if not tbl.check_columns():
190
+ self.err_list.extend(tbl.err_list)
191
+ return
192
+
193
+ return tbl
194
+
195
+ def read_agr_users(self, tables, sys_name=None):
196
+ AGR_USERS = "AGR_USERS"
197
+
198
+ if not isinstance(tables, list):
156
199
  new_item = tables
157
200
  tables = list()
158
201
  tables.append(new_item)
159
202
 
160
203
  temp_list = dict()
161
204
  for table in tables:
162
- if not os.path.isfile(table):
163
- print(" * [Warning] File %s not found" % (table,))
205
+ tbl = self.read_one_table(file_name=table,
206
+ table_name=AGR_USERS,
207
+ sys_name=sys_name)
208
+ if not tbl:
164
209
  continue
165
210
 
166
- tbl = SAPTable(table_name="AGR_USERS",
167
- file_name=table)
168
211
  tbl_content = list(filter(lambda x: len(x["AGR_NAME"]) > 1 and x["AGR_NAME"][0].upper() in ("Z", "Y"), tbl))
169
212
  cur_date = datetime.now()
170
213
  tbl_content = list(filter(lambda x: RolesCfgFile.compare_time_stamp(cur_date, x["FROM_DAT"], x["TO_DAT"]), tbl_content))
@@ -179,10 +222,12 @@ class RolesCfgFile:
179
222
  user = item["UNAME"]
180
223
  if user not in temp_list[mandt][role_name]:
181
224
  temp_list[mandt][role_name].append(user)
225
+
182
226
  return temp_list
183
227
 
184
- @staticmethod
185
- def read_usr02(tables):
228
+
229
+ def read_usr02(self, tables, sys_name=None):
230
+ USR02 = "USR02"
186
231
  if not isinstance(tables,list):
187
232
  new_item = tables
188
233
  tables = list()
@@ -190,32 +235,36 @@ class RolesCfgFile:
190
235
 
191
236
  temp_list = dict()
192
237
  for table in tables:
193
- if not os.path.isfile(table):
194
- print(" * [Warning] File %s not found" % (table,))
238
+ tbl = self.read_one_table(file_name=table,
239
+ table_name=USR02,
240
+ sys_name=sys_name)
241
+ if not tbl:
195
242
  continue
196
- tbl = SAPTable(table_name="USR02",
197
- file_name=table)
243
+
198
244
  temp_list = dict()
199
245
  for item in tbl:
200
246
  mandt = item["MANDT"]
201
247
  if mandt not in temp_list:
202
248
  temp_list[mandt] = dict()
203
249
  user_name = item["BNAME"]
204
- #valid from, valid to
250
+ cur_date = datetime.now()
205
251
  uflag = item["UFLAG"]
206
- active_user = True if (uflag.strip() == "0" or uflag.strip() == "") else False
252
+ validity = RolesCfgFile.compare_time_stamp(cur_date, item["GLTGB"], item["GLTGV"])
253
+ active_user = ((uflag.strip() == "0" or uflag.strip() == "") and validity)
207
254
  ustyp = item["USTYP"]
208
255
  dialog_user = True if (ustyp in ("A", "S")) else False
209
256
  if user_name not in temp_list[mandt]:
210
257
  temp_list[mandt][user_name] = (active_user, dialog_user)
258
+
211
259
  return temp_list
212
260
 
213
261
  @staticmethod
214
262
  def check_auth(line):
215
263
  return line["DELETED"].strip() != "X" and line["OBJECT"].startswith("S_")
216
264
 
217
- @staticmethod
218
- def read_agr_1251(tables):
265
+
266
+ def read_agr_1251(self, tables, sys_name=None):
267
+ AGR_1251 = "AGR_1251"
219
268
  if not isinstance(tables,list):
220
269
  new_item = tables
221
270
  tables = list()
@@ -223,13 +272,12 @@ class RolesCfgFile:
223
272
 
224
273
  temp_list = dict()
225
274
  for table in tables:
226
- if not os.path.isfile(table):
227
- print(" * [Warning] File %s not found" % (table,))
275
+ tbl = self.read_one_table(file_name=table,
276
+ table_name=AGR_1251,
277
+ sys_name=sys_name)
278
+ if not tbl:
228
279
  continue
229
280
 
230
- tbl = SAPTable(table_name="AGR_1251",
231
- file_name=table)
232
-
233
281
  tbl_content = list(filter(lambda x: RolesCfgFile.check_auth(x), tbl))
234
282
  for line in tbl_content:
235
283
  mandt = line["MANDT"]
@@ -245,42 +293,39 @@ class RolesCfgFile:
245
293
 
246
294
  @staticmethod
247
295
  def get_user_info(clientid, role_name, agr_users, usr02):
248
- if agr_users and len(agr_users):
249
- if usr02 and len(usr02):
250
- if role_name in agr_users[clientid]:
251
- user_list = agr_users[clientid][role_name]
252
- if clientid in usr02:
253
- assigned_to_users = 0
254
- assigned_to_active_users = 0
255
- assigned_to_active_dialog_users = 0
256
- assigned_to_active_npa_users = 0
257
- for user in usr02[clientid]:
258
- if user in user_list:
259
- active, dialog = usr02[clientid][user]
260
- assigned_to_users += 1
261
- if active:
262
- assigned_to_active_users += 1
263
- if dialog:
264
- assigned_to_active_dialog_users += 1
265
- else:
266
- assigned_to_active_npa_users += 1
267
- return (
268
- assigned_to_users,
269
- assigned_to_active_users,
270
- assigned_to_active_dialog_users,
271
- assigned_to_active_npa_users)
272
-
273
- else:
274
- return 0
275
- else:
296
+ if agr_users and len(agr_users) and clientid in agr_users:
297
+ if usr02 and len(usr02) and clientid in usr02:
298
+ if role_name not in agr_users[clientid]:
276
299
  return 0
300
+ if len(agr_users[clientid][role_name]) == 0:
301
+ return 0, 0, 0, 0
302
+
303
+ user_list = agr_users[clientid][role_name]
304
+ assigned_to_users = 0
305
+ assigned_to_active_users = 0
306
+ assigned_to_active_dialog_users = 0
307
+ assigned_to_active_npa_users = 0
308
+
309
+ for user in usr02[clientid]:
310
+ if user in user_list:
311
+ active, dialog = usr02[clientid][user]
312
+ assigned_to_users += 1
313
+ if active:
314
+ assigned_to_active_users += 1
315
+ if dialog:
316
+ assigned_to_active_dialog_users += 1
317
+ else:
318
+ assigned_to_active_npa_users += 1
319
+ return (
320
+ assigned_to_users,
321
+ assigned_to_active_users,
322
+ assigned_to_active_dialog_users,
323
+ assigned_to_active_npa_users)
277
324
  else:
278
- if clientid in agr_users:
279
- if role_name in agr_users[clientid]:
280
- return len(agr_users[clientid][role_name])
281
- else:
282
- return 0
325
+ # only one value int
326
+ return len(agr_users[clientid][role_name]) if role_name in agr_users[clientid] else 0
283
327
  else:
328
+ # not defined
284
329
  return
285
330
 
286
331
  @staticmethod
@@ -160,7 +160,7 @@ def wait_5_minutes(seconds=300, every=5):
160
160
  flag = True
161
161
  break
162
162
  if not flag:
163
- print(" * [Warning] The report isn't ready yet. Please try later with offlinesec_get_reports")
163
+ print(" * [WARNING] The report isn't ready yet. Please try later with offlinesec_get_reports")
164
164
  print("")
165
165
 
166
166
 
@@ -25,8 +25,8 @@ def init_args():
25
25
  help="The config file name (SAP systems (ABAP, JAVA, BO, ...) and role tables (AGR_1251, AGR_USERS, USR02) in YAML format)", required=True)
26
26
  parser.add_argument("-v", "--variant", action="store", type=check_variant,
27
27
  help="Check Variant (numeric)", required=False)
28
- parser.add_argument('-na', '--ignore_na_roles', action='store_true', help="Do not exclude notes marked as 'Not Relevant'")
29
- parser.add_argument('-ff', '--ignore_ff', action='store_true', help="Do not exclude notes marked as 'Not Relevant'")
28
+ parser.add_argument('-na', '--ignore_na_roles', action='store_true', help="Exclude roles not assigned to any user")
29
+ parser.add_argument('-ff', '--ignore_ff', action='store_true', help="Exclude FF roles")
30
30
  parser.add_argument('--do-not-send', action='store_true', help="Don't upload data to the server (review first)")
31
31
  parser.parse_args()
32
32
 
@@ -41,6 +41,16 @@ def process_it(args):
41
41
  return
42
42
  cfg = RolesCfgFile(file_name, ignore_na_roles=ignore_na, ignore_ff_roles=ignore_ff)
43
43
  data = cfg.parse()
44
+
45
+ if len(cfg.err_list):
46
+ for err in cfg.err_list:
47
+ print(err)
48
+ if cfg.err_flag:
49
+ return
50
+ resp = input("There are some warning. Do you want to continue?" + " (y/N):").strip().lower()
51
+ if resp is None or resp == "" or resp[0].lower() == "n":
52
+ return
53
+
44
54
  new_data = RolesCfgFile.masking(data)
45
55
  zip_file_name = RolesCfgFile.save_and_zip(new_data)
46
56
 
@@ -63,9 +73,13 @@ def process_it(args):
63
73
  if key1 in args and args[key1] is not None:
64
74
  additional_keys[key1] = args[key1]
65
75
 
76
+ wait = True
77
+ do_not_wait = False
66
78
  offlinesec_client.func.send_file_to_server(file_name=zip_file_name,
67
79
  extras=additional_keys,
68
- url=UPLOAD_URL)
80
+ url=UPLOAD_URL,
81
+ wait=wait,
82
+ do_not_wait=do_not_wait)
69
83
 
70
84
  def main():
71
85
  args = init_args()
@@ -4,9 +4,8 @@ import os
4
4
  import argparse
5
5
  from pathlib import Path
6
6
 
7
- from build.lib.offlinesec_client.masking import ROLE_MASK
8
7
  from offlinesec_client.const import SUBDIR, FILE
9
- from offlinesec_client.masking import Masking, SAPSID_MASK, USER_MASK,HOST_MASK, PATH_MASK, RFCDEST_MASK
8
+ from offlinesec_client.masking import Masking, SAPSID_MASK, USER_MASK,HOST_MASK, PATH_MASK, RFCDEST_MASK, ROLE_MASK
10
9
  import offlinesec_client.func
11
10
  import json
12
11
 
@@ -1,99 +1,8 @@
1
-
2
1
  # -*- coding: utf-8 -*-
3
2
 
4
3
  import os.path
5
4
  import openpyxl
6
-
7
- COLUMN_REPLACEMENT = {
8
- "RFCDES" : {
9
- "RFCDEST": ["RFC Destination", "Destination", "RFC-Destination"],
10
- "RFCTYPE": ["Connection Type", "Verbindungstyp"],
11
- "RFCOPTIONS": ["Options", "Optionen"],
12
- "RFCDOC1": ["Description", "Beschreibung"]
13
- },
14
-
15
- "UST04" : {
16
- "MANDT": ["Client", "Mandant"],
17
- "BNAME": ["User", "Benutzername"],
18
- "PROFIL": ["Profile", "Profil"],
19
- },
20
-
21
- "USR02" : {
22
- "MANDT": ["Client", "Mandant"],
23
- "BNAME": ["User Name", "Benutzername"],
24
- "USTYP": ["User Type", "Benutzertyp"],
25
- "UFLAG": ["User Lock Status", "Status der Benutzersperre"],
26
- "CLASS": ["User Master Maintenance: User Group", "Benutzerstammpflege: Benutzergruppe"],
27
- },
28
-
29
- "CWBNTCUST" : {
30
- "NUMM" : ["Note number", "Hinweisnummer"],
31
- "NTSTATUS" : ["Processing Status", "Proc. Status", "Bearb. Stat."],
32
- "PRSTATUS" : ["Implementation State", "Impl. State", "Einbaustand", "Impl. Status"],
33
- "CWBUSER" : ["User Name", "Benutzername"],
34
- "REQID" : ["Request ID", "Request-Id"],
35
- "IMPL_PROGRESS": ["Implementation Progress", "Impl."]
36
- },
37
- "CWBNTHEAD" : {
38
- "NUMM" : ["Note number", "Hinweisnummer"],
39
- "VERSNO": ["Version"],
40
- "INCOMPLETE": ["TRUE"]
41
- },
42
-
43
- "JAVA_SOFTS" : {
44
- "Version": [],
45
- "Vendor": [],
46
- "Name": [],
47
- "Location": []
48
- },
49
-
50
- "AGR_USERS": {
51
- "MANDT" : ["Client", "Mandant"],
52
- "AGR_NAME": ["Role", "Rolle"],
53
- "UNAME": ["User Name", "Benutzername"],
54
- "FROM_DAT": ["Start date", "Beginndatum"],
55
- "TO_DAT": ["End date", "Enddatum"],
56
-
57
- },
58
- "AGR_1251": {
59
- "MANDT": ["Client", "Mandant"],
60
- "AGR_NAME": ["Role", "Rolle"],
61
- "OBJECT": ["Object", "Objekt"],
62
- "AUTH": ["User Master Maint.: Authorization Name", "Benutzerstammpflege: Berechtigungsname"],
63
- "FIELD": ["Field name", "Feldname"],
64
- "LOW": ["Authorization value", "Berechtigungswert"],
65
- "HIGH": ["Authorization value", "Berechtigungswert"],
66
- "DELETED": ["ID whether object is deleted", "Kennzeichen, ob Objekt gelöscht"]
67
- },
68
-
69
- "RSPARAM": {
70
- "Parameter Name": ["Parametername"],
71
- "User-Defined Value": ["Benutzerdefinierter Wert"],
72
- "System Default Value": ["System-Defaultwert"],
73
- "System Default Value(Unsubstituted Form)": ["System-Defaultwert (Unsubst.Form)"],
74
- "Comment": ["Kommentar"]
75
- }
76
- }
77
-
78
- DATA_REPLACEMENT = {
79
- "CWBNTCUST" : {
80
- "NTSTATUS" : {
81
- "A" : ["Finished","erledigt"],
82
- "N" : ["new", "neu"],
83
- "R" : ["Not Relevant", "nicht relevant"],
84
- "I" : ["In Process", "in Bearbeitung"]
85
- },
86
- "PRSTATUS" : {
87
- "N" : ["Can be implemented", "einbaubar"],
88
- "E" : ["Completely implemented", "vollständig eingebaut"],
89
- "O" : ["Obsolete", "obsolet"],
90
- "-" : ["Cannot be implemented", "nicht einbaubar"],
91
- "" : ["Undefined Implementation State", "unbestimmter Einbauzustand"],
92
- "U" : ["Incompletely implemented", "unvollständig eingebaut"],
93
- "V" : ["Obsolete version implemented", "veraltete Version eingebaut"],
94
- },
95
- }
96
- }
5
+ from offlinesec_client.sap_table_def import COLUMN_REPLACEMENT, DATA_REPLACEMENT
97
6
 
98
7
 
99
8
  class SAP_Table_SE16:
@@ -255,22 +164,25 @@ class XLSX_SE16_Table(SAP_Table_SE16):
255
164
 
256
165
 
257
166
  class SAPTable:
258
- def __init__(self, table_name, file_name):
167
+ def __init__(self, table_name, file_name, sys_name=None):
259
168
  classmap = {
260
169
  "SAP_Table_SE16": SAP_Table_SE16,
261
170
  "HANA_SAP_Table": HANA_SAP_Table,
262
171
  "XLSX_SE16_Table": XLSX_SE16_Table,
263
172
  }
173
+
264
174
  self.table_name = table_name
175
+ self.file_name = file_name
176
+ self.sys_name = sys_name
265
177
 
266
178
  created_object = None
267
- err_list = list()
179
+ self.err_list = list()
268
180
  for class_name in classmap:
269
181
  try:
270
182
  created_object = classmap[class_name](table_name, file_name)
271
183
  self.class_name = class_name
272
184
  except ValueError as err:
273
- err_list.append(class_name + ": " + str(err))
185
+ self.err_list.append(class_name + ": " + str(err))
274
186
  else:
275
187
  break
276
188
 
@@ -278,10 +190,10 @@ class SAPTable:
278
190
  self.tbl = created_object
279
191
  self.columns = self.tbl.columns
280
192
  self.data = self.tbl.data
193
+
281
194
  else:
282
- print(err_list)
283
- raise ValueError("* [WARNING] Unsupported file format: %s. Supported files: HANA STUDIO, SE16-Unconverted, SE16-Spreadsheet" %
284
- (file_name,))
195
+ raise ValueError("Unsupported file format")
196
+
285
197
 
286
198
  def __iter__(self):
287
199
  for row in self.tbl.data:
@@ -289,3 +201,17 @@ class SAPTable:
289
201
  for num, column in enumerate(self.tbl.columns):
290
202
  out_row[column] = row[num]
291
203
  yield out_row
204
+
205
+ def check_columns(self):
206
+ if self.table_name in COLUMN_REPLACEMENT:
207
+ for column in COLUMN_REPLACEMENT[self.table_name]:
208
+ if column not in self.columns:
209
+ if self.sys_name:
210
+ self.err_list.append(" * [WARNING] The %s column not found in the %s file (the %s table in %s)" % (
211
+ column, self.file_name, self.table_name, self.sys_name))
212
+ else:
213
+ self.err_list.append(" * [WARNING] The %s column not found in the %s file (the %s table)" % (
214
+ column, self.file_name, self.table_name))
215
+ return False
216
+
217
+ return True
@@ -0,0 +1,91 @@
1
+ COLUMN_REPLACEMENT = {
2
+ "RFCDES" : {
3
+ "RFCDEST": ["RFC Destination", "Destination", "RFC-Destination"],
4
+ "RFCTYPE": ["Connection Type", "Verbindungstyp"],
5
+ "RFCOPTIONS": ["Options", "Optionen"],
6
+ "RFCDOC1": ["Description", "Beschreibung"]
7
+ },
8
+
9
+ "UST04" : {
10
+ "MANDT": ["Client", "Mandant", "Cl."],
11
+ "BNAME": ["User", "Benutzername"],
12
+ "PROFIL": ["Profile", "Profil"],
13
+ },
14
+
15
+ "USR02" : {
16
+ "MANDT": ["Client", "Mandant", "Cl."],
17
+ "BNAME": ["User Name", "Benutzername"],
18
+ "GLTGB": [],
19
+ "GLTGV": [],
20
+ "USTYP": ["User Type", "Benutzertyp"],
21
+ "UFLAG": ["User Lock Status", "Status der Benutzersperre"],
22
+ "CLASS": ["User Master Maintenance: User Group", "Benutzerstammpflege: Benutzergruppe"],
23
+ },
24
+
25
+ "CWBNTCUST" : {
26
+ "NUMM" : ["Note number", "Hinweisnummer"],
27
+ "NTSTATUS" : ["Processing Status", "Proc. Status", "Bearb. Stat."],
28
+ "PRSTATUS" : ["Implementation State", "Impl. State", "Einbaustand", "Impl. Status"],
29
+ "IMPL_PROGRESS": ["Implementation Progress", "Impl."]
30
+ },
31
+
32
+ "CWBNTHEAD" : {
33
+ "NUMM" : ["Note number", "Hinweisnummer"],
34
+ "VERSNO": ["Version"],
35
+ "INCOMPLETE": ["TRUE"]
36
+ },
37
+
38
+ "JAVA_SOFTS" : {
39
+ "Version": [],
40
+ "Vendor": [],
41
+ "Name": [],
42
+ "Location": []
43
+ },
44
+
45
+ "AGR_USERS": {
46
+ "MANDT" : ["Client", "Mandant", "Cl."],
47
+ "AGR_NAME": ["Role", "Rolle"],
48
+ "UNAME": ["User Name", "Benutzername"],
49
+ "FROM_DAT": ["Start date", "Beginndatum"],
50
+ "TO_DAT": ["End date", "Enddatum"],
51
+
52
+ },
53
+ "AGR_1251": {
54
+ "MANDT": ["Client", "Mandant", "Cl."],
55
+ "AGR_NAME": ["Role", "Rolle"],
56
+ "OBJECT": ["Object", "Objekt"],
57
+ "AUTH": ["User Master Maint.: Authorization Name", "Benutzerstammpflege: Berechtigungsname"],
58
+ "FIELD": ["Field name", "Feldname"],
59
+ "LOW": ["Authorization value", "Berechtigungswert"],
60
+ "HIGH": ["Authorization value", "Berechtigungswert"],
61
+ "DELETED": ["ID whether object is deleted", "Kennzeichen, ob Objekt gelöscht"]
62
+ },
63
+
64
+ "RSPARAM": {
65
+ "Parameter Name": ["Parametername"],
66
+ "User-Defined Value": ["Benutzerdefinierter Wert"],
67
+ "System Default Value": ["System-Defaultwert"],
68
+ "System Default Value(Unsubstituted Form)": ["System-Defaultwert (Unsubst.Form)"],
69
+ "Comment": ["Kommentar"]
70
+ }
71
+ }
72
+
73
+ DATA_REPLACEMENT = {
74
+ "CWBNTCUST" : {
75
+ "NTSTATUS" : {
76
+ "A" : ["Finished","erledigt"],
77
+ "N" : ["new", "neu"],
78
+ "R" : ["Not Relevant", "nicht relevant"],
79
+ "I" : ["In Process", "in Bearbeitung"]
80
+ },
81
+ "PRSTATUS" : {
82
+ "N" : ["Can be implemented", "einbaubar"],
83
+ "E" : ["Completely implemented", "vollständig eingebaut"],
84
+ "O" : ["Obsolete", "obsolet"],
85
+ "-" : ["Cannot be implemented", "nicht einbaubar"],
86
+ "" : ["Undefined Implementation State", "unbestimmter Einbauzustand"],
87
+ "U" : ["Incompletely implemented", "unvollständig eingebaut"],
88
+ "V" : ["Obsolete version implemented", "veraltete Version eingebaut"],
89
+ },
90
+ }
91
+ }
@@ -3,6 +3,7 @@ import yaml
3
3
 
4
4
  ADD_ROOT_DIR_KEYS = ["agr_users", "usr02", "agr_1251"]
5
5
  SAP_SYSTEMS_KEY = "sap_systems"
6
+ ROOT_DIR_KEY = "root_dir"
6
7
  DEF_SYSTEM_NAME = "System %s"
7
8
 
8
9
  class YamlCfgFile:
@@ -11,13 +12,14 @@ class YamlCfgFile:
11
12
  self.file_name = file_name
12
13
 
13
14
  self.check_file()
14
- if not len(self.err_list):
15
+ self.content = None
16
+ if self.check_class_item():
15
17
  self.read_file()
16
18
  self.get_root_dir()
17
19
 
18
20
  def check_file(self):
19
21
  if not self.file_name:
20
- self.err_list.append("YAML filename not defined")
22
+ self.err_list.append(" [ERROR] YAML filename not defined")
21
23
  return
22
24
 
23
25
  if not os.path.isfile(self.file_name):
@@ -35,15 +37,18 @@ class YamlCfgFile:
35
37
  with open(self.file_name, 'r', encoding="utf-8") as f:
36
38
  self.content = yaml.safe_load(f)
37
39
  except Exception as err:
38
- self.err_list.append("* [ERROR] " + str(err))
40
+ self.err_list.append("* [ERROR] Can't read the file %s due to %s" % (self.file_name, str(err)))
41
+ else:
42
+ if "sap_systems" not in self.content:
43
+ self.err_list.append("* [ERROR] The required key 'sap_systems' not found in file %s" % (self.file_name, ))
39
44
 
40
45
  def get_root_dir(self):
41
46
  self.root_dir = None
42
47
  if not self.content:
43
48
  return
44
- key_root_dir = "root_dir"
45
- if key_root_dir in self.content:
46
- self.root_dir = self.content[key_root_dir]
49
+
50
+ if ROOT_DIR_KEY in self.content:
51
+ self.root_dir = self.content[ROOT_DIR_KEY]
47
52
 
48
53
  def __iter__(self):
49
54
  if not self.content:
@@ -23,11 +23,6 @@ class YamlCfgRfc:
23
23
  self.ust04_list = dict()
24
24
  self.usr02_list = dict()
25
25
  self.sid_list = dict()
26
-
27
- if not os.path.isfile(file_name):
28
- self.err_list.append("* [ERROR] File %s not found" % (file_name,))
29
- return
30
-
31
26
  self.file_name = file_name
32
27
 
33
28
  def read_file(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: offlinesec-client
3
- Version: 1.1.45
3
+ Version: 1.1.47
4
4
  Summary: Offline Security Client
5
5
  Home-page: https://offlinesec.com
6
6
  Author: Offline Security
@@ -31,6 +31,7 @@ offlinesec_client/rsparam.py
31
31
  offlinesec_client/sap_gui.py
32
32
  offlinesec_client/sap_system.py
33
33
  offlinesec_client/sap_table.py
34
+ offlinesec_client/sap_table_def.py
34
35
  offlinesec_client/yaml_cfg_read.py
35
36
  offlinesec_client/yaml_cfg_rfc.py
36
37
  offlinesec_client.egg-info/PKG-INFO
@@ -1 +0,0 @@
1
- __version__ = "1.1.45"