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.
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/PKG-INFO +1 -1
- offlinesec_client-1.1.47/offlinesec_client/__init__.py +1 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/agr_cfg_read.py +112 -67
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/func.py +1 -1
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_roles_report.py +17 -3
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/resolve_report.py +1 -2
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/sap_table.py +24 -98
- offlinesec_client-1.1.47/offlinesec_client/sap_table_def.py +91 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/yaml_cfg_read.py +11 -6
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/yaml_cfg_rfc.py +0 -5
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/PKG-INFO +1 -1
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/SOURCES.txt +1 -0
- offlinesec_client-1.1.45/offlinesec_client/__init__.py +0 -1
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/README.md +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/__main__.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/abap_system.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/agr_1251.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/api_sec_notes.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/bo_system.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/config.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/const.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/cwbntcust.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/exclude_params.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/get_reports.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/java_system.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/masking.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/multi_systems.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_abap_review.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_bo_notes.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_java_notes.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_notes_report.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_param_report.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_patch_day.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_rfc_report.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/req_sec_notes.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/rfcdes.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/rsparam.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/sap_gui.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client/sap_system.py +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/dependency_links.txt +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/entry_points.txt +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/requires.txt +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/top_level.txt +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/setup.cfg +0 -0
- {offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/setup.py +0 -0
|
@@ -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
|
-
|
|
32
|
+
self.err_list.extend(yaml_file.err_list)
|
|
30
33
|
self.err_flag = True
|
|
31
34
|
return
|
|
32
35
|
|
|
33
|
-
if
|
|
34
|
-
if isinstance(yaml_file.content[
|
|
35
|
-
self.ff_masks = yaml_file.content[
|
|
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[
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
154
|
-
def
|
|
155
|
-
if not
|
|
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
|
-
|
|
163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
194
|
-
|
|
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
|
-
|
|
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
|
-
|
|
250
|
+
cur_date = datetime.now()
|
|
205
251
|
uflag = item["UFLAG"]
|
|
206
|
-
|
|
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
|
-
|
|
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
|
-
|
|
227
|
-
|
|
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
|
-
|
|
279
|
-
|
|
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(" * [
|
|
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="
|
|
29
|
-
parser.add_argument('-ff', '--ignore_ff', action='store_true', help="
|
|
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
|
-
|
|
283
|
-
|
|
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
|
-
|
|
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] "
|
|
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
|
-
|
|
45
|
-
if
|
|
46
|
-
self.root_dir = self.content[
|
|
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):
|
{offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/SOURCES.txt
RENAMED
|
@@ -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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/requires.txt
RENAMED
|
File without changes
|
{offlinesec_client-1.1.45 → offlinesec_client-1.1.47}/offlinesec_client.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|