Update vault (#564)

This commit is contained in:
Ross Scroggs
2017-09-10 16:40:25 -07:00
committed by Jay Lee
parent e8e9e599f8
commit bafc648c9d
2 changed files with 93 additions and 51 deletions

View File

@@ -83,7 +83,7 @@ Named items
<CourseID> ::= <Number>|d:<CourseAlias> <CourseID> ::= <Number>|d:<CourseAlias>
<CourseParticipantType> ::= teacher|teachers|student|students <CourseParticipantType> ::= teacher|teachers|student|students
<CrOSID> ::= <String> <CrOSID> ::= <String>
<CrOSItem> ::= <CrOSID>|(query:<QueryCrOS>) <CrOSItem> ::= <CrOSID>|(query:<QueryCrOS>)(query:orgunitpath:<OrgUnitPath>)
<CustomerID> ::= <String> <CustomerID> ::= <String>
<DomainAlias> ::= <String> <DomainAlias> ::= <String>
<DriveFileACLRole> :: =commenter|editor|organizer|owner|reader|writer <DriveFileACLRole> :: =commenter|editor|organizer|owner|reader|writer
@@ -462,7 +462,11 @@ Item attributes
(summary <String>)|(description <String>)|(location <String>)|(timezone <String>) (summary <String>)|(description <String>)|(location <String>)|(timezone <String>)
<CourseAttributes> ::= <CourseAttributes> ::=
(name <String>)|(section <string>)|(heading <String>)|(room <String>)|(description <String>)| (description <String>)|
(heading <String>)|
(name <String>)|
(room <String>)|
(section <string>)|
(state|status active|archived|provisioned|declined) (state|status active|archived|provisioned|declined)
<CrOSAttributes> ::= <CrOSAttributes> ::=
@@ -849,8 +853,11 @@ gam print vaultholds|holds [todrive] [matters <MatterItemList>]
gam create vaultmatter|matter [name <String>] [description <string>] gam create vaultmatter|matter [name <String>] [description <string>]
[collaborator|collaborators <CollaboratorItemList>] [collaborator|collaborators <CollaboratorItemList>]
gam update vaultmatter|matter <MatterItem> [action close|reopen|delete|undelete] [name <String>] [description <string>] gam update vaultmatter|matter <MatterItem> [name <String>] [description <string>]
[addcollaborator|addcollaborators <CollaboratorItemList>] [removecollaborator|removecollaborators <CollaboratorItemList>] [addcollaborator|addcollaborators <CollaboratorItemList>] [removecollaborator|removecollaborators <CollaboratorItemList>]
gam update vaultmatter|matter <MatterItem> action close|reopen|delete|undelete
gam close vaultmatter|matter <MatterItem>
gam reopen vaultmatter|matter <MatterItem>
gam delete vaultmatter|matter <MatterItem> gam delete vaultmatter|matter <MatterItem>
gam undelete vaultmatter|matter <MatterItem> gam undelete vaultmatter|matter <MatterItem>
gam info vaultmatter|matter <MatterItem> gam info vaultmatter|matter <MatterItem>
@@ -892,9 +899,9 @@ gam <UserTypeEntity> delete|del emptydrivefolders
gam <UserTypeEntity> empty drivetrash gam <UserTypeEntity> empty drivetrash
gam <UserTypeEntity> add drivefileacl <DriveFileID> anyone|(user <UserItem>)|(group <GroupItem>)|(domain <DomainName>) gam <UserTypeEntity> add drivefileacl <DriveFileID> anyone|(user <UserItem>)|(group <GroupItem>)|(domain <DomainName>)
(role <DriveFileACLRole>) [withlink|discoverable] [sendemail] [emailmessage <String>] (role <DriveFileACLRole>) [withlink|discoverable] [expires <Time>] [sendemail] [emailmessage <String>]
gam <UserTypeEntity> update drivefileacl <DriveFileID> <PermissionID> gam <UserTypeEntity> update drivefileacl <DriveFileID> <PermissionID>
(role <DriveFileACLRole>) [withlink|discoverable] [removeexpiration] (role <DriveFileACLRole>) [withlink|discoverable] [expires <Time>] [removeexpiration]
gam <UserTypeEntity> delete|del drivefileacl <DriveFileID> <PermissionID> gam <UserTypeEntity> delete|del drivefileacl <DriveFileID> <PermissionID>
gam <UserTypeEntity> show drivefileacl <DriveFileID> gam <UserTypeEntity> show drivefileacl <DriveFileID>

View File

@@ -874,21 +874,31 @@ def buildGAPIObject(api):
GC_Values[GC_CUSTOMER_ID] = MY_CUSTOMER GC_Values[GC_CUSTOMER_ID] = MY_CUSTOMER
return service return service
# Convert User UID to email address # Convert UID to email address
def convertUserUIDtoEmailAddress(emailAddressOrUID, cd=None): def convertUIDtoEmailAddress(emailAddressOrUID, cd=None, email_type=u'user'):
normalizedEmailAddressOrUID = normalizeEmailAddressOrUID(emailAddressOrUID) normalizedEmailAddressOrUID = normalizeEmailAddressOrUID(emailAddressOrUID)
if normalizedEmailAddressOrUID.find(u'@') > 0: if normalizedEmailAddressOrUID.find(u'@') > 0:
return normalizedEmailAddressOrUID return normalizedEmailAddressOrUID
try: if not cd:
if not cd: cd = buildGAPIObject(u'directory')
cd = buildGAPIObject(u'directory') if email_type == u'user':
result = callGAPI(cd.users(), u'get', try:
throw_reasons=[GAPI_USER_NOT_FOUND], result = callGAPI(cd.users(), u'get',
userKey=normalizedEmailAddressOrUID, fields=u'primaryEmail') throw_reasons=[GAPI_USER_NOT_FOUND],
if u'primaryEmail' in result: userKey=normalizedEmailAddressOrUID, fields=u'primaryEmail')
return result[u'primaryEmail'].lower() if u'primaryEmail' in result:
except GAPI_userNotFound: return result[u'primaryEmail'].lower()
pass except GAPI_userNotFound:
pass
else:
try:
result = callGAPI(cd.groups(), u'get',
throw_reasons=[GAPI_GROUP_NOT_FOUND],
groupKey=normalizedEmailAddressOrUID, fields=u'email')
if u'email' in result:
return result[u'email'].lower()
except GAPI_groupNotFound:
pass
return normalizedEmailAddressOrUID return normalizedEmailAddressOrUID
# Convert email address to UID # Convert email address to UID
@@ -974,7 +984,7 @@ def buildGAPIServiceObject(api, act_as, use_scopes=None):
return service return service
def buildActivityGAPIObject(user): def buildActivityGAPIObject(user):
userEmail = convertUserUIDtoEmailAddress(user) userEmail = convertUIDtoEmailAddress(user)
return (userEmail, buildGAPIServiceObject(u'appsactivity', userEmail)) return (userEmail, buildGAPIServiceObject(u'appsactivity', userEmail))
def normalizeCalendarId(calname, checkPrimary=False): def normalizeCalendarId(calname, checkPrimary=False):
@@ -983,7 +993,7 @@ def normalizeCalendarId(calname, checkPrimary=False):
return calname return calname
if not GC_Values[GC_DOMAIN]: if not GC_Values[GC_DOMAIN]:
GC_Values[GC_DOMAIN] = _getValueFromOAuth(u'hd') GC_Values[GC_DOMAIN] = _getValueFromOAuth(u'hd')
return convertUserUIDtoEmailAddress(calname) return convertUIDtoEmailAddress(calname)
def buildCalendarGAPIObject(calname): def buildCalendarGAPIObject(calname):
calendarId = normalizeCalendarId(calname) calendarId = normalizeCalendarId(calname)
@@ -999,19 +1009,19 @@ def buildCalendarDataGAPIObject(calname):
return (calendarId, cal) return (calendarId, cal)
def buildDriveGAPIObject(user): def buildDriveGAPIObject(user):
userEmail = convertUserUIDtoEmailAddress(user) userEmail = convertUIDtoEmailAddress(user)
return (userEmail, buildGAPIServiceObject(u'drive', userEmail)) return (userEmail, buildGAPIServiceObject(u'drive', userEmail))
def buildDrive3GAPIObject(user): def buildDrive3GAPIObject(user):
userEmail = convertUserUIDtoEmailAddress(user) userEmail = convertUIDtoEmailAddress(user)
return (userEmail, buildGAPIServiceObject(u'drive3', userEmail)) return (userEmail, buildGAPIServiceObject(u'drive3', userEmail))
def buildGmailGAPIObject(user): def buildGmailGAPIObject(user):
userEmail = convertUserUIDtoEmailAddress(user) userEmail = convertUIDtoEmailAddress(user)
return (userEmail, buildGAPIServiceObject(u'gmail', userEmail)) return (userEmail, buildGAPIServiceObject(u'gmail', userEmail))
def buildGplusGAPIObject(user): def buildGplusGAPIObject(user):
userEmail = convertUserUIDtoEmailAddress(user) userEmail = convertUIDtoEmailAddress(user)
return (userEmail, buildGAPIServiceObject(u'plus', userEmail)) return (userEmail, buildGAPIServiceObject(u'plus', userEmail))
def doCheckServiceAccount(users): def doCheckServiceAccount(users):
@@ -2258,7 +2268,7 @@ def doGetCourseInfo():
if not courseId.isdigit() and courseId[:2] != u'd:': if not courseId.isdigit() and courseId[:2] != u'd:':
courseId = u'd:%s' % courseId courseId = u'd:%s' % courseId
info = callGAPI(croom.courses(), u'get', id=courseId) info = callGAPI(croom.courses(), u'get', id=courseId)
info['ownerEmail'] = convertUserUIDtoEmailAddress(u'uid:%s' % info['ownerId']) info['ownerEmail'] = convertUIDtoEmailAddress(u'uid:%s' % info['ownerId'])
print_json(None, info) print_json(None, info)
teachers = callGAPIpages(croom.courses().teachers(), u'list', u'teachers', courseId=courseId) teachers = callGAPIpages(croom.courses().teachers(), u'list', u'teachers', courseId=courseId)
students = callGAPIpages(croom.courses().students(), u'list', u'students', courseId=courseId) students = callGAPIpages(croom.courses().students(), u'list', u'students', courseId=courseId)
@@ -7256,7 +7266,6 @@ def doCreateVaultHold():
body[u'name'] = sys.argv[i+1] body[u'name'] = sys.argv[i+1]
i += 2 i += 2
elif myarg == u'query': elif myarg == u'query':
body[u'query'] = {}
query = sys.argv[i+1] query = sys.argv[i+1]
i += 2 i += 2
elif myarg == u'corpus': elif myarg == u'corpus':
@@ -7293,13 +7302,21 @@ def doCreateVaultHold():
if not matterId: if not matterId:
print u'ERROR: you must specify a matter for the new hold.' print u'ERROR: you must specify a matter for the new hold.'
sys.exit(3) sys.exit(3)
if not body[u'corpus']: if not body.get(u'name'):
print u'ERROR: you must specify corpus for the hold. One of %s' % (u', '.join(allowed_corpuses)) print u'ERROR: you must specify a name for the new hold.'
sys.exit(3)
if not body.get(u'corpus'):
print u'ERROR: you must specify corpus for the new hold. One of %s' % (u', '.join(allowed_corpuses))
sys.exit(3) sys.exit(3)
query_type = u'%sQuery' % body[u'corpus'].lower() query_type = u'%sQuery' % body[u'corpus'].lower()
body[u'query'][query_type] = {} body[u'query'][query_type] = {}
if body[u'corpus'] == u'DRIVE' and query: if body[u'corpus'] == u'DRIVE':
body[u'query'][query_type] = json.loads(query) if query:
try:
body[u'query'][query_type] = json.loads(query)
except ValueError as e:
print u'Error: {0}, query: {1}'.format(str(e), query)
sys.exit(3)
elif body[u'corpus'] in [u'GROUPS', u'MAIL']: elif body[u'corpus'] in [u'GROUPS', u'MAIL']:
if query: if query:
body[u'query'][query_type] = {u'terms': query} body[u'query'][query_type] = {u'terms': query}
@@ -7310,10 +7327,7 @@ def doCreateVaultHold():
if accounts: if accounts:
body[u'accounts'] = [] body[u'accounts'] = []
cd = buildGAPIObject(u'directory') cd = buildGAPIObject(u'directory')
if body[u'corpus'] == u'GROUPS': account_type = u'group' if body[u'corpus'] == u'GROUPS' else u'user'
account_type = u'group'
else:
account_type = u'user'
for account in accounts: for account in accounts:
body[u'accounts'].append({u'accountId': convertEmailAddressToUID(account, cd, account_type)}) body[u'accounts'].append({u'accountId': convertEmailAddressToUID(account, cd, account_type)})
callGAPI(v.matters().holds(), u'create', matterId=matterId, body=body) callGAPI(v.matters().holds(), u'create', matterId=matterId, body=body)
@@ -7370,10 +7384,11 @@ def doGetVaultHoldInfo():
results = callGAPI(v.matters().holds(), u'get', matterId=matterId, holdId=holdId) results = callGAPI(v.matters().holds(), u'get', matterId=matterId, holdId=holdId)
cd = buildGAPIObject(u'directory') cd = buildGAPIObject(u'directory')
if u'accounts' in results: if u'accounts' in results:
account_type = u'group' if results[u'corpus'] == u'GROUPS' else u'user'
for i in range(0, len(results[u'accounts'])): for i in range(0, len(results[u'accounts'])):
uid = u'uid:%s' % results[u'accounts'][i][u'accountId'] uid = u'uid:%s' % results[u'accounts'][i][u'accountId']
user_email = convertUserUIDtoEmailAddress(uid, cd) acct_email = convertUIDtoEmailAddress(uid, cd, account_type)
results[u'accounts'][i][u'email'] = user_email results[u'accounts'][i][u'email'] = acct_email
if u'orgUnit' in results: if u'orgUnit' in results:
results[u'orgUnit'][u'orgUnitPath'] = doGetOrgInfo(results[u'orgUnit'][u'orgUnitId'], return_attrib=u'orgUnitPath') results[u'orgUnit'][u'orgUnitPath'] = doGetOrgInfo(results[u'orgUnit'][u'orgUnitId'], return_attrib=u'orgUnitPath')
print_json(None, results) print_json(None, results)
@@ -7451,7 +7466,7 @@ def doUpdateVaultHold():
if not matterId: if not matterId:
print u'ERROR: you must specify a matter for the hold.' print u'ERROR: you must specify a matter for the hold.'
sys.exit(3) sys.exit(3)
if query or start_time or end_time or body[u'orgUnit']: if query or start_time or end_time or body.get(u'orgUnit'):
old_body = callGAPI(v.matters().holds(), u'get', matterId=matterId, holdId=holdId, fields=u'corpus,query,orgUnit') old_body = callGAPI(v.matters().holds(), u'get', matterId=matterId, holdId=holdId, fields=u'corpus,query,orgUnit')
body[u'query'] = old_body[u'query'] body[u'query'] = old_body[u'query']
body[u'corpus'] = old_body[u'corpus'] body[u'corpus'] = old_body[u'corpus']
@@ -7459,14 +7474,20 @@ def doUpdateVaultHold():
# bah, API requires this to be sent on update even when it's not changing # bah, API requires this to be sent on update even when it's not changing
body[u'orgUnit'] = old_body[u'orgUnit'] body[u'orgUnit'] = old_body[u'orgUnit']
query_type = '%sQuery' % body[u'corpus'].lower() query_type = '%sQuery' % body[u'corpus'].lower()
if body[u'corpus'] == u'DRIVE' and query: if body[u'corpus'] == u'DRIVE':
body[u'query'][query_type] = json.loads(query) if query:
elif body[u'corpus'] in [u'GROUPS', u'MAIL'] and query: try:
body[u'query'][query_type][u'terms'] = query body[u'query'][query_type] = json.loads(query)
if start_time: except ValueError as e:
body[u'query'][query_type][u'startTime'] = start_time print u'Error: {0}, query: {1}'.format(str(e), query)
if end_time: sys.exit(3)
body[u'query'][query_type][u'endTime'] = end_time elif body[u'corpus'] in [u'GROUPS', u'MAIL']:
if query:
body[u'query'][query_type][u'terms'] = query
if start_time:
body[u'query'][query_type][u'startTime'] = start_time
if end_time:
body[u'query'][query_type][u'endTime'] = end_time
if body: if body:
print u'Updating hold %s / %s' % (hold, holdId) print u'Updating hold %s / %s' % (hold, holdId)
callGAPI(v.matters().holds(), u'update', matterId=matterId, holdId=holdId, body=body) callGAPI(v.matters().holds(), u'update', matterId=matterId, holdId=holdId, body=body)
@@ -7498,7 +7519,7 @@ def doUpdateVaultMatter(action=None):
if myarg == u'action': if myarg == u'action':
action = sys.argv[i+1].lower() action = sys.argv[i+1].lower()
if action not in VAULT_MATTER_ACTIONS: if action not in VAULT_MATTER_ACTIONS:
print u'ERROR: allowed actions are %s, got %s' % (u', '.join(VAULT_MATTER_ACTIONS), sys.argv[i]) print u'ERROR: allowed actions are %s, got %s' % (u', '.join(VAULT_MATTER_ACTIONS), action)
sys.exit(3) sys.exit(3)
i += 2 i += 2
elif myarg == u'name': elif myarg == u'name':
@@ -7524,6 +7545,11 @@ def doUpdateVaultMatter(action=None):
action_kwargs = {} action_kwargs = {}
if body: if body:
print u'Updating matter %s...' % sys.argv[3] print u'Updating matter %s...' % sys.argv[3]
if u'name' not in body or u'description' not in body:
# bah, API requires name/description to be sent on update even when it's not changing
result = callGAPI(v.matters(), u'get', matterId=matterId, view=u'BASIC')
body.setdefault(u'name', result[u'name'])
body.setdefault(u'description', result.get(u'description'))
callGAPI(v.matters(), u'update', body=body, matterId=matterId) callGAPI(v.matters(), u'update', body=body, matterId=matterId)
if action: if action:
print u'Performing %s on matter %s' % (action, sys.argv[3]) print u'Performing %s on matter %s' % (action, sys.argv[3])
@@ -7543,7 +7569,7 @@ def doGetVaultMatterInfo():
cd = buildGAPIObject(u'directory') cd = buildGAPIObject(u'directory')
for i in range(0, len(result[u'matterPermissions'])): for i in range(0, len(result[u'matterPermissions'])):
uid = u'uid:%s' % result[u'matterPermissions'][i][u'accountId'] uid = u'uid:%s' % result[u'matterPermissions'][i][u'accountId']
user_email = convertUserUIDtoEmailAddress(uid, cd) user_email = convertUIDtoEmailAddress(uid, cd)
result[u'matterPermissions'][i][u'email'] = user_email result[u'matterPermissions'][i][u'email'] = user_email
print_json(None, result) print_json(None, result)
@@ -8144,7 +8170,7 @@ def doUpdateCros():
for move_body in move_bodys: for move_body in move_bodys:
print u' moving %s devices to %s' % (len(move_body[u'deviceIds']), orgUnitPath) print u' moving %s devices to %s' % (len(move_body[u'deviceIds']), orgUnitPath)
result = callGAPI(cd.chromeosdevices(), u'moveDevicesToOu', customerId=GC_Values[GC_CUSTOMER_ID], orgUnitPath=orgUnitPath, result = callGAPI(cd.chromeosdevices(), u'moveDevicesToOu', customerId=GC_Values[GC_CUSTOMER_ID], orgUnitPath=orgUnitPath,
body=move_body) body=move_body)
def doUpdateMobile(): def doUpdateMobile():
cd = buildGAPIObject(u'directory') cd = buildGAPIObject(u'directory')
@@ -10311,7 +10337,7 @@ def doPrintVaultHolds():
v = buildGAPIObject(u'vault') v = buildGAPIObject(u'vault')
todrive = False todrive = False
csvRows = [] csvRows = []
initialTitles = [u'matterId', u'holdId', u'name', u'updateTime'] initialTitles = [u'matterId', u'holdId', u'name', u'corpus', u'updateTime']
titles = initialTitles[:] titles = initialTitles[:]
matters = [] matters = []
matterIds = [] matterIds = []
@@ -10321,7 +10347,7 @@ def doPrintVaultHolds():
if myarg == u'todrive': if myarg == u'todrive':
todrive = True todrive = True
i += 1 i += 1
elif myarg == u'matters': elif myarg in [u'matter', u'matters']:
matters = sys.argv[i+1].split(u',') matters = sys.argv[i+1].split(u',')
i += 2 i += 2
else: else:
@@ -11641,7 +11667,7 @@ def ProcessGAMCommand(args):
elif argument in [u'resoldsubscription', u'resellersubscription']: elif argument in [u'resoldsubscription', u'resellersubscription']:
doDeleteResoldSubscription() doDeleteResoldSubscription()
elif argument in [u'matter', u'vaultmatter']: elif argument in [u'matter', u'vaultmatter']:
doUpdateVaultMatter(action=u'delete') doUpdateVaultMatter(action=command)
elif argument in [u'hold', u'vaulthold']: elif argument in [u'hold', u'vaulthold']:
doDeleteVaultHold() doDeleteVaultHold()
else: else:
@@ -11653,11 +11679,20 @@ def ProcessGAMCommand(args):
if argument == u'user': if argument == u'user':
doUndeleteUser() doUndeleteUser()
elif argument in [u'matter', u'vaultmatter']: elif argument in [u'matter', u'vaultmatter']:
doUpdateVaultMatter(action=u'undelete') doUpdateVaultMatter(action=command)
else: else:
print u'ERROR: %s is not a valid argument for "gam undelete"' % argument print u'ERROR: %s is not a valid argument for "gam undelete"' % argument
sys.exit(2) sys.exit(2)
sys.exit(0) sys.exit(0)
elif command in [u'close', u'reopen']:
# close and reopen will have to be split apart if either takes a new argument
argument = sys.argv[2].lower()
if argument in [u'matter', u'vaultmatter']:
doUpdateVaultMatter(action=command)
else:
print u'ERROR: %s is not a valid argument for "gam %s"' % (argument, command)
sys.exit(2)
sys.exit(0)
elif command == u'print': elif command == u'print':
argument = sys.argv[2].lower().replace(u'-', u'') argument = sys.argv[2].lower().replace(u'-', u'')
if argument == u'users': if argument == u'users':