Shared Drive fixes/updates

This commit is contained in:
Ross Scroggs
2024-02-02 16:00:43 -08:00
parent ee68669652
commit 51c7a542e3
4 changed files with 188 additions and 84 deletions

View File

@ -4533,6 +4533,7 @@ gam create shareddrive <Name>
(<SharedDriveRestrictionsSubfieldName> <Boolean>)* (<SharedDriveRestrictionsSubfieldName> <Boolean>)*
[hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>] [hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>]
[errorretries <Integer>] [updateinitialdelay <Integer>] [updateretrydelay <Integer>] [errorretries <Integer>] [updateinitialdelay <Integer>] [updateretrydelay <Integer>]
[movetoorgunitdelay <Integer>]
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly] [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly]
gam update shareddrive <SharedDriveEntity> [name <Name>] gam update shareddrive <SharedDriveEntity> [name <Name>]
[(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])] [(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])]
@ -4542,9 +4543,11 @@ gam delete shareddrive <SharedDriveEntity>
[adminaccess|asadmin] [allowitemdeletion] [adminaccess|asadmin] [allowitemdeletion]
gam hide shareddrive <SharedDriveEntity> gam hide shareddrive <SharedDriveEntity>
gam unhide shareddrive <SharedDriveEntity> gam unhide shareddrive <SharedDriveEntity>
gam info shareddrive <SharedDriveEntity> [fields <SharedDriveFieldNameList>] gam info shareddrive <SharedDriveEntity>
[fields <SharedDriveFieldNameList>]
[formatjson] [formatjson]
gam show shareddriveinfo <SharedDriveEntity> [fields <SharedDriveFieldNameList>] gam show shareddriveinfo <SharedDriveEntity>
[fields <SharedDriveFieldNameList>]
[formatjson] [formatjson]
gam print shareddrives [todrive <ToDriveAttribute>*] gam print shareddrives [todrive <ToDriveAttribute>*]
[teamdriveadminquery|query <QueryTeamDrive>] [teamdriveadminquery|query <QueryTeamDrive>]
@ -4571,16 +4574,19 @@ gam <UserTypeEntity> create shareddrive <Name> adminaccess
(<SharedDriveRestrictionsSubfieldName> <Boolean>)* (<SharedDriveRestrictionsSubfieldName> <Boolean>)*
[hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>] [hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>]
[errorretries <Integer>] [updateinitialdelay <Integer>] [updateretrydelay <Integer>] [errorretries <Integer>] [updateinitialdelay <Integer>] [updateretrydelay <Integer>]
[movetoorgunitdelay <Integer>]
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly] [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly]
gam update shareddrive <SharedDriveEntity> asadmin [name <Name>] gam <UserTypeEntity> update shareddrive <SharedDriveEntity> adminaccess [name <Name>]
[(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])] [(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])]
(<SharedDriveRestrictionsFieldName> <Boolean>)* (<SharedDriveRestrictionsFieldName> <Boolean>)*
[hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>] [hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>]
gam <UserTypeEntity> delete shareddrive <SharedDriveEntity> gam <UserTypeEntity> delete shareddrive <SharedDriveEntity>
adminaccess [allowitemdeletion] adminaccess [allowitemdeletion]
gam <UserTypeEntity> info shareddrive <SharedDriveEntity> adminaccess [fields <SharedDriveFieldNameList>] gam <UserTypeEntity> info shareddrive <SharedDriveEntity>
adminaccess [fields <SharedDriveFieldNameList>]
[formatjson] [formatjson]
gam <UserTypeEntity> show shareddriveinfo <SharedDriveEntity> adminaccess [fields <SharedDriveFieldNameList>] gam <UserTypeEntity> show shareddriveinfo <SharedDriveEntity>
adminaccess [fields <SharedDriveFieldNameList>]
[formatjson] [formatjson]
gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*]
adminaccess [teamdriveadminquery|query <QueryTeamDrive>] adminaccess [teamdriveadminquery|query <QueryTeamDrive>]
@ -4595,6 +4601,40 @@ gam <UserTypeEntity> show shareddrives
[fields <SharedDriveFieldNameList>] [fields <SharedDriveFieldNameList>]
[formatjson] [formatjson]
In these commands, you specify a user, administrator access is not used.
gam <UserTypeEntity> create shareddrive <Name>
[(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])]
(<SharedDriveRestrictionsSubfieldName> <Boolean>)*
[hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>]
[errorretries <Integer>] [updateinitialdelay <Integer>] [updateretrydelay <Integer>]
[movetoorgunitdelay <Integer>]
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly]
gam <UserTypeEntity> update shareddrive <SharedDriveEntity> [name <Name>]
[(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])]
(<SharedDriveRestrictionsFieldName> <Boolean>)*
[hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>]
gam <UserTypeEntity> delete shareddrive <SharedDriveEntity>
[allowitemdeletion]
gam <UserTypeEntity> info shareddrive <SharedDriveEntity>
[fields <SharedDriveFieldNameList>]
[guiroles [<Boolean>]] [formatjson]
gam <UserTypeEntity> show shareddriveinfo <SharedDriveEntity>
[fields <SharedDriveFieldNameList>]
[guiroles [<Boolean>]] [formatjson]
gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*]
[teamdriveadminquery|query <QueryTeamDrive>]
[matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>]
(role|roles <SharedDriveACLRoleList>)*
[fields <SharedDriveFieldNameList>]
[guiroles [<Boolean>]] [formatjson [quotechar <Character>]]
gam <UserTypeEntity> show shareddrives
[teamdriveadminquery|query <QueryTeamDrive>]
[matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>]
(role|roles <SharedDriveACLRoleList>)*
[fields <SharedDriveFieldNameList>]
[guiroles [<Boolean>]] [formatjson]
These commands are used to manage the ACLs on the Team Drives themselves, not the files/folders on the Team Drives. These commands are used to manage the ACLs on the Team Drives themselves, not the files/folders on the Team Drives.
<DrivePermissionsFieldName> ::= <DrivePermissionsFieldName> ::=
@ -5771,12 +5811,14 @@ gam <UserTypeEntity> create focustime
[summary <String>] [summary <String>]
(timerange <Time> <Time> [recurrence <String>])+ (timerange <Time> <Time> [recurrence <String>])+
[timezone <String>] [timezone <String>]
gam <UserTypeEntity> create outofoffice gam <UserTypeEntity> create outofoffice
[declinemode none|all|new] [declinemode none|all|new]
[declinemessage <String>] [declinemessage <String>]
[summary <String>] [summary <String>]
(timerange <Time> <Time> [recurrence <String>])+ (timerange <Time> <Time> [recurrence <String>])+
[timezone <String>] [timezone <String>]
gam <UserTypeEntity> create workinglocation gam <UserTypeEntity> create workinglocation
(home| (home|
(custom <String>)| (custom <String>)|

View File

@ -2,10 +2,41 @@
Merged GAM-Team version Merged GAM-Team version
6.67.34
Added option `movetoorgunitdelay <Integer>` to `gam <UserTypeEntity> create shareddrive <Name> ... ou|org|orgunit <OrgUnitItem>`.
GAM creates the Shared Drive, verifies that it has been created and then tries to move it to `<OrgUnitItem>`. Google seems to
require a delay or the following error is generated.
```
ERROR: 409: 409 - The operation was aborted.
```
`movetoorgunitdelay` defaults to 20 seconds which seems to work; `<Integer>` can range from 0 to 60.
6.67.33
Upgraded to OpenSSL 3.2.1 where possible.
Fixed bug in `gam <UserTypeEntity> print shareddrives` where `role` was improperly displayed as `fileOrganizer`
rather than `writer`.
Added option `guiroles [<Boolean>]` to `gam <UserTypeEntity> info|print|show shareddrive` that maps
the Drive API role names to the Google Drive GUI role names.
```
API: GUI
commenter: Commenter
fileOrganizer: Content manager
organizer: Manager
reader: Viewer
writer: Contributor
```
6.67.32 6.67.32
Updated `<ToDriveAttribute>` to allow multiple `tdshare <EmailAddress> commenter|reader|writer` options. Updated `<ToDriveAttribute>` to allow multiple `tdshare <EmailAddress> commenter|reader|writer` options.
Fixed bug in `gam <UserTypeEntity> print shareddrives` where `role` was improperly displayed as `unknown`
rather than `reader` when `Allow viewers and commenters to download, print, and copy files` was unchecked for the Shared Drive.
6.67.31 6.67.31
Updated `gam <UserTypeEntity> claim|transfer ownership <DriveFileEntity>` to properly Updated `gam <UserTypeEntity> claim|transfer ownership <DriveFileEntity>` to properly

View File

@ -5158,6 +5158,8 @@ def checkGAPIError(e, softErrors=False, retryOnHttpError=False, mapNotFound=True
elif http_status == 409: elif http_status == 409:
if status == 'ALREADY_EXISTS' or 'requested entity already exists' in lmessage: if status == 'ALREADY_EXISTS' or 'requested entity already exists' in lmessage:
error = makeErrorDict(http_status, GAPI.ALREADY_EXISTS, message) error = makeErrorDict(http_status, GAPI.ALREADY_EXISTS, message)
elif status == 'ABORTED':
error = makeErrorDict(http_status, GAPI.ABORTED, message)
elif http_status == 412: elif http_status == 412:
if 'insufficient archived user licenses' in lmessage: if 'insufficient archived user licenses' in lmessage:
error = makeErrorDict(http_status, GAPI.INSUFFICIENT_ARCHIVED_USER_LICENSES, message) error = makeErrorDict(http_status, GAPI.INSUFFICIENT_ARCHIVED_USER_LICENSES, message)
@ -61418,11 +61420,12 @@ def _moveSharedDriveToOU(orgUnit, orgUnitId, driveId, user, i, count, ci, return
'destinationOrgUnit': f'orgUnits/{orgUnitId[3:]}'} 'destinationOrgUnit': f'orgUnits/{orgUnitId[3:]}'}
try: try:
callGAPI(ci.orgUnits().memberships(), 'move', callGAPI(ci.orgUnits().memberships(), 'move',
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.ABORTED],
name=name, body=cibody) name=name, body=cibody)
if not returnIdOnly: if not returnIdOnly:
Act.Set(Act.MOVE) Act.Set(Act.MOVE)
entityModifierNewValueActionPerformed([Ent.SHAREDDRIVE, driveId], Act.MODIFIER_TO, f'{Ent.Singular(Ent.ORGANIZATIONAL_UNIT)}: {orgUnit}', i, count) entityModifierNewValueActionPerformed([Ent.SHAREDDRIVE, driveId], Act.MODIFIER_TO, f'{Ent.Singular(Ent.ORGANIZATIONAL_UNIT)}: {orgUnit}', i, count)
except (GAPI.notFound, GAPI.forbidden, GAPI.badRequest, GAPI.internalError, except (GAPI.notFound, GAPI.forbidden, GAPI.aborted, GAPI.badRequest, GAPI.internalError,
GAPI.noManageTeamDriveAdministratorPrivilege) as e: GAPI.noManageTeamDriveAdministratorPrivilege) as e:
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], str(e), i, count) entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], str(e), i, count)
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
@ -61435,6 +61438,7 @@ def _moveSharedDriveToOU(orgUnit, orgUnitId, driveId, user, i, count, ci, return
# (<SharedDriveRestrictionsFieldName> <Boolean>)* # (<SharedDriveRestrictionsFieldName> <Boolean>)*
# [hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>] # [hide|hidden <Boolean>] [ou|org|orgunit <OrgUnitItem>]
# [errorretries <Integer>] [updateinitialdelay <Integer>] [updateretrydelay <Integer>] # [errorretries <Integer>] [updateinitialdelay <Integer>] [updateretrydelay <Integer>]
# [movetoorgunitdelay <Integer>]
# [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly] # [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly]
def createSharedDrive(users, useDomainAdminAccess=False): def createSharedDrive(users, useDomainAdminAccess=False):
def waitingForCreationToComplete(sleep_time): def waitingForCreationToComplete(sleep_time):
@ -61451,6 +61455,7 @@ def createSharedDrive(users, useDomainAdminAccess=False):
errorRetries = 5 errorRetries = 5
updateInitialDelay = 10 updateInitialDelay = 10
updateRetryDelay = 10 updateRetryDelay = 10
moveToOrgUnitDelay = 20
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if _getSharedDriveTheme(myarg, body): if _getSharedDriveTheme(myarg, body):
@ -61478,6 +61483,8 @@ def createSharedDrive(users, useDomainAdminAccess=False):
updateInitialDelay = getInteger(minVal=0, maxVal=60) updateInitialDelay = getInteger(minVal=0, maxVal=60)
elif myarg == 'updateretrydelay': elif myarg == 'updateretrydelay':
updateRetryDelay = getInteger(minVal=0, maxVal=60) updateRetryDelay = getInteger(minVal=0, maxVal=60)
elif myarg == 'movetoorgunitdelay':
moveToOrgUnitDelay = getInteger(minVal=0, maxVal=60)
else: else:
unknownArgumentExit() unknownArgumentExit()
if csvPF: if csvPF:
@ -61531,14 +61538,30 @@ def createSharedDrive(users, useDomainAdminAccess=False):
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count) userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
break break
if doUpdate and (updateBody or hide or orgUnit): if not (doUpdate or updateBody or hide or orgUnit):
if updateBody or hide: continue
waitingForCreationToComplete(updateInitialDelay) waitingForCreationToComplete(updateInitialDelay)
created = False
retry = 0
while True:
try:
callGAPI(drive.drives(), 'get',
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.NOT_FOUND],
useDomainAdminAccess=useDomainAdminAccess,
driveId=driveId, fields='id')
created = True
break
except GAPI.notFound as e:
retry += 1
if retry > errorRetries:
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], str(e), i, count)
break
waitingForCreationToComplete(updateRetryDelay)
if not created:
continue
try: try:
if updateBody: if updateBody:
Act.Set(Act.UPDATE) Act.Set(Act.UPDATE)
retry = 0
while True:
try: try:
callGAPI(drive.drives(), 'update', callGAPI(drive.drives(), 'update',
bailOnInternalError=True, bailOnInternalError=True,
@ -61549,41 +61572,21 @@ def createSharedDrive(users, useDomainAdminAccess=False):
useDomainAdminAccess=useDomainAdminAccess, driveId=driveId, body=updateBody) useDomainAdminAccess=useDomainAdminAccess, driveId=driveId, body=updateBody)
if not returnIdOnly and not csvPF: if not returnIdOnly and not csvPF:
entityActionPerformed([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], i, count) entityActionPerformed([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], i, count)
break
except GAPI.notFound as e:
retry += 1
if retry > errorRetries:
entityActionFailedWarning([Ent.USER, user, Ent.REQUEST_ID, requestId], str(e), i, count)
break
waitingForCreationToComplete(updateRetryDelay)
except (GAPI.badRequest, GAPI.internalError, GAPI.permissionDenied) as e:
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], str(e), i, count)
break
except GAPI.fileNotFound as e: except GAPI.fileNotFound as e:
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId, entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId,
Ent.DRIVE_FILE, body.get('backgroundImageFile', {}).get('id', UNKNOWN)], Ent.DRIVE_FILE, body.get('backgroundImageFile', {}).get('id', UNKNOWN)],
str(e), i, count) str(e), i, count)
break
if hide: if hide:
Act.Set(Act.HIDE) Act.Set(Act.HIDE)
retry = 0
while True:
try:
callGAPI(drive.drives(), 'hide', callGAPI(drive.drives(), 'hide',
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.FORBIDDEN], throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.FORBIDDEN],
driveId=driveId) driveId=driveId)
if not returnIdOnly and not csvPF: if not returnIdOnly and not csvPF:
entityActionPerformed([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], i, count) entityActionPerformed([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], i, count)
break
except GAPI.notFound as e:
retry += 1
if retry > errorRetries:
entityActionFailedWarning([Ent.USER, user, Ent.REQUEST_ID, requestId], str(e), i, count)
break
waitingForCreationToComplete(updateRetryDelay)
if orgUnit: if orgUnit:
ci = _moveSharedDriveToOU(orgUnit, orgUnitId, driveId, user, i, count, ci, returnIdOnly) waitingForCreationToComplete(moveToOrgUnitDelay)
except (GAPI.forbidden, GAPI.badRequest, GAPI.noManageTeamDriveAdministratorPrivilege) as e: ci = _moveSharedDriveToOU(orgUnit, orgUnitId, driveId, user, i, count, ci, returnIdOnly or csvPF)
except (GAPI.notFound, GAPI.forbidden, GAPI.badRequest, GAPI.noManageTeamDriveAdministratorPrivilege) as e:
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], str(e), i, count) entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], str(e), i, count)
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count) userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
@ -61594,6 +61597,8 @@ def createSharedDrive(users, useDomainAdminAccess=False):
# [(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])] # [(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])]
# (<SharedDriveRestrictionsFieldName> <Boolean>)* # (<SharedDriveRestrictionsFieldName> <Boolean>)*
# [hide|hidden <Boolean>] # [hide|hidden <Boolean>]
# [errorretries <Integer>] [updateinitialdelay <Integer>] [updateretrydelay <Integer>]
# [movetoorgunitdelay <Integer>]
# [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly] # [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly]
def doCreateSharedDrive(): def doCreateSharedDrive():
createSharedDrive([_getAdminEmail()], True) createSharedDrive([_getAdminEmail()], True)
@ -61750,6 +61755,36 @@ SHAREDDRIVE_LIST_FIELDS_CHOICE_MAP = {
'ou': 'orgUnitId', 'ou': 'orgUnitId',
} }
SHAREDDRIVE_TIME_OBJECTS = {'createdTime'} SHAREDDRIVE_TIME_OBJECTS = {'createdTime'}
SHAREDDRIVE_ROLES_CAPABILITIES_MAP = {
'commenter': {'canComment': True, 'canEdit': False},
'reader': {'canComment': False, 'canEdit': False},
'writer': {'canEdit': True, 'canTrashChildren': False},
'fileOrganizer': {'canTrashChildren': True, 'canManageMembers': False},
'organizer': {'canManageMembers': True},
}
SHAREDDRIVE_API_GUI_ROLES_MAP = {
'commenter': 'Commenter',
'fileOrganizer': 'Content manager',
'organizer': 'Manager',
'reader': 'Viewer',
'writer': 'Contributor',
'unknown': 'Unknown'
}
def _getSharedDriveRole(shareddrive):
if 'capabilities' not in shareddrive:
return None
for role, capabilities in iter(SHAREDDRIVE_ROLES_CAPABILITIES_MAP.items()):
match = True
for capability in capabilities:
if capabilities[capability] != shareddrive['capabilities'].get(capability, ''):
match = False
break
if match:
break
else:
role = 'unknown'
return role
def _showSharedDrive(user, shareddrive, j, jcount, FJQC): def _showSharedDrive(user, shareddrive, j, jcount, FJQC):
def _showCapabilitiesRestrictions(field): def _showCapabilitiesRestrictions(field):
@ -61780,17 +61815,23 @@ def _showSharedDrive(user, shareddrive, j, jcount, FJQC):
_showCapabilitiesRestrictions('restrictions') _showCapabilitiesRestrictions('restrictions')
Ind.Decrement() Ind.Decrement()
# gam <UserTypeEntity> info shareddrive <SharedDriveEntity> [adminaccess|asadmin] [fields <SharedDriveFieldNameList>] [formatjson] # gam <UserTypeEntity> info shareddrive <SharedDriveEntity>
# [adminaccess|asadmin]
# [fields <SharedDriveFieldNameList>]
# [guiroles [<Boolean>]] [formatjson]
def infoSharedDrive(users, useDomainAdminAccess=False): def infoSharedDrive(users, useDomainAdminAccess=False):
fileIdEntity = getSharedDriveEntity() fileIdEntity = getSharedDriveEntity()
fieldsList = [] fieldsList = []
FJQC = FormatJSONQuoteChar() FJQC = FormatJSONQuoteChar()
guiRoles = False
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg in ADMIN_ACCESS_OPTIONS: if myarg in ADMIN_ACCESS_OPTIONS:
useDomainAdminAccess = True useDomainAdminAccess = True
elif getFieldsList(myarg, SHAREDDRIVE_FIELDS_CHOICE_MAP, fieldsList, initialField=['id', 'name']): elif getFieldsList(myarg, SHAREDDRIVE_FIELDS_CHOICE_MAP, fieldsList, initialField=['id', 'name']):
pass pass
elif myarg == 'guiroles':
guiRoles = getBoolean()
else: else:
FJQC.GetFormatJSON(myarg) FJQC.GetFormatJSON(myarg)
fields = ','.join(set(fieldsList)) if fieldsList else '*' fields = ','.join(set(fieldsList)) if fieldsList else '*'
@ -61806,6 +61847,9 @@ def infoSharedDrive(users, useDomainAdminAccess=False):
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.NOT_FOUND], throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.NOT_FOUND],
useDomainAdminAccess=useDomainAdminAccess, useDomainAdminAccess=useDomainAdminAccess,
driveId=driveId, fields=fields) driveId=driveId, fields=fields)
role = _getSharedDriveRole(shareddrive)
if role:
shareddrive['role'] = role if not guiRoles else SHAREDDRIVE_API_GUI_ROLES_MAP[role]
_showSharedDrive(user, shareddrive, i, count, FJQC) _showSharedDrive(user, shareddrive, i, count, FJQC)
except GAPI.notFound as e: except GAPI.notFound as e:
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], str(e), i, count) entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, driveId], str(e), i, count)
@ -61832,26 +61876,18 @@ SHAREDDRIVE_ACL_ROLES_MAP = {
'writer': 'writer', 'writer': 'writer',
} }
SHAREDDRIVE_ROLES_CAPABILITIES_MAP = {
'commenter': {'canComment': True, 'canEdit': False},
'fileOrganizer': {'canAddChildren': True, 'canManageMembers': False},
'organizer': {'canManageMembers': True},
'reader': {'canEdit': False, 'canComment': False},
'writer': {'canEdit': True, 'canManageMembers': False},
}
# gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*] # gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*]
# [adminaccess|asadmin [shareddriveadminquery|query <QuerySharedDrive>]] # [adminaccess|asadmin [shareddriveadminquery|query <QuerySharedDrive>]]
# [matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>] # [matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>]
# (role|roles <SharedDriveACLRoleList>)* # (role|roles <SharedDriveACLRoleList>)*
# [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]] # [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
# [formatjson [quotechar <Character>]] # [guiroles [<Boolean>]] [formatjson [quotechar <Character>]]
# gam <UserTypeEntity> show shareddrives # gam <UserTypeEntity> show shareddrives
# [adminaccess|asadmin [shareddriveadminquery|query <QuerySharedDrive>]] # [adminaccess|asadmin [shareddriveadminquery|query <QuerySharedDrive>]]
# [matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>] # [matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>]
# (role|roles <SharedDriveACLRoleLIst>)* # (role|roles <SharedDriveACLRoleLIst>)*
# [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]] # [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
# [formatjson] # [guiroles [<Boolean>]] [formatjson]
def printShowSharedDrives(users, useDomainAdminAccess=False): def printShowSharedDrives(users, useDomainAdminAccess=False):
def stripNonShowFields(shareddrive): def stripNonShowFields(shareddrive):
if orgUnitIdToPathMap: if orgUnitIdToPathMap:
@ -61875,6 +61911,7 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
SHAREDDRIVE_FIELDS_CHOICE_MAP.update(SHAREDDRIVE_LIST_FIELDS_CHOICE_MAP) SHAREDDRIVE_FIELDS_CHOICE_MAP.update(SHAREDDRIVE_LIST_FIELDS_CHOICE_MAP)
showOrgUnitPaths = True showOrgUnitPaths = True
orgUnitIdToPathMap = None orgUnitIdToPathMap = None
guiRoles = False
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if csvPF and myarg == 'todrive': if csvPF and myarg == 'todrive':
@ -61902,6 +61939,8 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
pass pass
elif myarg == 'noorgunits': elif myarg == 'noorgunits':
showOrgUnitPaths = not getBoolean() showOrgUnitPaths = not getBoolean()
elif myarg == 'guiroles':
guiRoles = getBoolean()
else: else:
FJQC.GetFormatJSONQuoteChar(myarg, True) FJQC.GetFormatJSONQuoteChar(myarg, True)
if query and not useDomainAdminAccess: if query and not useDomainAdminAccess:
@ -61953,18 +61992,9 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
for shareddrive in feed: for shareddrive in feed:
if matchPattern is not None and matchPattern.match(shareddrive['name']) is None: if matchPattern is not None and matchPattern.match(shareddrive['name']) is None:
continue continue
for role, capabilities in iter(SHAREDDRIVE_ROLES_CAPABILITIES_MAP.items()): role = _getSharedDriveRole(shareddrive)
match = True
for capability in capabilities:
if capabilities[capability] != shareddrive['capabilities'][capability]:
match = False
break
if match:
break
else:
role = 'unknown'
if not roles or role in roles: if not roles or role in roles:
shareddrive['role'] = role shareddrive['role'] = role if not guiRoles else SHAREDDRIVE_API_GUI_ROLES_MAP[role]
matchedFeed.append(shareddrive) matchedFeed.append(shareddrive)
elif matchPattern is not None or orgUnitId is not None: elif matchPattern is not None or orgUnitId is not None:
for shareddrive in feed: for shareddrive in feed:
@ -61995,7 +62025,7 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
if FJQC.formatJSON: if FJQC.formatJSON:
row = {'User': user, 'id': shareddrive['id'], 'name': shareddrive['name']} row = {'User': user, 'id': shareddrive['id'], 'name': shareddrive['name']}
if not useDomainAdminAccess: if not useDomainAdminAccess:
row['role'] = shareddrive['role'] row['role'] = shareddrive['role'] if not guiRoles else SHAREDDRIVE_API_GUI_ROLES_MAP[shareddrive['role']]
row['JSON'] = json.dumps(cleanJSON(shareddrive, timeObjects=SHAREDDRIVE_TIME_OBJECTS), ensure_ascii=False, sort_keys=True) row['JSON'] = json.dumps(cleanJSON(shareddrive, timeObjects=SHAREDDRIVE_TIME_OBJECTS), ensure_ascii=False, sort_keys=True)
csvPF.WriteRow(row) csvPF.WriteRow(row)
else: else:

View File

@ -276,6 +276,7 @@ YOUTUBE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR, UNSUPPORTED_SUPERVIS
REASON_MESSAGE_MAP = { REASON_MESSAGE_MAP = {
ABORTED: [ ABORTED: [
('Label name exists or conflicts', DUPLICATE), ('Label name exists or conflicts', DUPLICATE),
('The operation was aborted', ABORTED),
], ],
CONDITION_NOT_MET: [ CONDITION_NOT_MET: [
('Cyclic memberships not allowed', CYCLIC_MEMBERSHIPS_NOT_ALLOWED), ('Cyclic memberships not allowed', CYCLIC_MEMBERSHIPS_NOT_ALLOWED),