gam7 7.18.4__py3-none-any.whl → 7.18.5__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.
gam/__init__.py CHANGED
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
25
25
  """
26
26
 
27
27
  __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
28
- __version__ = '7.18.04'
28
+ __version__ = '7.18.05'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -3952,14 +3952,20 @@ def SetGlobalVariables():
3952
3952
  if checkArgumentPresent(Cmd.SELECT_CMD):
3953
3953
  sectionName = _selectSection()
3954
3954
  GM.Globals[GM.SECTION] = sectionName # Save section for inner gams
3955
- while Cmd.ArgumentsRemaining():
3956
- if checkArgumentPresent('save'):
3957
- GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.SECTION, sectionName)
3958
- _writeGamCfgFile(GM.Globals[GM.PARSER], GM.Globals[GM.GAM_CFG_FILE], Act.SAVE)
3959
- elif checkArgumentPresent('verify'):
3960
- _verifyValues(sectionName, inputFilterSectionName, outputFilterSectionName)
3961
- else:
3962
- break
3955
+ # If command line is simply: gam select <SectionName>
3956
+ # assume save
3957
+ if not Cmd.ArgumentsRemaining():
3958
+ GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.SECTION, sectionName)
3959
+ _writeGamCfgFile(GM.Globals[GM.PARSER], GM.Globals[GM.GAM_CFG_FILE], Act.SAVE)
3960
+ else:
3961
+ while Cmd.ArgumentsRemaining():
3962
+ if checkArgumentPresent('save'):
3963
+ GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.SECTION, sectionName)
3964
+ _writeGamCfgFile(GM.Globals[GM.PARSER], GM.Globals[GM.GAM_CFG_FILE], Act.SAVE)
3965
+ elif checkArgumentPresent('verify'):
3966
+ _verifyValues(sectionName, inputFilterSectionName, outputFilterSectionName)
3967
+ else:
3968
+ break
3963
3969
  GM.Globals[GM.GAM_CFG_SECTION_NAME] = sectionName
3964
3970
  # showsections
3965
3971
  if checkArgumentPresent(Cmd.SHOWSECTIONS_CMD):
@@ -11482,13 +11488,14 @@ def _createOauth2serviceJSON(httpObj, projectInfo, svcAcctInfo, create_key=True)
11482
11488
  iam = getAPIService(API.IAM, httpObj)
11483
11489
  try:
11484
11490
  service_account = callGAPI(iam.projects().serviceAccounts(), 'create',
11485
- throwReasons=[GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED, GAPI.ALREADY_EXISTS],
11491
+ throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.NOT_FOUND,
11492
+ GAPI.PERMISSION_DENIED, GAPI.ALREADY_EXISTS],
11486
11493
  name=f'projects/{projectInfo["projectId"]}',
11487
11494
  body={'accountId': svcAcctInfo['name'],
11488
11495
  'serviceAccount': {'displayName': svcAcctInfo['displayName'],
11489
11496
  'description': svcAcctInfo['description']}})
11490
11497
  entityActionPerformed([Ent.PROJECT, projectInfo['projectId'], Ent.SVCACCT, service_account['name'].rsplit('/', 1)[-1]])
11491
- except (GAPI.notFound, GAPI.permissionDenied) as e:
11498
+ except (GAPI.failedPrecondition, GAPI.notFound, GAPI.permissionDenied) as e:
11492
11499
  entityActionFailedWarning([Ent.PROJECT, projectInfo['projectId']], str(e))
11493
11500
  return False
11494
11501
  except GAPI.alreadyExists as e:
@@ -44894,21 +44901,39 @@ def waitForMailbox(entityList):
44894
44901
  Ind.Decrement()
44895
44902
 
44896
44903
  def getUserLicenses(lic, user, skus):
44897
- def _callbackGetLicense(_, response, exception):
44904
+ def _callbackGetLicense(request_id, response, exception):
44898
44905
  if exception is None:
44899
44906
  if response and 'skuId' in response:
44900
44907
  licenses.append(response['skuId'])
44908
+ del(sku_calls[request_id])
44909
+ else:
44910
+ if exception.reason == not_found:
44911
+ del(sku_calls[request_id])
44901
44912
 
44913
+ not_found = 'User does not have a license for specified sku and product'
44902
44914
  licenses = []
44903
44915
  svcargs = dict([('userId', user['primaryEmail']), ('productId', None), ('skuId', None), ('fields', 'skuId')]+GM.Globals[GM.EXTRA_ARGS_LIST])
44904
44916
  method = getattr(lic.licenseAssignments(), 'get')
44905
44917
  dbatch = lic.new_batch_http_request(callback=_callbackGetLicense)
44918
+ sku_calls = {}
44906
44919
  for sku in skus:
44907
44920
  svcparms = svcargs.copy()
44908
44921
  svcparms['productId'] = sku[0]
44909
- svcparms['skuId'] = sku[1]
44910
- dbatch.add(method(**svcparms))
44911
- dbatch.execute()
44922
+ sku_id = sku[1]
44923
+ svcparms['skuId'] = sku_id
44924
+ sku_calls[sku_id] = method(**svcparms)
44925
+ try_count = 0
44926
+ while sku_calls:
44927
+ try_count += 1
44928
+ dbatch = lic.new_batch_http_request(callback=_callbackGetLicense)
44929
+ for sku_id, sku_call in sku_calls.items():
44930
+ dbatch.add(sku_call, request_id=sku_id)
44931
+ dbatch.execute()
44932
+ if sku_calls:
44933
+ if try_count >= 5:
44934
+ # give up and return what we have
44935
+ return licenses
44936
+ time.sleep(5)
44912
44937
  return licenses
44913
44938
 
44914
44939
  USER_NAME_PROPERTY_PRINT_ORDER = [
@@ -46393,9 +46418,30 @@ def checkCIUserIsInvitable(users):
46393
46418
  return
46394
46419
  csvPF.writeCSVfile('Invitable Users')
46395
46420
 
46421
+ INBOUNDSSO_INPUT_MODE_CHOICE_MAP = {
46422
+ 'saml': 'saml',
46423
+ 'samlsso': 'saml',
46424
+ 'oidc': 'oidc',
46425
+ 'oidcsso': 'oidc',
46426
+ }
46427
+
46428
+ INBOUNDSSO_OUTPUT_MODE_CHOICE_MAP = {
46429
+ 'all': 'all',
46430
+ 'saml': 'saml',
46431
+ 'samlsso': 'saml',
46432
+ 'oidc': 'oidc',
46433
+ 'oidcsso': 'oidc',
46434
+ }
46435
+
46436
+ INBOUNDSSO_ALL_SAML = {'all', 'saml'}
46437
+ INBOUNDSSO_ALL_OIDC = {'all', 'oidc'}
46438
+
46396
46439
  INBOUNDSSO_MODE_CHOICE_MAP = {
46397
46440
  'ssooff': 'SSO_OFF',
46441
+ 'saml': 'SAML_SSO',
46398
46442
  'samlsso': 'SAML_SSO',
46443
+ 'oidc': 'OIDC_SSO',
46444
+ 'oidcsso': 'OIDC_SSO',
46399
46445
  'domainwidesamlifenabled': 'DOMAIN_WIDE_SAML_IF_ENABLED'
46400
46446
  }
46401
46447
 
@@ -46405,29 +46451,49 @@ def getCIOrgunitID(cd, orgunit):
46405
46451
  ou_id = ou_id[3:]
46406
46452
  return f'orgUnits/{ou_id}'
46407
46453
 
46408
- def _getInboundSSOProfiles(ci):
46454
+ def _getInboundSSOProfiles(ci, mode):
46409
46455
  customer = normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID])
46410
- try:
46411
- return callGAPIpages(ci.inboundSamlSsoProfiles(), 'list', 'inboundSamlSsoProfiles',
46412
- throwReasons=GAPI.CISSO_LIST_THROW_REASONS,
46413
- retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46414
- bailOnInternalError=True,
46415
- filter=f'customer=="{customer}"')
46416
- except (GAPI.notFound, GAPI.domainNotFound, GAPI.domainCannotUseApis,
46417
- GAPI.forbidden, GAPI.badRequest, GAPI.invalid,
46418
- GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46419
- entityActionFailedWarning([Ent.INBOUND_SSO_PROFILE, customer], str(e))
46420
- return []
46456
+ profiles = []
46457
+ if mode in INBOUNDSSO_ALL_SAML:
46458
+ try:
46459
+ profiles.extend(callGAPIpages(ci.inboundSamlSsoProfiles(), 'list', 'inboundSamlSsoProfiles',
46460
+ throwReasons=GAPI.CISSO_LIST_THROW_REASONS,
46461
+ retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46462
+ bailOnInternalError=True,
46463
+ filter=f'customer=="{customer}"'))
46464
+ except (GAPI.notFound, GAPI.domainNotFound, GAPI.domainCannotUseApis,
46465
+ GAPI.forbidden, GAPI.badRequest, GAPI.invalid,
46466
+ GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46467
+ entityActionFailedWarning([Ent.INBOUND_SSO_PROFILE, customer], str(e))
46468
+ if mode in INBOUNDSSO_ALL_OIDC:
46469
+ try:
46470
+ profiles.extend(callGAPIpages(ci.inboundOidcSsoProfiles(), 'list', 'inboundOidcSsoProfiles',
46471
+ throwReasons=GAPI.CISSO_LIST_THROW_REASONS,
46472
+ retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46473
+ bailOnInternalError=True,
46474
+ filter=f'customer=="{customer}"'))
46475
+ except (GAPI.notFound, GAPI.domainNotFound, GAPI.domainCannotUseApis,
46476
+ GAPI.forbidden, GAPI.badRequest, GAPI.invalid,
46477
+ GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46478
+ entityActionFailedWarning([Ent.INBOUND_SSO_PROFILE, customer], str(e))
46479
+ return profiles
46421
46480
 
46422
- def _convertInboundSSOProfileDisplaynameToName(ci=None, displayName=''):
46481
+ def _convertInboundSSOProfileDisplaynameToName(ci, mode, displayName='',
46482
+ entityType=Ent.INBOUND_SSO_PROFILE):
46423
46483
  if displayName.lower().startswith('id:') or displayName.lower().startswith('uid:'):
46424
46484
  displayName = displayName.split(':', 1)[1]
46425
- if not displayName.startswith('inboundSamlSsoProfiles/'):
46426
- displayName = f'inboundSamlSsoProfiles/{displayName}'
46485
+ if mode == 'all':
46486
+ if not (displayName.startswith('inboundSamlSsoProfiles/') and
46487
+ displayName.startswith('inboundOidcSsoProfiles/')):
46488
+ displayName = f'inboundSamlSsoProfiles/{displayName}'
46489
+ elif mode == 'saml':
46490
+ if not displayName.startswith('inboundSamlSsoProfiles/'):
46491
+ displayName = f'inboundSamlSsoProfiles/{displayName}'
46492
+ else:
46493
+ if not displayName.startswith('inboundOidcSsoProfiles/'):
46494
+ displayName = f'inboundOidcSsoProfiles/{displayName}'
46427
46495
  return displayName
46428
- if not ci:
46429
- ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
46430
- profiles = _getInboundSSOProfiles(ci)
46496
+ profiles = _getInboundSSOProfiles(ci, mode)
46431
46497
  matches = []
46432
46498
  for profile in profiles:
46433
46499
  if displayName.lower() == profile.get('displayName', '').lower():
@@ -46435,30 +46501,50 @@ def _convertInboundSSOProfileDisplaynameToName(ci=None, displayName=''):
46435
46501
  if len(matches) == 1:
46436
46502
  return matches[0]['name']
46437
46503
  if len(matches) == 0:
46438
- usageErrorExit(Msg.NO_SSO_PROFILE_MATCHES.format(displayName))
46439
- errMsg = Msg.MULTIPLE_SSO_PROFILES_MATCH.format(displayName)
46440
- for m in matches:
46441
- errMsg += f' {m["name"]} {m["displayName"]}\n'
46442
- usageErrorExit(errMsg)
46504
+ errMsg = Msg.NO_SSO_PROFILE_MATCHES.format(displayName)
46505
+ else:
46506
+ errMsg = Msg.MULTIPLE_SSO_PROFILES_MATCH.format(displayName)
46507
+ for m in matches:
46508
+ errMsg += f' {m["name"]} {m["displayName"]}\n'
46509
+ entityActionFailedWarning([entityType, None], errMsg)
46510
+ return None
46443
46511
 
46444
- def _getInboundSSOProfileArguments(body):
46512
+ def _getInboundSSOProfileArguments(body, mode):
46445
46513
  returnNameOnly = False
46446
- while Cmd.ArgumentsRemaining():
46447
- myarg = getArgument()
46448
- if myarg == 'name':
46449
- body['displayName'] = getString(Cmd.OB_STRING)
46450
- elif myarg == 'entityid':
46451
- body.setdefault('idpConfig', {})['entityId'] = getString(Cmd.OB_STRING)
46452
- elif myarg == 'loginurl':
46453
- body.setdefault('idpConfig', {})['singleSignOnServiceUri'] = getString(Cmd.OB_STRING)
46454
- elif myarg == 'logouturl':
46455
- body.setdefault('idpConfig', {})['logoutRedirectUri'] = getString(Cmd.OB_STRING)
46456
- elif myarg == 'changepasswordurl':
46457
- body.setdefault('idpConfig', {})['changePasswordUri'] = getString(Cmd.OB_STRING)
46458
- elif myarg == 'returnnameonly':
46459
- returnNameOnly = True
46460
- else:
46461
- unknownArgumentExit()
46514
+ if mode == 'saml':
46515
+ while Cmd.ArgumentsRemaining():
46516
+ myarg = getArgument()
46517
+ if myarg == 'name':
46518
+ body['displayName'] = getString(Cmd.OB_STRING)
46519
+ elif myarg == 'entityid':
46520
+ body.setdefault('idpConfig', {})['entityId'] = getString(Cmd.OB_STRING)
46521
+ elif myarg == 'loginurl':
46522
+ body.setdefault('idpConfig', {})['singleSignOnServiceUri'] = getString(Cmd.OB_STRING)
46523
+ elif myarg == 'logouturl':
46524
+ body.setdefault('idpConfig', {})['logoutRedirectUri'] = getString(Cmd.OB_STRING)
46525
+ elif myarg == 'changepasswordurl':
46526
+ body.setdefault('idpConfig', {})['changePasswordUri'] = getString(Cmd.OB_STRING)
46527
+ elif myarg == 'returnnameonly':
46528
+ returnNameOnly = True
46529
+ else:
46530
+ unknownArgumentExit()
46531
+ else:
46532
+ while Cmd.ArgumentsRemaining():
46533
+ myarg = getArgument()
46534
+ if myarg == 'name':
46535
+ body['displayName'] = getString(Cmd.OB_STRING)
46536
+ elif myarg == 'issueruri':
46537
+ body.setdefault('idpConfig', {})['issuerUri'] = getString(Cmd.OB_STRING)
46538
+ elif myarg == 'changepasswordurl':
46539
+ body.setdefault('idpConfig', {})['changePasswordUri'] = getString(Cmd.OB_STRING)
46540
+ elif myarg == 'clientid':
46541
+ body.setdefault('rpConfig', {})['clientId'] = getString(Cmd.OB_STRING)
46542
+ elif myarg == 'clientsecret':
46543
+ body.setdefault('rpConfig', {})['clientSecret'] = getString(Cmd.OB_STRING)
46544
+ elif myarg == 'returnnameonly':
46545
+ returnNameOnly = True
46546
+ else:
46547
+ unknownArgumentExit()
46462
46548
  return (returnNameOnly, body)
46463
46549
 
46464
46550
  def _showInboundSSOProfile(profile, FJQC, i=0, count=0):
@@ -46489,18 +46575,24 @@ def _processInboundSSOProfileResult(result, returnNameOnly, kvlist, function):
46489
46575
  else:
46490
46576
  writeStdout('inProgress\n')
46491
46577
 
46492
- # gam create inboundssoprofile [name <SSOProfileName>]
46578
+ def _getInboundSSOModeService(ci):
46579
+ mode = getChoice(INBOUNDSSO_INPUT_MODE_CHOICE_MAP, defaultChoice='saml', mapChoice=True)
46580
+ service = ci.inboundSamlSsoProfiles() if mode == 'saml' else ci.inboundOidcSsoProfiles()
46581
+ return (mode, service)
46582
+
46583
+ # gam create inboundssoprofile [saml|oidc] [name <SSOProfileName>]
46493
46584
  # [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>]
46494
46585
  # [returnnameonly]
46495
46586
  def doCreateInboundSSOProfile():
46496
46587
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
46588
+ mode, service = _getInboundSSOModeService(ci)
46497
46589
  body = {'customer': normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID]),
46498
46590
  'displayName': 'SSO Profile'
46499
46591
  }
46500
- returnNameOnly, body = _getInboundSSOProfileArguments(body)
46592
+ returnNameOnly, body = _getInboundSSOProfileArguments(body, mode)
46501
46593
  kvlist = [Ent.INBOUND_SSO_PROFILE, body['displayName']]
46502
46594
  try:
46503
- result = callGAPI(ci.inboundSamlSsoProfiles(), 'create',
46595
+ result = callGAPI(service, 'create',
46504
46596
  throwReasons=GAPI.CISSO_CREATE_THROW_REASONS,
46505
46597
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46506
46598
  bailOnInternalError=True,
@@ -46511,16 +46603,19 @@ def doCreateInboundSSOProfile():
46511
46603
  GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46512
46604
  entityActionFailedWarning(kvlist, str(e))
46513
46605
 
46514
- # gam update inboundssoprofile <SSOProfileItem>
46606
+ # gam update inboundssoprofile [saml|oidc] <SSOProfileItem>
46515
46607
  # [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>]
46516
46608
  # [returnnameonly]
46517
46609
  def doUpdateInboundSSOProfile():
46518
46610
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
46519
- name = _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING))
46520
- returnNameOnly, body = _getInboundSSOProfileArguments({})
46611
+ mode, service = _getInboundSSOModeService(ci)
46612
+ name = _convertInboundSSOProfileDisplaynameToName(ci, mode, getString(Cmd.OB_STRING))
46613
+ if not name:
46614
+ return
46615
+ returnNameOnly, body = _getInboundSSOProfileArguments({}, mode)
46521
46616
  kvlist = [Ent.INBOUND_SSO_PROFILE, name]
46522
46617
  try:
46523
- result = callGAPI(ci.inboundSamlSsoProfiles(), 'patch',
46618
+ result = callGAPI(service, 'patch',
46524
46619
  throwReasons=GAPI.CISSO_UPDATE_THROW_REASONS,
46525
46620
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46526
46621
  bailOnInternalError=True,
@@ -46533,14 +46628,17 @@ def doUpdateInboundSSOProfile():
46533
46628
  GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46534
46629
  entityActionFailedWarning(kvlist, str(e))
46535
46630
 
46536
- # gam delete inboundssoprofile <SSOProfileItem>
46631
+ # gam delete inboundssoprofile [saml|oidc] <SSOProfileItem>
46537
46632
  def doDeleteInboundSSOProfile():
46538
46633
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
46539
- name = _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING))
46634
+ mode, service = _getInboundSSOModeService(ci)
46635
+ name = _convertInboundSSOProfileDisplaynameToName(ci, mode, getString(Cmd.OB_STRING))
46636
+ if not name:
46637
+ return
46540
46638
  checkForExtraneousArguments()
46541
46639
  kvlist = [Ent.INBOUND_SSO_PROFILE, name]
46542
46640
  try:
46543
- result = callGAPI(ci.inboundSamlSsoProfiles(), 'delete',
46641
+ result = callGAPI(service, 'delete',
46544
46642
  throwReasons=GAPI.CISSO_UPDATE_THROW_REASONS,
46545
46643
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46546
46644
  bailOnInternalError=True,
@@ -46553,33 +46651,54 @@ def doDeleteInboundSSOProfile():
46553
46651
  GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46554
46652
  entityActionFailedWarning(kvlist, str(e))
46555
46653
 
46556
- def _getInboundSSOProfile(ci, name):
46654
+ def _getInboundSSOProfileByName(ci, mode, name):
46655
+ notFound = False
46557
46656
  kvlist = [Ent.INBOUND_SSO_PROFILE, name]
46558
- try:
46559
- return callGAPI(ci.inboundSamlSsoProfiles(), 'get',
46560
- throwReasons=GAPI.CISSO_GET_THROW_REASONS,
46561
- retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46562
- bailOnInternalError=True,
46563
- name=name)
46564
- except GAPI.notFound:
46657
+ if mode in INBOUNDSSO_ALL_SAML:
46658
+ try:
46659
+ return callGAPI(ci.inboundSamlSsoProfiles(), 'get',
46660
+ throwReasons=GAPI.CISSO_GET_THROW_REASONS,
46661
+ retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46662
+ bailOnInternalError=True,
46663
+ name=name)
46664
+ except GAPI.notFound:
46665
+ notFound = True
46666
+ except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
46667
+ GAPI.badRequest, GAPI.invalid, GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46668
+ entityActionFailedWarning(kvlist, str(e))
46669
+ if mode in INBOUNDSSO_ALL_OIDC:
46670
+ try:
46671
+ return callGAPI(ci.inboundOidcSsoProfiles(), 'get',
46672
+ throwReasons=GAPI.CISSO_GET_THROW_REASONS,
46673
+ retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
46674
+ bailOnInternalError=True,
46675
+ name=name)
46676
+ except GAPI.notFound:
46677
+ notFound = True
46678
+ except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
46679
+ GAPI.badRequest, GAPI.invalid, GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46680
+ entityActionFailedWarning(kvlist, str(e))
46681
+ if notFound:
46565
46682
  entityActionFailedWarning(kvlist, Msg.DOES_NOT_EXIST)
46566
- except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
46567
- GAPI.badRequest, GAPI.invalid, GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46568
- entityActionFailedWarning(kvlist, str(e))
46569
46683
  return None
46570
46684
 
46571
- # gam info inboundssoprofile <SSOProfileItem> [formatjson]
46685
+ # gam info inboundssoprofile [all|saml|oidc] <SSOProfileItem> [formatjson]
46572
46686
  def doInfoInboundSSOProfile():
46573
46687
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
46574
- name = _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING))
46688
+ mode = getChoice(INBOUNDSSO_OUTPUT_MODE_CHOICE_MAP, defaultChoice='all', mapChoice=True)
46689
+ name = getString(Cmd.OB_STRING)
46575
46690
  FJQC = FormatJSONQuoteChar(formatJSONOnly=True)
46576
- profile = _getInboundSSOProfile(ci, name)
46691
+ name = _convertInboundSSOProfileDisplaynameToName(ci, mode, name)
46692
+ if not name:
46693
+ return
46694
+ mode = 'saml' if name.startswith('inboundSamlSsoProfiles/') else 'oidc'
46695
+ profile = _getInboundSSOProfileByName(ci, mode, name)
46577
46696
  if profile:
46578
46697
  _showInboundSSOProfile(profile, FJQC)
46579
46698
 
46580
- # gam show inboundssoprofile
46699
+ # gam show inboundssoprofile [all|saml|oidc]
46581
46700
  # [formatjson]
46582
- # gam print inboundssoprofile [todrive <ToDriveAttribute>*]
46701
+ # gam print inboundssoprofile [all|saml|oidc] [todrive <ToDriveAttribute>*]
46583
46702
  # [[formatjson [quotechar <Character>]]
46584
46703
  def doPrintShowInboundSSOProfiles():
46585
46704
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
@@ -46587,6 +46706,7 @@ def doPrintShowInboundSSOProfiles():
46587
46706
  csvPF = CSVPrintFile(['name']) if Act.csvFormat() else None
46588
46707
  FJQC = FormatJSONQuoteChar(csvPF)
46589
46708
  cfilter = f'customer=="{customer}"'
46709
+ mode = getChoice(INBOUNDSSO_OUTPUT_MODE_CHOICE_MAP, defaultChoice='all', mapChoice=True)
46590
46710
  while Cmd.ArgumentsRemaining():
46591
46711
  myarg = getArgument()
46592
46712
  if csvPF and myarg == 'todrive':
@@ -46595,7 +46715,7 @@ def doPrintShowInboundSSOProfiles():
46595
46715
  FJQC.GetFormatJSONQuoteChar(myarg, True)
46596
46716
  if csvPF:
46597
46717
  printGettingAllAccountEntities(Ent.INBOUND_SSO_PROFILE, cfilter)
46598
- profiles = _getInboundSSOProfiles(ci)
46718
+ profiles = _getInboundSSOProfiles(ci, mode)
46599
46719
  if not csvPF:
46600
46720
  count = len(profiles)
46601
46721
  if not FJQC.formatJSON:
@@ -46665,6 +46785,7 @@ def _processInboundSSOCredentialsResult(result, kvlist, function):
46665
46785
  # (pemfile <FileName>)|(generatekey [keysize 1024|2048|4096]) [replaceolddest]
46666
46786
  def doCreateInboundSSOCredential():
46667
46787
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
46788
+ mode = 'saml'
46668
46789
  profile = None
46669
46790
  generateKey = replaceOldest = False
46670
46791
  keySize = 2048
@@ -46672,7 +46793,11 @@ def doCreateInboundSSOCredential():
46672
46793
  while Cmd.ArgumentsRemaining():
46673
46794
  myarg = getArgument()
46674
46795
  if myarg == 'profile':
46675
- profile = _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING))
46796
+ profile = _convertInboundSSOProfileDisplaynameToName(ci, mode,
46797
+ getString(Cmd.OB_STRING),
46798
+ Ent.INBOUND_SSO_CREDENTIALS)
46799
+ if not profile:
46800
+ return
46676
46801
  elif myarg == 'pemfile':
46677
46802
  pemData = readFile(getString(Cmd.OB_FILE_NAME))
46678
46803
  elif myarg == 'generatekey':
@@ -46776,15 +46901,24 @@ def doPrintShowInboundSSOCredentials():
46776
46901
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
46777
46902
  csvPF = CSVPrintFile(['name']) if Act.csvFormat() else None
46778
46903
  FJQC = FormatJSONQuoteChar(csvPF)
46904
+ mode = 'saml'
46779
46905
  profiles = []
46780
46906
  while Cmd.ArgumentsRemaining():
46781
46907
  myarg = getArgument()
46782
46908
  if myarg in {'profile', 'profiles'}:
46783
- profiles = [_convertInboundSSOProfileDisplaynameToName(ci, profile) for profile in getString(Cmd.OB_STRING_LIST).split(',')]
46909
+ errors = 0
46910
+ for profile in getEntityList(Cmd.OB_STRING_LIST, shlexSplit=True):
46911
+ name = _convertInboundSSOProfileDisplaynameToName(ci, mode, profile, Ent.INBOUND_SSO_CREDENTIALS)
46912
+ if name:
46913
+ profiles.append(name)
46914
+ else:
46915
+ errors += 1
46916
+ if errors:
46917
+ return
46784
46918
  else:
46785
46919
  FJQC.GetFormatJSONQuoteChar(myarg, True)
46786
46920
  if not profiles:
46787
- profiles = [p['name'] for p in _getInboundSSOProfiles(ci)]
46921
+ profiles = [p['name'] for p in _getInboundSSOProfiles(ci, mode)]
46788
46922
  count = len(profiles)
46789
46923
  i = 0
46790
46924
  for profile in profiles:
@@ -46877,6 +47011,7 @@ def _getInboundSSOAssignmentByTarget(ci, cd, target):
46877
47011
  usageErrorExit(Msg.NO_SSO_PROFILE_ASSIGNED.format(targetType, target))
46878
47012
 
46879
47013
  def _getInboundSSOAssignmentArguments(ci, cd, body):
47014
+ mode = None
46880
47015
  rank = 0
46881
47016
  while Cmd.ArgumentsRemaining():
46882
47017
  myarg = getArgument()
@@ -46884,9 +47019,19 @@ def _getInboundSSOAssignmentArguments(ci, cd, body):
46884
47019
  rank = getInteger(minVal=1)
46885
47020
  elif myarg == 'mode':
46886
47021
  body['ssoMode'] = getChoice(INBOUNDSSO_MODE_CHOICE_MAP, mapChoice=True)
46887
- elif myarg == 'profile':
46888
- body['samlSsoInfo'] = {'inboundSamlSsoProfile':
46889
- _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING))}
47022
+ if body['ssoMode'] == 'SAML_SSO':
47023
+ mode = 'saml'
47024
+ profile = 'inboundSamlSsoProfile'
47025
+ elif body['ssoMode'] == 'OIDC_SSO':
47026
+ mode = 'oidc'
47027
+ profile = 'inboundOidcSsoProfile'
47028
+ elif mode and myarg == 'profile':
47029
+ name = _convertInboundSSOProfileDisplaynameToName(ci, mode,
47030
+ getString(Cmd.OB_STRING),
47031
+ Ent.INBOUND_SSO_ASSIGNMENT)
47032
+ if not name:
47033
+ return None
47034
+ body['samlSsoInfo'] = {profile: name}
46890
47035
  elif myarg == 'neverredirect':
46891
47036
  body['signInBehavior'] = {'redirectCondition': 'NEVER'}
46892
47037
  elif myarg == 'group':
@@ -46897,7 +47042,7 @@ def _getInboundSSOAssignmentArguments(ci, cd, body):
46897
47042
  unknownArgumentExit()
46898
47043
  if 'ssoMode' not in body:
46899
47044
  missingArgumentExit('mode')
46900
- if body['ssoMode'] == 'SAML_SSO' and 'samlSsoInfo' not in body:
47045
+ if mode and 'samlSsoInfo' not in body:
46901
47046
  missingArgumentExit('profile')
46902
47047
  if 'targetGroup' in body:
46903
47048
  if 'targetOrgUnit' in body:
@@ -46935,13 +47080,17 @@ def _processInboundSSOAssignmentResult(result, kvlist, ci, cd, function):
46935
47080
  else:
46936
47081
  entityActionPerformedMessage(kvlist, Msg.ACTION_IN_PROGRESS.format(f'{function} inboundssoassignment'))
46937
47082
 
46938
- # gam create inboundssoassignment (group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)
46939
- # (mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled) [neverredirect]
47083
+ # gam create inboundssoassignment
47084
+ # (group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)
47085
+ # (mode sso_off)|(mode saml_sso profile <SSOProfileItem>)|(mode oidc_sso profile <SSOProfileName>}|(mode domain_wide_saml_if_enabled)
47086
+ # [neverredirect]
46940
47087
  def doCreateInboundSSOAssignment():
46941
47088
  cd = buildGAPIObject(API.DIRECTORY)
46942
47089
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
46943
47090
  body = {'customer': normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID])}
46944
47091
  body = _getInboundSSOAssignmentArguments(ci, cd, body)
47092
+ if not body:
47093
+ return
46945
47094
  kvlist = [Ent.INBOUND_SSO_ASSIGNMENT, body['customer']]
46946
47095
  try:
46947
47096
  result = callGAPI(ci.inboundSsoAssignments(), 'create',
@@ -46955,8 +47104,10 @@ def doCreateInboundSSOAssignment():
46955
47104
  GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
46956
47105
  entityActionFailedWarning(kvlist, str(e))
46957
47106
 
46958
- # gam update inboundssoassignment [(group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)]
46959
- # [(mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled)] [neverredirect]
47107
+ # gam update inboundssoassignment <SSOAssignmentName>
47108
+ # [(group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)]
47109
+ # (mode sso_off)|(mode saml_sso profile <SSOProfileItem>)|(mode oidc_sso profile <SSOProfileName>}|(mode domain_wide_saml_if_enabled)
47110
+ # [neverredirect]
46960
47111
  def doUpdateInboundSSOAssignment():
46961
47112
  cd = buildGAPIObject(API.DIRECTORY)
46962
47113
  ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
@@ -47013,14 +47164,20 @@ def doInfoInboundSSOAssignment():
47013
47164
  return
47014
47165
  name = assignment.get('samlSsoInfo', {}).get('inboundSamlSsoProfile')
47015
47166
  if name:
47016
- profile = _getInboundSSOProfile(ci, name)
47167
+ profile = _getInboundSSOProfileByName(ci, 'saml', name)
47017
47168
  if profile:
47018
47169
  assignment['samlSsoInfo']['inboundSamlSsoProfile'] = profile
47170
+ else:
47171
+ name = assignment.get('oidcSsoInfo', {}).get('inboundOidcSsoProfile')
47172
+ if name:
47173
+ profile = _getInboundSSOProfileByName(ci, 'oidc', name)
47174
+ if profile:
47175
+ assignment['oidcSsoInfo']['inboundOidcSsoProfile'] = profile
47019
47176
  _showInboundSSOAssignment(assignment, FJQC, ci, cd)
47020
47177
 
47021
- # gam show inboundssoassignment
47178
+ # gam show inboundssoassignments
47022
47179
  # [formatjson]
47023
- # gam print inboundssoassignment [todrive <ToDriveAttribute>*]
47180
+ # gam print inboundssoassignments [todrive <ToDriveAttribute>*]
47024
47181
  # [[formatjson [quotechar <Character>]]
47025
47182
  def doPrintShowInboundSSOAssignments():
47026
47183
  cd = buildGAPIObject(API.DIRECTORY)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.18.4
3
+ Version: 7.18.5
4
4
  Summary: CLI tool to manage Google Workspace
5
5
  Project-URL: Homepage, https://github.com/GAM-team/GAM
6
6
  Project-URL: Issues, https://github.com/GAM-team/GAM/issues
@@ -1,4 +1,4 @@
1
- gam/__init__.py,sha256=lSFipSI6fSlg0J9H08IWN05Mo_kIh61EeR86LIEGQ-c,3577219
1
+ gam/__init__.py,sha256=QJekeV8HEGrQCPUNeJc6AL-0fkgPuC0tSNR6M-ETh-E,3583485
2
2
  gam/__main__.py,sha256=amz0-959ph6zkZKqjaar4n60yho-T37w6qWI36qx0CA,1049
3
3
  gam/cacerts.pem,sha256=82Ak7btW_2XvocLUvAwPmpx8Chi0oqtZUG1gseLK_t4,50235
4
4
  gam/cbcm-v1.1beta1.json,sha256=xO5XloCQQULmPbFBx5bckdqmbLFQ7sJ2TImhE1ysDIY,19439
@@ -65,8 +65,8 @@ gam/googleapiclient/discovery_cache/base.py,sha256=yCDPtxnbNN-p5_9fzBacC6P3wcUPl
65
65
  gam/googleapiclient/discovery_cache/file_cache.py,sha256=sim3Mg4HgRYo3vX75jvcKy_aV568EvIrtBfvfbw-044,4774
66
66
  gam/iso8601/__init__.py,sha256=Z2PsYbXgAH5a5xzUvgczCboPzqWpm65kRcIngCnhViU,1218
67
67
  gam/iso8601/iso8601.py,sha256=Li2FHZ4sBTWuthuQhyCvmvj0j6At8JbGzkSv2fc2RHU,4384
68
- gam7-7.18.4.dist-info/METADATA,sha256=9Jont_975UdHfv5JG2oX6m9QUjoCE-wMBIpGS_UR6xg,2940
69
- gam7-7.18.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
- gam7-7.18.4.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
71
- gam7-7.18.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
72
- gam7-7.18.4.dist-info/RECORD,,
68
+ gam7-7.18.5.dist-info/METADATA,sha256=628E9mgFMjRM6W-64H88Hp6dW9X1APB82o-I6MbUSjw,2940
69
+ gam7-7.18.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
+ gam7-7.18.5.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
71
+ gam7-7.18.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
72
+ gam7-7.18.5.dist-info/RECORD,,
File without changes