gam7 7.10.7__py3-none-any.whl → 7.10.9__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.

Potentially problematic release.


This version of gam7 might be problematic. Click here for more details.

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.10.07'
28
+ __version__ = '7.10.09'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -5187,6 +5187,12 @@ def checkGAPIError(e, softErrors=False, retryOnHttpError=False, mapNotFound=True
5187
5187
  return (0, None, None)
5188
5188
  else:
5189
5189
  systemErrorExit(HTTP_ERROR_RC, eContent)
5190
+ requiredScopes = ''
5191
+ wwwAuthenticate = e.resp.get('www-authenticate', '')
5192
+ if 'insufficient_scope' in wwwAuthenticate:
5193
+ mg = re.match(r'.+scope="(.+)"', wwwAuthenticate)
5194
+ if mg:
5195
+ requiredScopes = mg.group(1).split(' ')
5190
5196
  if 'error' in error:
5191
5197
  http_status = error['error']['code']
5192
5198
  reason = ''
@@ -5256,6 +5262,8 @@ def checkGAPIError(e, softErrors=False, retryOnHttpError=False, mapNotFound=True
5256
5262
  elif 'the authenticated user cannot access this service' in lmessage:
5257
5263
  error = makeErrorDict(http_status, GAPI.SERVICE_NOT_AVAILABLE, message)
5258
5264
  elif status == 'PERMISSION_DENIED' or 'the caller does not have permission' in lmessage or 'permission iam.serviceaccountkeys' in lmessage:
5265
+ if requiredScopes:
5266
+ message += f', {Msg.NO_SCOPES_FOR_API.format(API.findAPIforScope(requiredScopes))}'
5259
5267
  error = makeErrorDict(http_status, GAPI.PERMISSION_DENIED, message)
5260
5268
  elif http_status == 404:
5261
5269
  if status == 'NOT_FOUND' or 'requested entity was not found' in lmessage or 'does not exist' in lmessage:
@@ -65792,7 +65800,7 @@ def _showSharedDrive(user, shareddrive, j, jcount, FJQC):
65792
65800
  printKeyValueList(['hidden', shareddrive['hidden']])
65793
65801
  if 'createdTime' in shareddrive:
65794
65802
  printKeyValueList(['createdTime', formatLocalTime(shareddrive['createdTime'])])
65795
- for setting in ['backgroundImageLink', 'colorRgb', 'themeId', 'orgUnit', 'orgUnitId']:
65803
+ for setting in ['backgroundImageLink', 'colorRgb', 'themeId', 'orgUnit', 'orgUnitId', 'webViewLink']:
65796
65804
  if setting in shareddrive:
65797
65805
  printKeyValueList([setting, shareddrive[setting]])
65798
65806
  if 'role' in shareddrive:
@@ -65867,6 +65875,7 @@ SHAREDDRIVE_ACL_ROLES_MAP = {
65867
65875
  # [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
65868
65876
  # (role|roles <SharedDriveACLRoleList>)*
65869
65877
  # [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
65878
+ # [showwebviewlink]
65870
65879
  # [guiroles [<Boolean>]] [formatjson [quotechar <Character>]]
65871
65880
  # [showitemcountonly]
65872
65881
  # gam <UserTypeEntity> show shareddrives
@@ -65874,6 +65883,7 @@ SHAREDDRIVE_ACL_ROLES_MAP = {
65874
65883
  # [matchname <REMatchPattrn>] [orgunit|org|ou <OrgUnitPath>]
65875
65884
  # (role|roles <SharedDriveACLRoleLIst>)*
65876
65885
  # [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
65886
+ # [showwebviewlink]
65877
65887
  # [guiroles [<Boolean>]] [formatjson]
65878
65888
  # [showitemcountonly]
65879
65889
  def printShowSharedDrives(users, useDomainAdminAccess=False):
@@ -65882,6 +65892,8 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
65882
65892
  td_ouid = shareddrive.get('orgUnitId')
65883
65893
  if td_ouid:
65884
65894
  shareddrive['orgUnit'] = orgUnitIdToPathMap.get(f'id:{td_ouid}', UNKNOWN)
65895
+ if showWebViewLink:
65896
+ shareddrive['webViewLink'] = 'https://drive.google.com/drive/folders/'+shareddrive['id']
65885
65897
  if not showFields:
65886
65898
  return shareddrive
65887
65899
  sshareddrive = {}
@@ -65900,6 +65912,7 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
65900
65912
  showOrgUnitPaths = True
65901
65913
  orgUnitIdToPathMap = None
65902
65914
  guiRoles = showItemCountOnly = False
65915
+ showWebViewLink = False
65903
65916
  while Cmd.ArgumentsRemaining():
65904
65917
  myarg = getArgument()
65905
65918
  if csvPF and myarg == 'todrive':
@@ -65929,6 +65942,8 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
65929
65942
  showOrgUnitPaths = not getBoolean()
65930
65943
  elif myarg == 'guiroles':
65931
65944
  guiRoles = getBoolean()
65945
+ elif myarg == 'showwebviewlink':
65946
+ showWebViewLink = True
65932
65947
  elif myarg == 'showitemcountonly':
65933
65948
  showItemCountOnly = True
65934
65949
  showOrgUnitPaths = False
@@ -65953,6 +65968,14 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
65953
65968
  orgUnitIdToPathMap = getOrgUnitIdToPathMap(cd)
65954
65969
  if showFields:
65955
65970
  showFields.add('orgUnit')
65971
+ if showWebViewLink:
65972
+ if showFields:
65973
+ showFields.add('webViewLink')
65974
+ if csvPF:
65975
+ csvPF.AddTitle('webViewLink')
65976
+ if FJQC.formatJSON:
65977
+ csvPF.AddJSONTitles(['webViewLink'])
65978
+ csvPF.MoveJSONTitlesToEnd(['JSON'])
65956
65979
  i, count, users = getEntityArgument(users)
65957
65980
  for user in users:
65958
65981
  i += 1
@@ -66021,6 +66044,8 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
66021
66044
  row = {'User': user, 'id': shareddrive['id'], 'name': shareddrive['name']}
66022
66045
  if not useDomainAdminAccess:
66023
66046
  row['role'] = shareddrive['role'] if not guiRoles else SHAREDDRIVE_API_GUI_ROLES_MAP[shareddrive['role']]
66047
+ if showWebViewLink:
66048
+ row['webViewLink'] = shareddrive['webViewLink']
66024
66049
  row['JSON'] = json.dumps(cleanJSON(shareddrive, timeObjects=SHAREDDRIVE_TIME_OBJECTS), ensure_ascii=False, sort_keys=True)
66025
66050
  csvPF.WriteRow(row)
66026
66051
  else:
@@ -70247,14 +70272,16 @@ def _finalizeMessageSelectParameters(parameters, queryOrIdsRequired):
70247
70272
  for queryTimeName, queryTimeValue in iter(parameters['queryTimes'].items()):
70248
70273
  parameters['query'] = parameters['query'].replace(f'#{queryTimeName}#', queryTimeValue)
70249
70274
  _mapMessageQueryDates(parameters)
70250
- elif queryOrIdsRequired and parameters['messageEntity'] is None:
70251
- missingArgumentExit('query|matchlabel|ids')
70275
+ elif queryOrIdsRequired and parameters['messageEntity'] is None and not parameters['labelIds']:
70276
+ missingArgumentExit('query|matchlabel|ids|labelids')
70252
70277
  else:
70253
70278
  parameters['query'] = None
70254
70279
  parameters['maxItems'] = parameters['maxToProcess'] if parameters['quick'] and not parameters['labelMatchPattern'] else 0
70255
70280
 
70256
70281
  # gam <UserTypeEntity> archive messages <GroupItem>
70257
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>)
70282
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70283
+ # [labelids <LabelIDList>]
70284
+ # [quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>)
70258
70285
  # [csv [todrive <ToDriveAttribute>*]]
70259
70286
  def archiveMessages(users):
70260
70287
  def _processMessageFailed(user, idsList, errMsg, j=0, jcount=0):
@@ -70539,39 +70566,59 @@ def _processMessagesThreads(users, entityType):
70539
70566
  csvPF.writeCSVfile(f'{Act.ToPerform()} Messages')
70540
70567
 
70541
70568
  # gam <UserTypeEntity> delete message|messages
70542
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>)
70569
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70570
+ # [labelids <LabelIDList>]
70571
+ # [quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>)
70543
70572
  # [csv [todrive <ToDriveAttribute>*]]
70544
70573
  # gam <UserTypeEntity> modify message|messages
70545
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>)
70574
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70575
+ # [labelids <LabelIDList>]
70576
+ # [quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>)
70546
70577
  # (addlabel <LabelName>)* (removelabel <LabelName>)*
70547
70578
  # [csv [todrive <ToDriveAttribute>*]]
70548
70579
  # gam <UserTypeEntity> spam message|messages
70549
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>)
70580
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70581
+ # [labelids <LabelIDList>]
70582
+ # [quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>)
70550
70583
  # [csv [todrive <ToDriveAttribute>*]]
70551
70584
  # gam <UserTypeEntity> trash message|messages
70552
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>)
70585
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70586
+ # [labelids <LabelIDList>]
70587
+ # [quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>)
70553
70588
  # [csv [todrive <ToDriveAttribute>*]]
70554
70589
  # gam <UserTypeEntity> untrash message|messages
70555
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>)
70590
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70591
+ # [labelids <LabelIDList>]
70592
+ # [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>)
70556
70593
  # [csv [todrive <ToDriveAttribute>*]]
70557
70594
  def processMessages(users):
70558
70595
  _processMessagesThreads(users, Ent.MESSAGE)
70559
70596
 
70560
70597
  # gam <UserTypeEntity> delete thread|threads
70561
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_delete <Number>])|(ids <ThreadIDEntity>)
70598
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70599
+ # [labelids <LabelIDList>]
70600
+ # [quick|notquick] [doit] [max_to_delete <Number>])|(ids <ThreadIDEntity>)
70562
70601
  # [csv [todrive <ToDriveAttribute>*]]
70563
70602
  # gam <UserTypeEntity> modify thread|threads
70564
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_modify <Number>])|(ids <ThreadIDEntity>)
70603
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70604
+ # [labelids <LabelIDList>]
70605
+ # [quick|notquick] [doit] [max_to_modify <Number>])|(ids <ThreadIDEntity>)
70565
70606
  # (addlabel <LabelName>)* (removelabel <LabelName>)*
70566
70607
  # [csv [todrive <ToDriveAttribute>*]]
70567
70608
  # gam <UserTypeEntity> spam thread|threads
70568
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_spam <Number>])|(ids <ThreadIDEntity>)
70609
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70610
+ # [labelids <LabelIDList>]
70611
+ # [quick|notquick] [doit] [max_to_spam <Number>])|(ids <ThreadIDEntity>)
70569
70612
  # [csv [todrive <ToDriveAttribute>*]]
70570
70613
  # gam <UserTypeEntity> trash thread|threads
70571
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>)
70614
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70615
+ # [labelids <LabelIDList>]
70616
+ # [quick|notquick] [doit] [max_to_trash <Number>])|(ids <ThreadIDEntity>)
70572
70617
  # [csv [todrive <ToDriveAttribute>*]]
70573
70618
  # gam <UserTypeEntity> untrash thread|threads
70574
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <ThreadIDEntity>)
70619
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
70620
+ # [labelids <LabelIDList>]
70621
+ # [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <ThreadIDEntity>)
70575
70622
  # [csv [todrive <ToDriveAttribute>*]]
70576
70623
  def processThreads(users):
70577
70624
  _processMessagesThreads(users, Ent.THREAD)
@@ -71993,7 +72040,9 @@ def printShowMessagesThreads(users, entityType):
71993
72040
  csvPF.writeCSVfile('Message Counts' if not show_labels else 'Message Label Counts')
71994
72041
 
71995
72042
  # gam <UserTypeEntity> print message|messages [todrive <ToDriveAttribute>*]
71996
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
72043
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
72044
+ # [labelids <LabelIDList>]
72045
+ # [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
71997
72046
  # [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
71998
72047
  # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
71999
72048
  # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
@@ -72003,7 +72052,9 @@ def printShowMessagesThreads(users, entityType):
72003
72052
  # [showattachments [noshowtextplain]]]
72004
72053
  # (addcsvdata <FieldName> <String>)*
72005
72054
  # gam <UserTypeEntity> show message|messages
72006
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
72055
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
72056
+ # [labelids <LabelIDList>]
72057
+ # [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
72007
72058
  # [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
72008
72059
  # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
72009
72060
  # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
@@ -72016,7 +72067,9 @@ def printShowMessages(users):
72016
72067
  printShowMessagesThreads(users, Ent.MESSAGE)
72017
72068
 
72018
72069
  # gam <UserTypeEntity> print thread|threads [todrive <ToDriveAttribute>*]
72019
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <ThreadIDEntity>)
72070
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
72071
+ # [labelids <LabelIDList>]
72072
+ # [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <ThreadIDEntity>)
72020
72073
  # [labelmatchpattern <REMatchPattern>]
72021
72074
  # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
72022
72075
  # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
@@ -72026,7 +72079,9 @@ def printShowMessages(users):
72026
72079
  # [showattachments [noshowtextplain]]]
72027
72080
  # (addcsvdata <FieldName> <String>)*
72028
72081
  # gam <UserTypeEntity> show thread|threads
72029
- # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <ThreadIDEntity>)
72082
+ # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
72083
+ # [labelids <LabelIDList>]
72084
+ # [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <ThreadIDEntity>)
72030
72085
  # [labelmatchpattern <REMatchPattern>]
72031
72086
  # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
72032
72087
  # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
gam/gamlib/glapi.py CHANGED
@@ -226,15 +226,15 @@ _INFO = {
226
226
  CHROMEMANAGEMENT_TELEMETRY: {'name': 'Chrome Management API - Telemetry', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHROMEMANAGEMENT},
227
227
  CHROMEPOLICY: {'name': 'Chrome Policy API', 'version': 'v1', 'v2discovery': True},
228
228
  CHROMEVERSIONHISTORY: {'name': 'Chrome Version History API', 'version': 'v1', 'v2discovery': True},
229
- CLOUDCHANNEL: {'name': 'Channel Channel API', 'version': 'v1', 'v2discovery': True},
230
- CLOUDIDENTITY_DEVICES: {'name': 'Cloud Identity Devices API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
231
- CLOUDIDENTITY_GROUPS: {'name': 'Cloud Identity Groups API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
232
- CLOUDIDENTITY_GROUPS_BETA: {'name': 'Cloud Identity Groups API', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
233
- CLOUDIDENTITY_INBOUND_SSO: {'name': 'Cloud Identity Inbound SSO API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
234
- CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity OrgUnits API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
235
- CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity OrgUnits API', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
236
- CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity Policy API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
237
- CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity User Invitations API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
229
+ CLOUDCHANNEL: {'name': 'Cloud Channel API', 'version': 'v1', 'v2discovery': True},
230
+ CLOUDIDENTITY_DEVICES: {'name': 'Cloud Identity API - Devices', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
231
+ CLOUDIDENTITY_GROUPS: {'name': 'Cloud Identity API - Groups', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
232
+ CLOUDIDENTITY_GROUPS_BETA: {'name': 'Cloud Identity API - Groups Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
233
+ CLOUDIDENTITY_INBOUND_SSO: {'name': 'Cloud Identity API - Inbound SSO Settings', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
234
+ CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity API - OrgUnits', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
235
+ CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity API - OrgUnits Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
236
+ CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
237
+ CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
238
238
  CLOUDRESOURCEMANAGER: {'name': 'Cloud Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
239
239
  CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False},
240
240
  CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
@@ -258,13 +258,13 @@ _INFO = {
258
258
  LICENSING: {'name': 'License Manager API', 'version': 'v1', 'v2discovery': True},
259
259
  LOOKERSTUDIO: {'name': 'Looker Studio API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
260
260
  MEET: {'name': 'Meet API', 'version': 'v2', 'v2discovery': True},
261
- MEET_BETA: {'name': 'Meet API', 'version': 'v2beta', 'v2discovery': True, 'localjson': True, 'mappedAPI': MEET},
261
+ MEET_BETA: {'name': 'Meet API Beta', 'version': 'v2beta', 'v2discovery': True, 'localjson': True, 'mappedAPI': MEET},
262
262
  OAUTH2: {'name': 'OAuth2 API', 'version': 'v2', 'v2discovery': False},
263
263
  ORGPOLICY: {'name': 'Organization Policy API', 'version': 'v2', 'v2discovery': True},
264
264
  PEOPLE: {'name': 'People API', 'version': 'v1', 'v2discovery': True},
265
265
  PEOPLE_DIRECTORY: {'name': 'People Directory API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE},
266
266
  PEOPLE_OTHERCONTACTS: {'name': 'People API - Other Contacts', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE},
267
- PRINTERS: {'name': 'Directory API Printers', 'version': 'directory_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
267
+ PRINTERS: {'name': 'Directory API - Printers', 'version': 'directory_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
268
268
  PUBSUB: {'name': 'Pub / Sub API', 'version': 'v1', 'v2discovery': True},
269
269
  REPORTS: {'name': 'Reports API', 'version': 'reports_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
270
270
  RESELLER: {'name': 'Reseller API', 'version': 'v1', 'v2discovery': True},
@@ -362,29 +362,29 @@ _CLIENT_SCOPES = [
362
362
  'subscopes': READONLY,
363
363
  'offByDefault': True,
364
364
  'scope': 'https://www.googleapis.com/auth/apps.order'},
365
- {'name': 'Cloud Identity Groups API',
365
+ {'name': 'Cloud Identity API - Groups',
366
366
  'api': CLOUDIDENTITY_GROUPS,
367
367
  'subscopes': READONLY,
368
368
  'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'},
369
- {'name': 'Cloud Identity Groups API Beta (Enables group locking/unlocking)',
369
+ {'name': 'Cloud Identity API - Groups Beta (Enables group locking/unlocking)',
370
370
  'api': CLOUDIDENTITY_GROUPS_BETA,
371
371
  'subscopes': [],
372
372
  'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'},
373
- {'name': 'Cloud Identity - Inbound SSO Settings',
373
+ {'name': 'Cloud Identity API - Inbound SSO Settings',
374
374
  'api': CLOUDIDENTITY_INBOUND_SSO,
375
375
  'subscopes': READONLY,
376
376
  'scope': 'https://www.googleapis.com/auth/cloud-identity.inboundsso'},
377
- {'name': 'Cloud Identity OrgUnits API',
377
+ {'name': 'Cloud Identity API - OrgUnits Beta',
378
378
  'api': CLOUDIDENTITY_ORGUNITS_BETA,
379
379
  'subscopes': READONLY,
380
380
  'scope': 'https://www.googleapis.com/auth/cloud-identity.orgunits'},
381
- {'name': 'Cloud Identity - Policy',
381
+ {'name': 'Cloud Identity API - Policy',
382
382
  'api': CLOUDIDENTITY_POLICY,
383
383
  'subscopes': READONLY,
384
384
  'roByDefault': True,
385
385
  'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'
386
386
  },
387
- {'name': 'Cloud Identity User Invitations API',
387
+ {'name': 'Cloud Identity API - User Invitations',
388
388
  'api': CLOUDIDENTITY_USERINVITATIONS,
389
389
  'subscopes': READONLY,
390
390
  'scope': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'},
@@ -833,3 +833,27 @@ def getSvcAcctScopesList(userServiceAccountAccessOnly, svcAcctSpecialScopes):
833
833
 
834
834
  def hasLocalJSON(api):
835
835
  return _INFO[api].get('localjson', False)
836
+
837
+ def findAPIforScope(scopesList):
838
+ def checkScopeMatch(scope, cscope):
839
+ if cscope['scope'] == scope:
840
+ requiredAPIs.append(cscope['name'])
841
+ return True
842
+ if cscope['subscopes'] == READONLY and cscope['scope']+'.readonly' == scope:
843
+ requiredAPIs.append(cscope['name']+' (supports readonly)')
844
+ return True
845
+ return False
846
+
847
+ requiredAPIs = []
848
+ for scope in scopesList:
849
+ for cscope in _CLIENT_SCOPES:
850
+ if checkScopeMatch(scope, cscope):
851
+ break
852
+ else:
853
+ for cscope in _SVCACCT_SCOPES:
854
+ if checkScopeMatch(scope, cscope):
855
+ break
856
+ if not requiredAPIs:
857
+ requiredAPIs = scopesList
858
+ return ' or '.join(requiredAPIs)
859
+
gam/gamlib/glmsgs.py CHANGED
@@ -184,8 +184,8 @@ ALREADY_EXISTS_IN_TARGET_FOLDER = 'Already exists in {0}: {1}'
184
184
  ALREADY_EXISTS_USE_MERGE_ARGUMENT = 'Already exists; use the "merge" argument to merge the labels'
185
185
  API_ACCESS_DENIED = 'API access Denied'
186
186
  API_CALLS_RETRY_DATA = 'API calls retry data\n'
187
- API_CHECK_CLIENT_AUTHORIZATION = 'Please make sure the Client ID: {0} is authorized for the appropriate API or scopes:\n{1}\n\nRun: gam oauth create\n'
188
- API_CHECK_SVCACCT_AUTHORIZATION = 'Please make sure the Service Account Client ID: {0} is authorized for the appropriate API or scopes:\n{1}\n\nRun: gam user {2} update serviceaccount\n'
187
+ API_CHECK_CLIENT_AUTHORIZATION = 'Please make sure the Client ID: {0} is authorized for the appropriate API or scopes: {1}\n\nRun: gam oauth create\n'
188
+ API_CHECK_SVCACCT_AUTHORIZATION = 'Please make sure the Service Account Client ID: {0} is authorized for the appropriate API or scopes: {1}\n\nRun: gam user {2} update serviceaccount\n'
189
189
  API_ERROR_SETTINGS = 'API error, some settings not set'
190
190
  ARE_BOTH_REQUIRED = 'Arguments {0} and {1} are both required'
191
191
  ARE_MUTUALLY_EXCLUSIVE = 'Arguments {0} and {1} are mutually exclusive'
@@ -425,7 +425,7 @@ NO_LABELS_TO_PROCESS = 'No Labels to process'
425
425
  NO_MESSAGES_WITH_LABEL = 'No Messages with Label'
426
426
  NO_PARENTS_TO_CONVERT_TO_SHORTCUTS = 'No parents to convert to shortcuts'
427
427
  NO_REPORT_AVAILABLE = 'No {0} report available.'
428
- NO_SCOPES_FOR_API = 'There are no scopes authorized for the {0}'
428
+ NO_SCOPES_FOR_API = 'There are no scopes authorized for the API(s): {0}'
429
429
  NO_SERIAL_NUMBERS_SPECIFIED = 'No serial numbers specified'
430
430
  NO_SSO_PROFILE_MATCHES = 'No SSO profile matches display name {0}'
431
431
  NO_SSO_PROFILE_ASSIGNED = 'No SSO profile assigned to {0} {1}'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.10.7
3
+ Version: 7.10.9
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=gqwRxpsHisE3vG2X2AHWvt6mgfwCTjW1rGYI2q0z9ao,3534107
1
+ gam/__init__.py,sha256=a5ax8oW9hLZp6ojUKdPmXBmRIKKA949pTP3H9OvJvoY,3535564
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
@@ -23,7 +23,7 @@ gam/atom/token_store.py,sha256=7E6Ecvxa86WCvl1pJAhv78jg9OxQv8pMtIUcPhZCq04,3803
23
23
  gam/atom/url.py,sha256=pxO1TlORxyKQTQ1bkBE1unFzjnv9c8LjJkm-UEORShY,4276
24
24
  gam/gamlib/__init__.py,sha256=z5mF-y0j8pm-YNFBaiuxB4M_GAUPG-cXWwrhYwrVReM,679
25
25
  gam/gamlib/glaction.py,sha256=1Il_HrChVnPkzZwiZs5au4mFQVtq4K1Z42uIuR6qdnI,9419
26
- gam/gamlib/glapi.py,sha256=A6kdyCacc9tvTaxMUNvWj8jWbOrss8e8XdkqF1xbN70,34572
26
+ gam/gamlib/glapi.py,sha256=27NW2etvdNK4jfR699eqFzhV4gPotijXIQeX-wxCvHA,35319
27
27
  gam/gamlib/glcfg.py,sha256=bNTckxzIM_HruxO2DfYsDbEgqOIz1RX6CbU6XOQQQyg,28296
28
28
  gam/gamlib/glclargs.py,sha256=Ohe746FOQqMlXlutH-XJ6E1unYNzf_EJhdubnPp3new,42472
29
29
  gam/gamlib/glentity.py,sha256=c9-7MAp0HruXEUVq8Nwkllxc4KypFeZRUFkvVzPwrwk,33760
@@ -31,7 +31,7 @@ gam/gamlib/glgapi.py,sha256=2mu7DQGGYmF7ZGXeBQu_mT1FNZgXbEQqcddJjHzbvE4,39833
31
31
  gam/gamlib/glgdata.py,sha256=weRppttWm6uRyqtBoGPKoHiNZ2h28nhfUV4J_mbCszY,2707
32
32
  gam/gamlib/glglobals.py,sha256=J0xcHggVrUBzHJ5GruenKV-qV1zPKcK2qWgAgN3i5Jw,9608
33
33
  gam/gamlib/glindent.py,sha256=RfBa2LDfLIqPLL5vMfC689TCVmqn8xf-qulSzkiatrc,1228
34
- gam/gamlib/glmsgs.py,sha256=uSshtTyemMcJGCnYMy3hIilYHIh-IHFbCLlY2aAyTGM,33798
34
+ gam/gamlib/glmsgs.py,sha256=c6ff4fetFjcMtOA37-jdkNNdQVgmFgbkzoUPt99vcpI,33804
35
35
  gam/gamlib/glskus.py,sha256=e1u3zw1MGQjBgAFXqjrGWQl2d7eYpVlMYGpIKNwjskQ,15360
36
36
  gam/gamlib/gluprop.py,sha256=IyPLCyvn7-NHTUenM71YPQPXRZXx6CB5q-GtJ-FYd1c,11461
37
37
  gam/gamlib/glverlibs.py,sha256=xoQXiwcE_-HVYKv-VYA8O0mazRsc9mN-_ysj1dAlMyc,992
@@ -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.10.7.dist-info/METADATA,sha256=magKLnQvWiUc1Exm6w0uq8CAPWXSSw8VeANe4O4yWqs,2978
69
- gam7-7.10.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
- gam7-7.10.7.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
71
- gam7-7.10.7.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
72
- gam7-7.10.7.dist-info/RECORD,,
68
+ gam7-7.10.9.dist-info/METADATA,sha256=9YO3xc8QUSIb2qXdCLLFSbQDi0UcpQshJOXVhGhTfng,2978
69
+ gam7-7.10.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
+ gam7-7.10.9.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
71
+ gam7-7.10.9.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
72
+ gam7-7.10.9.dist-info/RECORD,,
File without changes