roadrecon 1.6.0__py3-none-any.whl → 1.6.2__py3-none-any.whl

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.
@@ -723,8 +723,17 @@ def main(args=None):
723
723
  dburl = 'sqlite:///' + args.database
724
724
  else:
725
725
  dburl = args.database
726
+ try:
727
+ _, tokendata = Authentication.parse_accesstoken(token['accessToken'])
728
+ except KeyError:
729
+ print('No access token found in tokenfile')
730
+ return
731
+ if tokendata['aud'] not in ('https://graph.windows.net', 'https://graph.windows.net/', '00000002-0000-0000-c000-000000000000'):
732
+ print(f"Wrong token audience, got {tokendata['aud']} but expected https://graph.windows.net")
733
+ print("Make sure to request a token with -r https://graph.windows.net")
734
+ return
726
735
 
727
- headers['Authorization'] = '%s %s' % (token['tokenType'], token['accessToken'])
736
+ headers['Authorization'] = f"Bearer {token['accessToken']}"
728
737
 
729
738
  seconds = time.perf_counter()
730
739
  loop = asyncio.get_event_loop()
@@ -129,6 +129,11 @@ class AccessPoliciesPlugin():
129
129
  return self.session.query(ServicePrincipal).filter(ServicePrincipal.objectId.in_(uid)).all()
130
130
  return self.session.query(ServicePrincipal).filter(ServicePrincipal.objectId == uid).first()
131
131
 
132
+ def _get_serviceprincipalrule(self, rule):
133
+ if isinstance(rule, list):
134
+ return [', '.join(rule)]
135
+ return [rule]
136
+
132
137
  def _get_role(self, rid):
133
138
  if isinstance(rid, list):
134
139
  return self.session.query(DirectoryRole).filter(DirectoryRole.roleTemplateId.in_(rid)).all()
@@ -174,6 +179,7 @@ class AccessPoliciesPlugin():
174
179
  'Groups' : self._get_group,
175
180
  'Roles': self._get_role,
176
181
  'ServicePrincipals': self._get_serviceprincipal,
182
+ 'ServicePrincipalFilterRule': self._get_serviceprincipalrule,
177
183
  'GuestsOrExternalUsers': self._translate_guestsexternal
178
184
  }
179
185
  ot = ''
@@ -206,6 +212,9 @@ class AccessPoliciesPlugin():
206
212
  elif ctype == 'GuestsOrExternalUsers':
207
213
  ot += 'Guests or external user types: '
208
214
  ot += ', '.join([escape(uobj) for uobj in objects])
215
+ elif ctype == 'ServicePrincipalFilterRule':
216
+ ot += 'Service Principals matching the following filter: '
217
+ ot += ', '.join([escape(sprule) for sprule in objects])
209
218
  else:
210
219
  raise Exception('Unsupported criterium type: {0}'.format(ctype))
211
220
  else:
@@ -222,18 +231,20 @@ class AccessPoliciesPlugin():
222
231
  ot += ', '.join([escape(action) for action in clist])
223
232
  else:
224
233
  if 'All' in clist:
225
- ot += 'All applications'
234
+ ot += 'All resources'
226
235
  break
227
236
  if 'None' in clist:
228
237
  ot += 'None'
229
238
  break
230
239
  if 'Office365' in clist:
231
- ot += 'All Office 365 applications'
240
+ ot += 'All Office 365 applications '
241
+ if 'MicrosoftAdminPortals' in clist:
242
+ ot += 'All Microsoft Admin Portals '
232
243
  objects = self._get_application(clist)
233
244
  if objects is not None:
234
245
  if len(objects) > 0:
235
246
  if ctype == 'Applications':
236
- ot += 'Applications: '
247
+ ot += 'Resources: '
237
248
  ot += ', '.join([escape(uobj.displayName) for uobj in objects])
238
249
  return ot
239
250
 
@@ -510,9 +521,9 @@ class AccessPoliciesPlugin():
510
521
  print(policy.objectId)
511
522
  detail = json.loads(policy.policyDetail[0])
512
523
  if detail['State'] == 'Reporting':
513
- out['name'] += ' (<strong>Report only</strong>)'
524
+ out['name'] += ' (<i>Report only</i>)'
514
525
  elif detail['State'] != 'Enabled':
515
- out['name'] += ' (<strong>Disabled</strong>)'
526
+ out['name'] += ' (<i>Disabled</i>)'
516
527
  if should_print:
517
528
  pp.pprint(detail)
518
529
  try:
@@ -524,6 +535,7 @@ class AccessPoliciesPlugin():
524
535
  print('Invalid policy - no conditions')
525
536
  continue
526
537
  out['who'] = self._parse_who(conditions)
538
+ out['status'] = escape(detail['State'])
527
539
  out['applications'] = self._parse_application(conditions)
528
540
  out['authflows'] = self._parse_authflows(conditions)
529
541
  out['platforms'] = self._parse_platform(conditions)
@@ -601,7 +613,9 @@ class AccessPoliciesPlugin():
601
613
  for out in ol:
602
614
  table = '<thead><tr><td colspan="2">{0}</td></tr></thead><tbody>'.format(out['name'])
603
615
  table += '<tr><td>Applies to</td><td>{0}</td></tr>'.format(out['who'])
604
- table += '<tr><td>Applications</td><td>{0}</td></tr>'.format(out['applications'])
616
+ if out['status'] != 'Enabled':
617
+ table += '<tr><td>Policy state</td><td>{0}</td></tr>'.format(out['status'])
618
+ table += '<tr><td>Resources</td><td>{0}</td></tr>'.format(out['applications'])
605
619
  if out['platforms'] != '':
606
620
  table += '<tr><td>On platforms</td><td>{0}</td></tr>'.format(out['platforms'])
607
621
  if out['devices'] != '':
@@ -507,9 +507,24 @@ def get_allroles():
507
507
  'scopeNames': snames,
508
508
  'scopeIds': sids
509
509
  }
510
- _, principal = resolve_objectid(assignment.principalId)
510
+ principalType, principal = resolve_objectid(assignment.principalId)
511
511
  aobj['principal'] = principal
512
+
512
513
  roleobj['assignments'].append(aobj)
514
+ if principalType == 'Group':
515
+ group = db.session.get(Group, assignment.principalId)
516
+ for member in group.memberUsers:
517
+ mp = users_schema.dump([member])[0]
518
+ mp['displayName'] = f"{principal['displayName']} member: {mp['displayName']}"
519
+ roleobj['assignments'].append({
520
+ 'type': 'assignment',
521
+ 'scope': assignment.resourceScopes,
522
+ 'scopeTypes': stypes,
523
+ 'scopeNames': snames,
524
+ 'scopeIds': sids,
525
+ 'principal': mp
526
+ })
527
+
513
528
  for assignment in role.eligibleAssignments:
514
529
  stypes, snames, sids = translate_rolescopes(assignment.resourceScopes)
515
530
  aobj = {
@@ -519,9 +534,22 @@ def get_allroles():
519
534
  'scopeNames': snames,
520
535
  'scopeIds': sids
521
536
  }
522
- _, principal = resolve_objectid(assignment.principalId)
537
+ principalType, principal = resolve_objectid(assignment.principalId)
523
538
  aobj['principal'] = principal
524
539
  roleobj['assignments'].append(aobj)
540
+ if principalType == 'Group':
541
+ group = db.session.get(Group, assignment.principalId)
542
+ for member in group.memberUsers:
543
+ mp = users_schema.dump([member])[0]
544
+ mp['displayName'] = f"{principal['displayName']} member: {mp['displayName']}"
545
+ roleobj['assignments'].append({
546
+ 'type': 'eligible',
547
+ 'scope': assignment.resourceScopes,
548
+ 'scopeTypes': stypes,
549
+ 'scopeNames': snames,
550
+ 'scopeIds': sids,
551
+ 'principal': mp
552
+ })
525
553
  allroles.append(roleobj)
526
554
  return jsonify(allroles)
527
555