gam7 7.23.6__py3-none-any.whl → 7.24.0__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.23.06'
28
+ __version__ = '7.24.00'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -3049,9 +3049,10 @@ def getGDocData(gformat):
3049
3049
  mimeType = GDOC_FORMAT_MIME_TYPES[gformat]
3050
3050
  user = getEmailAddress()
3051
3051
  fileIdEntity = getDriveFileEntity(queryShortcutsOK=False)
3052
- user, drive, jcount = _validateUserGetFileIDs(user, 0, 0, fileIdEntity)
3052
+ _, drive = buildGAPIServiceObject(chooseSaAPI(API.DRIVECD, API.DRIVE3), user)
3053
3053
  if not drive:
3054
3054
  sys.exit(GM.Globals[GM.SYSEXITRC])
3055
+ _, _, jcount = _validateUserGetFileIDs(user, 0, 0, fileIdEntity, drive=drive)
3055
3056
  if jcount == 0:
3056
3057
  getGDocSheetDataFailedExit([Ent.USER, user], Msg.NO_ENTITIES_FOUND.format(Ent.Singular(Ent.DRIVE_FILE)))
3057
3058
  if jcount > 1:
@@ -3105,14 +3106,15 @@ def getGSheetData():
3105
3106
  user = getEmailAddress()
3106
3107
  fileIdEntity = getDriveFileEntity(queryShortcutsOK=False)
3107
3108
  sheetEntity = getSheetEntity(False)
3108
- user, drive, jcount = _validateUserGetFileIDs(user, 0, 0, fileIdEntity)
3109
+ user, drive = buildGAPIServiceObject(chooseSaAPI(API.DRIVECD, API.DRIVE3), user)
3109
3110
  if not drive:
3110
3111
  sys.exit(GM.Globals[GM.SYSEXITRC])
3112
+ _, _, jcount = _validateUserGetFileIDs(user, 0, 0, fileIdEntity, drive=drive)
3111
3113
  if jcount == 0:
3112
3114
  getGDocSheetDataFailedExit([Ent.USER, user], Msg.NO_ENTITIES_FOUND.format(Ent.Singular(Ent.DRIVE_FILE)))
3113
3115
  if jcount > 1:
3114
3116
  getGDocSheetDataFailedExit([Ent.USER, user], Msg.MULTIPLE_ENTITIES_FOUND.format(Ent.Plural(Ent.DRIVE_FILE), jcount, ','.join(fileIdEntity['list'])))
3115
- _, sheet = buildGAPIServiceObject(API.SHEETS, user)
3117
+ _, sheet = buildGAPIServiceObject(chooseSaAPI(API.SHEETSCD, API.SHEETS), user)
3116
3118
  if not sheet:
3117
3119
  sys.exit(GM.Globals[GM.SYSEXITRC])
3118
3120
  fileId = fileIdEntity['list'][0]
@@ -4801,8 +4803,6 @@ def defaultSvcAcctScopes():
4801
4803
  saScopes[scope['api']].extend(scope['scope'])
4802
4804
  saScopes[API.DRIVEACTIVITY].append(API.DRIVE_SCOPE)
4803
4805
  saScopes[API.DRIVE2] = saScopes[API.DRIVE3]
4804
- saScopes[API.DRIVETD] = saScopes[API.DRIVE3]
4805
- saScopes[API.SHEETSTD] = saScopes[API.SHEETS]
4806
4806
  return saScopes
4807
4807
 
4808
4808
  def _getSvcAcctData():
@@ -5609,6 +5609,12 @@ def getSaUser(user):
5609
5609
  GM.Globals[GM.CURRENT_CLIENT_API_SCOPES] = currentClientAPIScopes
5610
5610
  return userEmail
5611
5611
 
5612
+ def chooseSaAPI(api1, api2):
5613
+ _getSvcAcctData()
5614
+ if api1 in GM.Globals[GM.SVCACCT_SCOPES]:
5615
+ return api1
5616
+ return api2
5617
+
5612
5618
  def buildGAPIServiceObject(api, user, i=0, count=0, displayError=True):
5613
5619
  userEmail = getSaUser(user)
5614
5620
  httpObj = getHttpObj(cache=GM.Globals[GM.CACHE_DIR])
@@ -8030,7 +8036,7 @@ class CSVPrintFile():
8030
8036
 
8031
8037
  def getDriveObject():
8032
8038
  if not GC.Values[GC.TODRIVE_CLIENTACCESS]:
8033
- _, drive = buildGAPIServiceObject(API.DRIVETD, self.todrive['user'])
8039
+ _, drive = buildGAPIServiceObject(chooseSaAPI(API.DRIVETD, API.DRIVE3), self.todrive['user'])
8034
8040
  if not drive:
8035
8041
  invalidTodriveUserExit(Ent.USER, Msg.NOT_FOUND)
8036
8042
  else:
@@ -8183,7 +8189,7 @@ class CSVPrintFile():
8183
8189
  if result['mimeType'] != MIMETYPE_GA_SPREADSHEET:
8184
8190
  invalidTodriveFileIdExit([], f'{Msg.NOT_A} {Ent.Singular(Ent.SPREADSHEET)}', tdfileidLocation)
8185
8191
  if not GC.Values[GC.TODRIVE_CLIENTACCESS]:
8186
- _, sheet = buildGAPIServiceObject(API.SHEETSTD, self.todrive['user'])
8192
+ _, sheet = buildGAPIServiceObject(chooseSaAPI(API.SHEETSTD, API.SHEETS), self.todrive['user'])
8187
8193
  if sheet is None:
8188
8194
  invalidTodriveUserExit(Ent.USER, Msg.NOT_FOUND)
8189
8195
  else:
@@ -8696,7 +8702,7 @@ class CSVPrintFile():
8696
8702
  sheetTitle += tdtime.strftime(self.todrive['sheettimeformat'])
8697
8703
  action = Act.Get()
8698
8704
  if not GC.Values[GC.TODRIVE_CLIENTACCESS]:
8699
- user, drive = buildGAPIServiceObject(API.DRIVETD, self.todrive['user'])
8705
+ user, drive = buildGAPIServiceObject(chooseSaAPI(API.DRIVETD, API.DRIVE3), self.todrive['user'])
8700
8706
  if not drive:
8701
8707
  closeFile(csvFile)
8702
8708
  return
@@ -8729,7 +8735,7 @@ class CSVPrintFile():
8729
8735
  if result['mimeType'] != MIMETYPE_GA_SPREADSHEET:
8730
8736
  todriveCSVErrorExit(entityValueList, f'{Msg.NOT_A} {Ent.Singular(Ent.SPREADSHEET)}')
8731
8737
  if not GC.Values[GC.TODRIVE_CLIENTACCESS]:
8732
- _, sheet = buildGAPIServiceObject(API.SHEETSTD, user)
8738
+ _, sheet = buildGAPIServiceObject(chooseSaAPI(API.SHEETSTD, API.SHEETS), user)
8733
8739
  if sheet is None:
8734
8740
  return
8735
8741
  else:
@@ -8877,7 +8883,7 @@ class CSVPrintFile():
8877
8883
  (self.todrive['sheetEntity'] or self.todrive['locale'] or self.todrive['timeZone'] or
8878
8884
  self.todrive['sheettitle'] or self.todrive['cellwrap'] or self.todrive['cellnumberformat'])):
8879
8885
  if not GC.Values[GC.TODRIVE_CLIENTACCESS]:
8880
- _, sheet = buildGAPIServiceObject(API.SHEETSTD, user)
8886
+ _, sheet = buildGAPIServiceObject(chooseSaAPI(API.SHEETSTD, API.SHEETS), user)
8881
8887
  if sheet is None:
8882
8888
  return
8883
8889
  else:
@@ -16263,7 +16269,7 @@ def _showCustomerLicenseInfo(customerInfo, FJQC):
16263
16269
  while True:
16264
16270
  try:
16265
16271
  result = callGAPI(rep.customerUsageReports(), 'get',
16266
- throwReasons=[GAPI.INVALID, GAPI.FORBIDDEN, GAPI.PERMISSION_DENIED],
16272
+ throwReasons=[GAPI.INVALID, GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.PERMISSION_DENIED],
16267
16273
  date=tryDate, customerId=customerInfo['id'],
16268
16274
  fields='warnings,usageReports', parameters=parameters)
16269
16275
  usageReports = numUsersAvailable(result)
@@ -16276,7 +16282,7 @@ def _showCustomerLicenseInfo(customerInfo, FJQC):
16276
16282
  if fullData == 0:
16277
16283
  continue
16278
16284
  break
16279
- except GAPI.invalid as e:
16285
+ except (GAPI.invalid, GAPI.failedPrecondition) as e:
16280
16286
  tryDate = _adjustTryDate(str(e), 0, -1, tryDate)
16281
16287
  if not tryDate:
16282
16288
  return
@@ -16998,22 +17004,11 @@ ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP = {
16998
17004
  }
16999
17005
  ALL_ASSIGNEE_TYPES = ['user', 'group', 'serviceaccount']
17000
17006
 
17001
- PRINT_ADMIN_FIELDS = ['roleAssignmentId', 'roleId', 'assignedTo', 'scopeType', 'orgUnitId', 'assigneeType']
17007
+ PRINT_ADMIN_FIELDS = ['roleAssignmentId', 'roleId', 'assignedTo', 'scopeType', 'orgUnitId']
17002
17008
  PRINT_ADMIN_TITLES = ['roleAssignmentId', 'roleId', 'role',
17003
17009
  'assignedTo', 'assignedToUser', 'assignedToGroup', 'assignedToServiceAccount', 'assignedToUnknown',
17004
17010
  'scopeType', 'orgUnitId', 'orgUnit']
17005
17011
 
17006
- def getAssigneeTypes(myarg, typesSet):
17007
- if myarg in {'type', 'types'}:
17008
- for gtype in getString(Cmd.OB_ADMIN_ASSIGNEE_TYPE_LIST).lower().replace(',', ' ').split():
17009
- if gtype in ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP:
17010
- typesSet.add(ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP[gtype])
17011
- else:
17012
- invalidChoiceExit(gtype, ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP, True)
17013
- else:
17014
- return False
17015
- return True
17016
-
17017
17012
  # gam print admins [todrive <ToDriveAttribute>*]
17018
17013
  # [user|group <EmailAddress>|<UniqueID>] [role <RoleItem>]
17019
17014
  # [types <AdminAssigneeTypeList>]
@@ -17023,6 +17018,17 @@ def getAssigneeTypes(myarg, typesSet):
17023
17018
  # [types <AdminAssigneeTypeList>]
17024
17019
  # [recursive] [condition] [privileges]
17025
17020
  def doPrintShowAdmins():
17021
+ def _getAssigneeTypes(myarg):
17022
+ if myarg in {'type', 'types'}:
17023
+ for gtype in getString(Cmd.OB_ADMIN_ASSIGNEE_TYPE_LIST).lower().replace(',', ' ').split():
17024
+ if gtype in ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP:
17025
+ typesSet.add(ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP[gtype])
17026
+ else:
17027
+ invalidChoiceExit(gtype, ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP, True)
17028
+ else:
17029
+ return False
17030
+ return True
17031
+
17026
17032
  def _getPrivileges(admin):
17027
17033
  if showPrivileges:
17028
17034
  roleId = admin['roleId']
@@ -17048,13 +17054,11 @@ def doPrintShowAdmins():
17048
17054
  def _setNamesFromIds(admin, privileges):
17049
17055
  admin['role'] = role_from_roleid(admin['roleId'])
17050
17056
  assignedTo = admin['assignedTo']
17057
+ admin['assignedToUnknown'] = False
17051
17058
  if assignedTo not in assignedToIdEmailMap:
17052
- assigneeEmail, assigneeType = convertUIDtoEmailAddressWithType(f'uid:{assignedTo}', cd, sal,
17053
- emailTypes=ALL_ASSIGNEE_TYPES if admin.get('assigneeType') != 'group' else ['group'])
17054
- if assigneeType in ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP:
17055
- assignedToField = ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP[assigneeType]
17056
- else:
17057
- assignedToField = 'assignedToUnknown'
17059
+ emailTypes = ALL_ASSIGNEE_TYPES if admin.get('assigneeType', '') != 'group' else ['group']
17060
+ assigneeEmail, assigneeType = convertUIDtoEmailAddressWithType(f'uid:{assignedTo}', cd, sal, emailTypes=emailTypes)
17061
+ assignedToField = ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP.get(assigneeType, 'assignedToUnknown')
17058
17062
  if assignedToField == 'assignedToUnknown':
17059
17063
  assigneeEmail = True
17060
17064
  assignedToIdEmailMap[assignedTo] = {'assignedToField': assignedToField, 'assigneeEmail': assigneeEmail}
@@ -17069,17 +17073,22 @@ def doPrintShowAdmins():
17069
17073
  admin['condition'] = 'securitygroup'
17070
17074
  elif admin['condition'] == NONSECURITY_GROUP_CONDITION:
17071
17075
  admin['condition'] = 'nonsecuritygroup'
17076
+ if debug:
17077
+ print('******', admin['assignedTo'], admin.get('assigneeType', 'no type'),
17078
+ admin['assignedToField'], not typesSet or admin['assignedToField'] in typesSet)
17079
+ return not typesSet or admin['assignedToField'] in typesSet
17072
17080
 
17073
17081
  cd = buildGAPIObject(API.DIRECTORY)
17074
17082
  sal = buildGAPIObject(API.SERVICEACCOUNTLOOKUP)
17075
17083
  csvPF = CSVPrintFile(PRINT_ADMIN_TITLES) if Act.csvFormat() else None
17076
17084
  roleId = None
17077
17085
  userKey = None
17078
- oneItemPerRow = recursive = showPrivileges = False
17086
+ debug = oneItemPerRow = recursive = showPrivileges = False
17079
17087
  typesSet = set()
17080
17088
  kwargs = {}
17081
17089
  rolePrivileges = {}
17082
- fieldsList = PRINT_ADMIN_FIELDS
17090
+ allGroupRoles = ','.join(sorted(ALL_GROUP_ROLES))
17091
+ fieldsList = PRINT_ADMIN_FIELDS+['assigneeType']
17083
17092
  assignedToIdEmailMap = {}
17084
17093
  while Cmd.ArgumentsRemaining():
17085
17094
  myarg = getArgument()
@@ -17089,11 +17098,10 @@ def doPrintShowAdmins():
17089
17098
  userKey = kwargs['userKey'] = getEmailAddress()
17090
17099
  elif myarg == 'role':
17091
17100
  _, roleId = getRoleId()
17092
- elif getAssigneeTypes(myarg, typesSet):
17101
+ elif _getAssigneeTypes(myarg):
17093
17102
  pass
17094
17103
  elif myarg == 'recursive':
17095
17104
  recursive = True
17096
- allGroupRoles = ','.join(sorted(ALL_GROUP_ROLES))
17097
17105
  memberOptions = initMemberOptions()
17098
17106
  memberOptions[MEMBEROPTION_INCLUDEDERIVEDMEMBERSHIP] = True
17099
17107
  memberOptions[MEMBEROPTION_DISPLAYMATCH] = False
@@ -17108,13 +17116,13 @@ def doPrintShowAdmins():
17108
17116
  showPrivileges = True
17109
17117
  elif myarg == 'oneitemperrow':
17110
17118
  oneItemPerRow = True
17119
+ elif myarg == 'debug':
17120
+ debug = True
17111
17121
  else:
17112
17122
  unknownArgumentExit()
17113
17123
  if roleId and not kwargs:
17114
17124
  kwargs['roleId'] = roleId
17115
17125
  roleId = None
17116
- if not typesSet:
17117
- typesSet = set(ADMIN_ASSIGNEE_TYPE_TO_ASSIGNEDTO_FIELD_MAP.values())
17118
17126
  fields = getItemFieldsFromFieldsList('items', fieldsList)
17119
17127
  printGettingAllAccountEntities(Ent.ADMIN_ROLE_ASSIGNMENT)
17120
17128
  try:
@@ -17131,7 +17139,7 @@ def doPrintShowAdmins():
17131
17139
  return
17132
17140
  except GAPI.notFound as e:
17133
17141
  entityActionFailedExit([Ent.ADMIN_ROLE, kwargs['roleId']], str(e))
17134
- except (GAPI.forbidden, GAPI.serviceNotAvailable) as e:
17142
+ except GAPI.serviceNotAvailable as e:
17135
17143
  entityActionFailedExit([Ent.ADMINISTRATOR, userKey], str(e))
17136
17144
  except (GAPI.badRequest, GAPI.customerNotFound):
17137
17145
  accessErrorExit(cd)
@@ -17147,8 +17155,7 @@ def doPrintShowAdmins():
17147
17155
  continue
17148
17156
  assignedTo = admin['assignedTo']
17149
17157
  if admin['assigneeType'] != 'group' or not recursive:
17150
- _setNamesFromIds(admin, _getPrivileges(admin))
17151
- if admin['assignedToField'] in typesSet:
17158
+ if _setNamesFromIds(admin, _getPrivileges(admin)):
17152
17159
  expandedAdmins.append(admin)
17153
17160
  continue
17154
17161
  if assignedTo not in groupMembers:
@@ -17158,10 +17165,8 @@ def doPrintShowAdmins():
17158
17165
  getGroupMembers(cd, assignedTo, allGroupRoles, membersList, membersSet, i, count,
17159
17166
  memberOptions, memberDisplayOptions, level, {Ent.TYPE_USER})
17160
17167
  groupMembers[assignedTo] = membersList[:]
17161
- _setNamesFromIds(admin, _getPrivileges(admin))
17162
- if admin[assignedToIdEmailMap[assignedTo]['assignedToField']] not in typesSet:
17168
+ if not _setNamesFromIds(admin, _getPrivileges(admin)):
17163
17169
  continue
17164
- expandedAdmins.append(admin)
17165
17170
  if not groupMembers[assignedTo]:
17166
17171
  expandedAdmins.append(admin)
17167
17172
  continue
@@ -17184,7 +17189,7 @@ def doPrintShowAdmins():
17184
17189
  Ind.Increment()
17185
17190
  for field in PRINT_ADMIN_TITLES:
17186
17191
  if field in admin:
17187
- if field == 'roleAssignmentId':
17192
+ if (field == 'roleAssignmentId') or (field == 'assignedToUnknown' and not admin[field]):
17188
17193
  continue
17189
17194
  printKeyValueList([field, admin[field]])
17190
17195
  if showPrivileges:
@@ -17199,7 +17204,8 @@ def doPrintShowAdmins():
17199
17204
  Ind.Decrement()
17200
17205
  else:
17201
17206
  for admin in expandedAdmins:
17202
- admin.pop('assignedToField')
17207
+ admin.pop('assigneeType', None)
17208
+ admin.pop('assignedToField', None)
17203
17209
  if not oneItemPerRow or 'rolePrivileges' not in admin:
17204
17210
  csvPF.WriteRowTitles(flattenJSON(admin))
17205
17211
  else:
gam/gamlib/glapi.py CHANGED
@@ -60,6 +60,7 @@ DIRECTORY = 'directory'
60
60
  DOCS = 'docs'
61
61
  DRIVE2 = 'drive2'
62
62
  DRIVE3 = 'drive3'
63
+ DRIVECD = 'drivecd'
63
64
  DRIVETD = 'drivetd'
64
65
  DRIVEACTIVITY = 'driveactivity'
65
66
  DRIVELABELS = 'drivelabels'
@@ -91,6 +92,7 @@ SERVICEACCOUNTLOOKUP = 'serviceaccountlookup'
91
92
  SERVICEMANAGEMENT = 'servicemanagement'
92
93
  SERVICEUSAGE = 'serviceusage'
93
94
  SHEETS = 'sheets'
95
+ SHEETSCD = 'sheetscd'
94
96
  SHEETSTD = 'sheetstd'
95
97
  SITEVERIFICATION = 'siteVerification'
96
98
  STORAGE = 'storage'
@@ -253,7 +255,8 @@ _INFO = {
253
255
  DOCS: {'name': 'Docs API', 'version': 'v1', 'v2discovery': True},
254
256
  DRIVE2: {'name': 'Drive API v2', 'version': 'v2', 'v2discovery': False, 'mappedAPI': 'drive'},
255
257
  DRIVE3: {'name': 'Drive API v3', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
256
- DRIVETD: {'name': 'Drive API v3 - todrive', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
258
+ DRIVECD: {'name': 'Drive API v3 - read command data', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
259
+ DRIVETD: {'name': 'Drive API v3 - write todrive data', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
257
260
  DRIVEACTIVITY: {'name': 'Drive Activity API v2', 'version': 'v2', 'v2discovery': True},
258
261
  DRIVELABELS_ADMIN: {'name': 'Drive Labels API - Admin', 'version': 'v2', 'v2discovery': True, 'mappedAPI': DRIVELABELS},
259
262
  DRIVELABELS_USER: {'name': 'Drive Labels API - User', 'version': 'v2', 'v2discovery': True, 'mappedAPI': DRIVELABELS},
@@ -283,7 +286,8 @@ _INFO = {
283
286
  SERVICEMANAGEMENT: {'name': 'Service Management API', 'version': 'v1', 'v2discovery': True},
284
287
  SERVICEUSAGE: {'name': 'Service Usage API', 'version': 'v1', 'v2discovery': True},
285
288
  SHEETS: {'name': 'Sheets API', 'version': 'v4', 'v2discovery': True},
286
- SHEETSTD: {'name': 'Sheets API - todrive', 'version': 'v4', 'v2discovery': True, 'mappedAPI': SHEETS},
289
+ SHEETSCD: {'name': 'Sheets API - read command data', 'version': 'v4', 'v2discovery': True, 'mappedAPI': SHEETS},
290
+ SHEETSTD: {'name': 'Sheets API - write todrive data', 'version': 'v4', 'v2discovery': True, 'mappedAPI': SHEETS},
287
291
  SITEVERIFICATION: {'name': 'Site Verification API', 'version': 'v1', 'v2discovery': True},
288
292
  STORAGE: {'name': 'Cloud Storage API', 'version': 'v1', 'v2discovery': True},
289
293
  STORAGEREAD: {'name': 'Cloud Storage API - Read', 'version': 'v1', 'v2discovery': True, 'mappedAPI': STORAGE},
@@ -750,9 +754,15 @@ _SVCACCT_SCOPES = [
750
754
  ]
751
755
 
752
756
  _SVCACCT_SPECIAL_SCOPES = [
753
- {'name': 'Drive API - todrive',
757
+ {'name': 'Drive API - read command data',
758
+ 'api': DRIVECD,
759
+ 'subscopes': [],
760
+ 'offByDefault': True,
761
+ 'scope': DRIVE_SCOPE+'.readonly'},
762
+ {'name': 'Drive API - write todrive data',
754
763
  'api': DRIVETD,
755
764
  'subscopes': [],
765
+ 'offByDefault': True,
756
766
  'scope': DRIVE_SCOPE},
757
767
  {'name': 'Gmail API - Full Access - read only',
758
768
  'api': GMAIL,
@@ -764,8 +774,14 @@ _SVCACCT_SPECIAL_SCOPES = [
764
774
  'subscopes': [],
765
775
  'offByDefault': True,
766
776
  'scope': GMAIL_SEND_SCOPE},
767
- {'name': 'Sheets API - todrive',
777
+ {'name': 'Sheets API - read command data',
778
+ 'api': SHEETSCD,
779
+ 'offByDefault': True,
780
+ 'subscopes': [],
781
+ 'scope': 'https://www.googleapis.com/auth/spreadsheets.readonly'},
782
+ {'name': 'Sheets API - write todrive data',
768
783
  'api': SHEETSTD,
784
+ 'offByDefault': True,
769
785
  'subscopes': [],
770
786
  'scope': 'https://www.googleapis.com/auth/spreadsheets'},
771
787
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.23.6
3
+ Version: 7.24.0
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=hT_6mB1-IGqw6dWjKeo0W3EQF73Ve2_NjiX_xB7INIc,3623383
1
+ gam/__init__.py,sha256=S6kbqI9bqkYEDPEJ8m4BmUeX4vCC1NX0ssjp4FnmkHM,3623835
2
2
  gam/__main__.py,sha256=amz0-959ph6zkZKqjaar4n60yho-T37w6qWI36qx0CA,1049
3
3
  gam/cacerts.pem,sha256=DUsVo2XlFYwfkhe3gnxa-Km4Z4noz74hSApXwTT-nQE,44344
4
4
  gam/cbcm-v1.1beta1.json,sha256=xO5XloCQQULmPbFBx5bckdqmbLFQ7sJ2TImhE1ysDIY,19439
@@ -22,7 +22,7 @@ gam/atom/token_store.py,sha256=7E6Ecvxa86WCvl1pJAhv78jg9OxQv8pMtIUcPhZCq04,3803
22
22
  gam/atom/url.py,sha256=pxO1TlORxyKQTQ1bkBE1unFzjnv9c8LjJkm-UEORShY,4276
23
23
  gam/gamlib/__init__.py,sha256=z5mF-y0j8pm-YNFBaiuxB4M_GAUPG-cXWwrhYwrVReM,679
24
24
  gam/gamlib/glaction.py,sha256=1Il_HrChVnPkzZwiZs5au4mFQVtq4K1Z42uIuR6qdnI,9419
25
- gam/gamlib/glapi.py,sha256=u97M7Y2BeP3tYEEGYEz-9kY4fdV0fYkeqC3YN-sRwNc,36028
25
+ gam/gamlib/glapi.py,sha256=GjnAySjnFQ3sMnOXZC7HNjR-Fk-q5BV-6v0A0cG-O3w,36723
26
26
  gam/gamlib/glcfg.py,sha256=jX9IIrqSa8CPZ-UdnMDs2RuGo8vPh3jpgvRhI9VRbII,28325
27
27
  gam/gamlib/glclargs.py,sha256=LlTtwJJHqU48l7SQT4bcZCWlw3Y46g42Bn1ACGW8gIk,53307
28
28
  gam/gamlib/glentity.py,sha256=KWFomkoNE6lLE83zVqVIlJ2rkzfLkhEasW1M0TWGieA,35373
@@ -47,8 +47,8 @@ gam/gdata/apps/audit/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrK
47
47
  gam/gdata/apps/audit/service.py,sha256=Z1eueThcNeVUMWP1DRWc_DGHrJCiJI8W_xj6L-cqu-Q,9658
48
48
  gam/gdata/apps/contacts/__init__.py,sha256=Um6zgIkiahZns7yAEuC3pxHSMD8iciZ_EoynSLoYPfU,30463
49
49
  gam/gdata/apps/contacts/service.py,sha256=5lNb-Ii1Gyek6ePFji3kyoYtCBc8CuJTwagx2BL2o14,15684
50
- gam7-7.23.6.dist-info/METADATA,sha256=BEAOLvBw21I1PEiIFYzkqJhHRdWQeu1_BzMSM6LDzrU,3092
51
- gam7-7.23.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
52
- gam7-7.23.6.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
53
- gam7-7.23.6.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
54
- gam7-7.23.6.dist-info/RECORD,,
50
+ gam7-7.24.0.dist-info/METADATA,sha256=EOGIrgksY6lGM8VUUx9boPqt1YynQ1-GBDEENHcsGzU,3092
51
+ gam7-7.24.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
52
+ gam7-7.24.0.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
53
+ gam7-7.24.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
54
+ gam7-7.24.0.dist-info/RECORD,,
File without changes