mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-05 06:41:38 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8db37786c | ||
|
|
79bc1065f3 | ||
|
|
b107afc13c | ||
|
|
fcfbf0a733 | ||
|
|
8460a7a87d | ||
|
|
2940dd71ab | ||
|
|
135ebaa251 | ||
|
|
f94b3eb383 | ||
|
|
a3db496f31 | ||
|
|
dd78c05d59 | ||
|
|
d9c4326a6b |
@@ -41,14 +41,14 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<FileFormat> ::=
|
||||
csv|html|txt|tsv|jpeg|jpg|png|svg|pdf|rtf|pptx|xlsx|docx|odt|ods|openoffice|ms|microsoft|micro$oft
|
||||
<LabelColorHex> ::=
|
||||
#000000|#076239|#0b804b|#149e60|#16a766|#1a764d|#1c4587|#285bac|
|
||||
#2a9c68|#3c78d8|#3dc789|#41236d|#434343|#43d692|#44b984|#4a86e8|
|
||||
#653e9b|#666666|#68dfa9|#6d9eeb|#822111|#83334c|#89d3b2|#8e63ce|
|
||||
#999999|#a0eac9|#a46a21|#a479e2|#a4c2f4|#aa8831|#ac2b16|#b65775|
|
||||
#b694e8|#b9e4d0|#c6f3de|#c9daf8|#cc3a21|#cccccc|#cf8933|#d0bcf1|
|
||||
#d5ae49|#e07798|#e4d7f5|#e66550|#eaa041|#efa093|#efefef|#f2c960|
|
||||
#f3f3f3|#f691b3|#f6c5be|#f7a7c0|#fad165|#fb4c2f|#fbc8d9|#fcda83|
|
||||
#fcdee8|#fce8b3|#fef1d1|#ffad47|#ffbc6b|#ffd6a2|#ffe6c7|#ffffff
|
||||
#000000|#076239|#0b804b|#149e60|#16a766|#1a764d|#1c4587|#285bac|
|
||||
#2a9c68|#3c78d8|#3dc789|#41236d|#434343|#43d692|#44b984|#4a86e8|
|
||||
#653e9b|#666666|#68dfa9|#6d9eeb|#822111|#83334c|#89d3b2|#8e63ce|
|
||||
#999999|#a0eac9|#a46a21|#a479e2|#a4c2f4|#aa8831|#ac2b16|#b65775|
|
||||
#b694e8|#b9e4d0|#c6f3de|#c9daf8|#cc3a21|#cccccc|#cf8933|#d0bcf1|
|
||||
#d5ae49|#e07798|#e4d7f5|#e66550|#eaa041|#efa093|#efefef|#f2c960|
|
||||
#f3f3f3|#f691b3|#f6c5be|#f7a7c0|#fad165|#fb4c2f|#fbc8d9|#fcda83|
|
||||
#fcdee8|#fce8b3|#fef1d1|#ffad47|#ffbc6b|#ffd6a2|#ffe6c7|#ffffff
|
||||
<Language> ::=
|
||||
ach|af|ag|ak|am|ar|az|be|bem|bg|bn|br|bs|ca|chr|ckb|co|crs|cs|cy|da|de|ee|el|en|en-gb|en-us|eo|es|es-419|et|eu|
|
||||
fa|fi|fo|fr|fr-ca|fy|ga|gaa|gd|gl|gn|gu|ha|haw|he|hi|hr|ht|hu|hy|ia|id|ig|in|is|it|iw|ja|jw|
|
||||
@@ -136,6 +136,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<CalendarACLRole> ::= editor|freebusy|freebusyreader|owner|reader|writer
|
||||
<CalendarColorIndex> ::= <Number in range 1-24>
|
||||
<CalendarItem> ::= <EmailAddress>|<String>
|
||||
<ChatRoom> ::= <String>
|
||||
<ClientID> ::= <String>
|
||||
<ColorValue> ::= <ColorName>|<ColorHex>
|
||||
<CollaboratorItem> ::= <EmailAddress>|<UniqueID>|<String>
|
||||
@@ -144,7 +145,6 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<CourseParticipantType> ::= teacher|teachers|student|students
|
||||
<CourseState> ::= active|archived|provisioned|declined
|
||||
<CrOSID> ::= <String>
|
||||
<CrOSItem> ::= <CrOSID>|(query:<QueryCrOS>)|(query:orgunitpath:<OrgUnitPath>)
|
||||
<CustomerID> ::= <String>
|
||||
<DomainAlias> ::= <String>
|
||||
<DriveFileACLRole> ::= commenter|editor|organizer|owner|reader|writer
|
||||
@@ -157,6 +157,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<EmailItem> ::= <EmailAddress>|<UniqueID>|<String>
|
||||
<EventColorIndex> ::= <Number in range 1-11>
|
||||
<EventID> ::= <String>
|
||||
<ExportItem> ::= <UniqueID>|<String>
|
||||
<FeatureName> ::= <String>
|
||||
<FieldName> ::= <String>
|
||||
<FileName> ::= <String>
|
||||
@@ -209,6 +210,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<RoleAssignmentID> ::= <String>
|
||||
<SchemaName> ::= <String>
|
||||
<Section> ::= <String>
|
||||
<SerialNumber> ::= <String>
|
||||
<S/MIMEID> ::= <String>
|
||||
<StudentItem> ::= <EmailAddress>|<UniqueID>|<String>
|
||||
<TeamDriveID> ::= <String>
|
||||
@@ -512,12 +514,13 @@ Items, separated by spaces, with spaces, commas or single quotes in the items th
|
||||
<ACLList> ::= "<ACLScope>(,<ACLScope>)*"
|
||||
<ASPIDList> ::= "<ASPID>(,<ASPID>)*"
|
||||
<CalendarList> ::= "<CalendarItem>(,<CalendarItem>)*"
|
||||
<ChatRoomList> ::= "<ChatRoom>(,<ChatRoom>)*"
|
||||
<CollaboratorItemList> ::= "<CollaboratorItem>(,<CollaboratorItem>)*"
|
||||
<CourseAliasList> ::= "<CourseAlias>(,<CourseAlias>)*"
|
||||
<CourseIDList> ::= "<CourseID>(,<CourseID>)*"
|
||||
<CourseStateList> ::= "<CourseState>(,<CourseState>)*"
|
||||
<CrOSFieldNameList> ::= "<CrOSFieldName>(,<CrOSFieldName>)*"
|
||||
<CrOSList> ::= "<CrOSID>(,<CrOSID>)*"
|
||||
<CrOSIDList> ::= "<CrOSID>(,<CrOSID>)*"
|
||||
<DriveFileList> ::= "<DriveFileItem>(,<DriveFileItem>)*"
|
||||
<EmailAddressList> ::= "<EmailAddress>(,<EmailAddress>)*"
|
||||
<EmailItemList> ::= "<EmailItem>(,<EmailItem>)*"
|
||||
@@ -546,6 +549,8 @@ Items, separated by spaces, with spaces, commas or single quotes in the items th
|
||||
<ResourceIDList> ::= "<ResourceID>(,<ResourceID>)*"
|
||||
<SKUIDList> ="<SKUID>(,<SKUID>)*"
|
||||
<SchemaNameList> ::= "<SchemaName>(,<SchemaName>)*"
|
||||
<SerialNumberList> ::= "<SerialNumber>(,<SerialNumber>)*"
|
||||
<TeamDriveIDList> ::= "<TeamDriveID>(,<TeamDriveID>)*"
|
||||
<UserFieldNameList> ::= "<UserFieldName>(,<UserFieldName>)*"
|
||||
<UserList> ::= "<UserItem>(,<UserItem>)*"
|
||||
|
||||
@@ -553,9 +558,14 @@ Items, separated by spaces, with spaces, commas or single quotes in the items th
|
||||
|
||||
Specify a collection of ChromeOS devices by directly specifying them
|
||||
|
||||
<CrOSEntity> ::=
|
||||
<CrOSIDList> | (cros_sn <SerialNumberList>) |
|
||||
(query:<QueryCrOS>)|(query:orgunitpath:<OrgUnitPath>)|(query <QueryCrOS>)
|
||||
|
||||
<CrOSTypeEntity> ::=
|
||||
(all cros)|
|
||||
(cros <CrOSList>)|
|
||||
(cros <CrOSIDList>)|
|
||||
(cros_sn <SerialNumberList>)|
|
||||
(crosfile <FileName>)|
|
||||
(croscsvfile <FileName>:<FieldName>)|
|
||||
(crosquery <QueryCrOS>)|
|
||||
@@ -569,9 +579,13 @@ Specify a collection of Users by directly specifying them or by specifiying item
|
||||
(all users)|
|
||||
(user <UserItem>)|
|
||||
(users <UserList>)|
|
||||
(group <GroupItem)|
|
||||
(group|group_ns|group_susp <GroupItem)|
|
||||
(ou|org <OrgUnitPath)|
|
||||
(ou_ns|org_ns <OrgUnitPath)|
|
||||
(ou_susp|org_susp <OrgUnitPath)|
|
||||
(ou_and_children|ou_and_child <OrgUnitPath>)|
|
||||
(ou_and_children_ns|ou_and_child_ns <OrgUnitPath>)|
|
||||
(ou_and_children_susp|ou_and_child_susp <OrgUnitPath>)|
|
||||
(courseparticipants <CourseID>)|
|
||||
(students <CourseID>)|
|
||||
(teachers <CourseID>)|
|
||||
@@ -597,7 +611,7 @@ Specify a collection of Users by directly specifying them or by specifiying item
|
||||
(notification clear|(email|sms eventcreation|eventchange|eventcancellation|eventresponse|agenda))
|
||||
|
||||
<CalendarSettings> ::=
|
||||
(summary <String>)|(description <String>)|(location <String>)|(timezone <String>)
|
||||
(summary <String>)|(description <String>)|(location <String>)|(timezone <TimeZone>)
|
||||
|
||||
<CourseAttributes> ::=
|
||||
(description <String>)|
|
||||
@@ -706,7 +720,6 @@ Specify a collection of Users by directly specifying them or by specifiying item
|
||||
<UserAttributes> ::=
|
||||
(address clear|(type work|home|other|(custom <String>) [unstructured|formatted <String>] [pobox <String>] [extendedaddress <String>] [streetaddress <String>]
|
||||
[locality <String>] [region <String>] [postalcode <String>] [country <String>] [countrycode <String>] notprimary|primary))|
|
||||
(admin <Boolean>)|
|
||||
(agreed2terms|agreedtoterms <Boolean>)|
|
||||
(changepassword|changepasswordatnextlogin <Boolean>)|
|
||||
(crypt|sha|sha1|sha-1|md5|nohash)|
|
||||
@@ -859,7 +872,7 @@ gam create org|ou <Name> [description <String>] [parent <OrgUnitPath>] [inherit|
|
||||
gam update org|ou <OrgUnitPath> [name <Name>] [description <String>] [parent <OrgUnitPath>] [inherit|noinherit]
|
||||
gam update org|ou <OrgUnitPath> add|move <CrOSTypeEntity>|<UserTypeEntity>
|
||||
gam delete org|ou <OrgUnitPath>
|
||||
gam info org|ou <OrgUnitPath> [nousers] [children|child]
|
||||
gam info org|ou <OrgUnitPath> [nousers|notsuspended|suspended] [children|child]
|
||||
gam print orgs|ous [todrive] [toplevelonly] [from_parent <OrgUnitPath>] [allfields|(fields <OrgUnitFieldNameList>)]
|
||||
|
||||
gam create alias|nickname <EmailAddress> user|group|target <UniqueID>|<EmailAddress>
|
||||
@@ -881,12 +894,12 @@ gam calendar <CalendarItem> wipe
|
||||
summary <String>|
|
||||
description <String>|
|
||||
location <String>|
|
||||
timezone <String>
|
||||
timezone <TimeZone>
|
||||
|
||||
gam calendar <CalendarItem> modify <CalendarSettings>+
|
||||
|
||||
gam update cros <CrOSItem> (<CrOSAttributes>+)|(action deprovision_same_model_replace|deprovision_different_model_replace|deprovision_retiring_device|disable|reenable [acknowledge_device_touch_requirement])
|
||||
gam info cros <CrOSItem> [nolists] [listlimit <Number>] [start <Date>] [end <Date>]
|
||||
gam update cros <CrOSEntity> (<CrOSAttributes>+)|(action deprovision_same_model_replace|deprovision_different_model_replace|deprovision_retiring_device|disable|reenable [acknowledge_device_touch_requirement])
|
||||
gam info cros <CrOSEntity> [nolists] [listlimit <Number>] [start <Date>] [end <Date>]
|
||||
[basic|full|allfields] <CrOSFieldName>* [fields <CrOSFieldNameList>] [downloadfile latest|<Time>] [targetfolder <FilePath>]
|
||||
|
||||
gam print cros [todrive] [(query <QueryCrOS>)|(queries <QueryCrOSList>)] [limittoou <OrgUnitItem>]
|
||||
@@ -949,11 +962,11 @@ gam print mobile [todrive] [(query <QueryMobile>)|(queries <QueryMobileList>)] [
|
||||
|
||||
gam create group <EmailAddress> <GroupAttributes>*
|
||||
gam update group <GroupItem> [admincreated <Boolean>] [email <EmailAddress>] <GroupAttributes>*
|
||||
gam update group <GroupItem> add [owner|manager|member] [notsuspended] <UserTypeEntity>
|
||||
gam update group <GroupItem> add [owner|manager|member] [notsuspended|suspended] <UserTypeEntity>
|
||||
gam update group <GroupItem> delete|remove [owner|manager|member] <UserTypeEntity>
|
||||
gam update group <GroupItem> sync [owner|manager|member] [notsuspended] <UserTypeEntity>
|
||||
gam update group <GroupItem> sync [owner|manager|member] [notsuspended|suspended] <UserTypeEntity>
|
||||
gam update group <GroupItem> update [owner|manager|member] <UserTypeEntity>
|
||||
gam update group <GroupItem> clear [member] [manager] [owner] [suspended]
|
||||
gam update group <GroupItem> clear [member] [manager] [owner] [notsuspended|suspended]
|
||||
gam delete group <GroupItem>
|
||||
gam info group <GroupItem> [nousers] [noaliases] [groups]
|
||||
|
||||
@@ -962,7 +975,8 @@ gam print groups [todrive] ([domain <DomainName>] ([member <UserItem>]|[query <Q
|
||||
[members|memberscount] [managers|managerscount] [owners|ownerscount]
|
||||
[delimiter <Character>] [sortheaders]
|
||||
|
||||
gam print group-members|groups-members [todrive] ([domain <DomainName>] ([member <UserItem>]|[query <QueryGroup>]))|[group <GroupItem>]
|
||||
gam print group-members|groups-members [todrive]
|
||||
([domain <DomainName>] ([member <UserItem>]|[query <QueryGroup>]))|[group|group_ns|group_susp <GroupItem>] [notsuspended|suspended]
|
||||
[roles <GroupRoleList>] [membernames] [fields <MembersFieldNameList>]
|
||||
|
||||
gam print license|licenses|licence|licences [todrive] [(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||
@@ -1065,12 +1079,23 @@ gam print printjobs [todrive] [printer|printerid <PrinterID>]
|
||||
[owner|user <EmailAddress>]
|
||||
[limit <Number>]
|
||||
|
||||
gam create vaultexport|export matter <MatterItem> [name <name>] corpus <drive|mail|groups|hangouts_chat>
|
||||
(accounts <EmailAddressList>) | (orgunit|ou <OrgUnitPath>) | (teamdrives <TeamDriveList>) | (rooms <ChatRoomList>) | everyone
|
||||
[scope <all_data|held_data|unprocessed_data>]
|
||||
[terms <terms>] [start|starttime <Date>|<DateTime>] [end|endtime <Date>|<DateTime>] [timezone <TimeZone>] [format mbox|pst]
|
||||
[excludedrafts <Boolean>] [driveversiondate <Date>|<DateTime>] [includeteamdrives] [includerooms]
|
||||
[includeaccessinfo <Boolean>]
|
||||
gam delete export <MatterItem> <ExportItem>
|
||||
gam info export <MatterItem> <ExportItem>
|
||||
gam print exports [todrive] [matters <MatterItemList>]
|
||||
gam download export <MatterItem> <ExportItem> [noverify] [noextract] [targetfolder <FilePath>]
|
||||
|
||||
gam create vaulthold|hold corpus drive|groups|mail matter <MatterItem> [name <String>] [query <QueryVaultCorpus>]
|
||||
[(accounts|groups|users <EmailItemList>) | (orgunit|ou <OrgUnit>)]
|
||||
[starttime <Date>|<DateTime>] [endtime <Date>|<DateTime>]
|
||||
[start|starttime <Date>|<DateTime>] [end|endtime <Date>|<DateTime>]
|
||||
gam update vaulthold|hold <HoldItem> matter <MatterItem> [query <QueryVaultCorpus>]
|
||||
[([addaccounts|addgroups|addusers <EmailItemList>] [removeaccounts|removegroups|removeusers <EmailItemList>]) | (orgunit|ou <OrgUnit>)]
|
||||
[starttime <Date>|<DateTime>] [endtime <Date>|<DateTime>]
|
||||
[start|starttime <Date>|<DateTime>] [end|endtime <Date>|<DateTime>]
|
||||
gam delete vaulthold|hold <HoldItem> matter <MatterItem>
|
||||
gam info vaulthold|hold <HoldItem> matter <MatterItem>
|
||||
gam print vaultholds|holds [todrive] [matters <MatterItemList>]
|
||||
@@ -1117,7 +1142,7 @@ gam <UserTypeEntity> show filetree [anyowner] (orderby <DriveOrderByFieldName> [
|
||||
gam <UserTypeEntity> create|add drivefile [drivefilename <DriveFileName>] <DriveFileAddAttributes>* [csv] [todrive]
|
||||
gam <UserTypeEntity> update drivefile (id <DriveFileID)|(drivefilename <DriveFileName>)|(query <QueryDriveFile) [copy] [newfilename <DriveFileName>] <DriveFileUpdateAttributes>*
|
||||
gam <UserTypeEntity> get drivefile (id <DriveFileID>)|(drivefilename <DriveFileName>)|(query <QueryDriveFile>) [revision <Number>] [format <FileFormatList>]
|
||||
targetfolder <FilePath>] [targetname <FileName>] [overwrite] [showprogress]
|
||||
[targetfolder <FilePath>] [targetname <FileName>] [overwrite] [showprogress]
|
||||
gam <UserTypeEntity> delete|del drivefile <DriveFileID>|<DriveFileURL>|(query:<QueryDriveFile>) [purge|untrash]
|
||||
gam <UserTypeEntity> transfer drive <UserItem> [keepuser]
|
||||
gam <UserTypeEntity> delete|del emptydrivefolders
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
{
|
||||
"kind": "discovery#restDescription",
|
||||
"discoveryVersion": "v1",
|
||||
"id": "email-settings:v2",
|
||||
"name": "email-settings",
|
||||
"version": "v2",
|
||||
"revision": "20161013",
|
||||
"title": "Email Settings API",
|
||||
"description": "Lets you manage Google Apps Email Settings",
|
||||
"ownerDomain": "google.com",
|
||||
"ownerName": "Google",
|
||||
"icons": {
|
||||
"x16": "http://www.google.com/images/icons/product/search-16.gif",
|
||||
"x32": "http://www.google.com/images/icons/product/search-32.gif"
|
||||
},
|
||||
"documentationLink": "https://developers.google.com/admin-sdk/email-settings",
|
||||
"protocol": "rest",
|
||||
"baseUrl": "https://apps-apis.google.com/",
|
||||
"rootUrl": "https://apps-apis.google.com/",
|
||||
"servicePath": "/a/feeds/emailsettings/2.0/",
|
||||
"parameters": {
|
||||
"v": {
|
||||
"type": "string",
|
||||
"description": "GData Version",
|
||||
"default": "2.0",
|
||||
"enum": [
|
||||
"2.0"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"GData 2.0"
|
||||
],
|
||||
"location": "query"
|
||||
},
|
||||
"alt": {
|
||||
"type": "string",
|
||||
"description": "Data format for the response.",
|
||||
"default": "json",
|
||||
"enum": [
|
||||
"json"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"Responses with Content-Type of application/json"
|
||||
],
|
||||
"location": "query"
|
||||
},
|
||||
"quotaUser": {
|
||||
"type": "string",
|
||||
"description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.",
|
||||
"location": "query"
|
||||
},
|
||||
"prettyPrint": {
|
||||
"type": "boolean",
|
||||
"description": "Returns response with indentations and line breaks.",
|
||||
"default": "true",
|
||||
"location": "query"
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"oauth2": {
|
||||
"scopes": {
|
||||
"https://apps-apis.google.com/a/feeds/emailsettings/2.0/": {
|
||||
"description": "Manage email settings"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"Delegate": {
|
||||
"id": "Delegate",
|
||||
"type": "object",
|
||||
"description": "a delegate.",
|
||||
"properties": {
|
||||
"apps$property": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "property name"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "organization name value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Delegates": {
|
||||
"id": "feed",
|
||||
"type": "object",
|
||||
"description": "List of delegates.",
|
||||
"properties": {
|
||||
"entry": {
|
||||
"type": "object",
|
||||
"description": "list of delegates",
|
||||
"items": {
|
||||
"$ref": "Delegate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"delegates": {
|
||||
"methods": {
|
||||
"get": {
|
||||
"id": "email-settings.delegates.get",
|
||||
"path": "{domainName}/{delegator}/delegation",
|
||||
"httpMethod": "GET",
|
||||
"parameters": {
|
||||
"domainName": {
|
||||
"type": "string",
|
||||
"required": "true",
|
||||
"location": "path"
|
||||
},
|
||||
"delegator": {
|
||||
"type": "string",
|
||||
"required": "true",
|
||||
"location": "path"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"$ref": "Delegates"
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"id": "email-settings.delegates.delete",
|
||||
"path": "{domainName}/{delegator}/delegation/{delegate}",
|
||||
"httpMethod": "DELETE",
|
||||
"parameters": {
|
||||
"domainName": {
|
||||
"type": "string",
|
||||
"required": "true",
|
||||
"location": "path"
|
||||
},
|
||||
"delegator": {
|
||||
"type": "string",
|
||||
"required": "true",
|
||||
"location": "path"
|
||||
},
|
||||
"delegate": {
|
||||
"type": "string",
|
||||
"required": "true",
|
||||
"location": "path"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
479
src/gam.py
479
src/gam.py
@@ -1502,56 +1502,26 @@ def addDelegates(users, i):
|
||||
if sys.argv[i].lower() != u'to':
|
||||
systemErrorExit(2, u'%s is not a valid argument for "gam <users> delegate", expected to' % sys.argv[i])
|
||||
i += 1
|
||||
delegate = sys.argv[i].lower()
|
||||
atLoc = delegate.find(u'@')
|
||||
if atLoc == -1:
|
||||
delegate_domain = GC_Values[GC_DOMAIN].lower()
|
||||
delegate_email = u'%s@%s' % (delegate, delegate_domain)
|
||||
else:
|
||||
delegate_domain = delegate[atLoc+1:].lower()
|
||||
delegate_email = delegate
|
||||
delegate = normalizeEmailAddressOrUID(sys.argv[i], noUid=True)
|
||||
i = 0
|
||||
count = len(users)
|
||||
emailsettings = buildGAPIObject(u'email-settings')
|
||||
for delegator in users:
|
||||
i += 1
|
||||
atLocd = delegator.find(u'@')
|
||||
if atLocd == -1:
|
||||
delegator_domain = GC_Values[GC_DOMAIN].lower()
|
||||
delegator_email = u'%s@%s' % (delegator, delegator_domain)
|
||||
else:
|
||||
delegator_domain = delegator[atLocd+1:].lower()
|
||||
delegator_email = delegator
|
||||
delegator = delegator[:atLocd]
|
||||
uri = u'https://apps-apis.google.com/a/feeds/emailsettings/2.0/%s/%s/delegation' % (delegator_domain, delegator)
|
||||
body = u'''<?xml version="1.0" encoding="utf-8"?>
|
||||
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:apps="http://schemas.google.com/apps/2006">
|
||||
<apps:property name="address" value="%s" />
|
||||
</atom:entry>''' % delegate_email
|
||||
headers = {u'GData-Version': u'2.0', u'Content-Type': u'application/atom+xml; charset=UTF-8'}
|
||||
print u"Giving %s delegate access to %s (%s/%s)" % (delegate_email, delegator_email, i, count)
|
||||
retries = 10
|
||||
for n in range(1, retries+1):
|
||||
status, result = emailsettings._http.request(uri=uri, method=u'POST', body=body, headers=headers)
|
||||
httpStatus = int(status[u'status'])
|
||||
if httpStatus == 201: # Success
|
||||
time.sleep(10) # on success, sleep 10 seconds before exiting or moving on to next user to prevent ghost delegates
|
||||
break
|
||||
elif httpStatus > 499:
|
||||
waitOnFailure(n, retries, str(httpStatus))
|
||||
else:
|
||||
systemErrorExit(3, u'Could not create delegation - %s - %s' % (httpStatus, result))
|
||||
delegator, gmail = buildGmailGAPIObject(delegator)
|
||||
if not gmail:
|
||||
continue
|
||||
print u"Giving %s delegate access to %s (%s/%s)" % (delegate, delegator, i, count)
|
||||
callGAPI(gmail.users().settings().delegates(), u'create', soft_errors=True, userId=u'me', body={u'delegateEmail': delegate})
|
||||
|
||||
def gen_sha512_hash(password):
|
||||
from passlib.handlers.sha2_crypt import sha512_crypt
|
||||
return sha512_crypt.encrypt(password, rounds=5000)
|
||||
|
||||
def printShowDelegates(users, csvFormat):
|
||||
emailsettings = buildGAPIObject(u'email-settings')
|
||||
if csvFormat:
|
||||
todrive = False
|
||||
csvRows = []
|
||||
titles = [u'User', u'delegateName', u'delegateAddress', u'delegationStatus']
|
||||
titles = [u'User', u'delegateAddress', u'delegationStatus']
|
||||
else:
|
||||
csvStyle = False
|
||||
i = 5
|
||||
@@ -1565,64 +1535,41 @@ def printShowDelegates(users, csvFormat):
|
||||
i += 1
|
||||
else:
|
||||
systemErrorExit(2, u'%s is not a valid argument for "gam <users> show delegates"' % sys.argv[i])
|
||||
count = len(users)
|
||||
i = 1
|
||||
for user in users:
|
||||
atLoc = user.find(u'@')
|
||||
if atLoc == -1:
|
||||
userName = user
|
||||
domainName = GC_Values[GC_DOMAIN]
|
||||
user = u'%s@%s' % (user, domainName)
|
||||
else:
|
||||
userName = user[:atLoc]
|
||||
domainName = user[atLoc+1:]
|
||||
sys.stderr.write(u"Getting delegates for %s...\n" % (user))
|
||||
delegates = callGAPI(emailsettings.delegates(), u'get', soft_errors=True, v=u'2.0', domainName=domainName, delegator=userName)
|
||||
if delegates and u'feed' in delegates and u'entry' in delegates[u'feed']:
|
||||
for delegate in delegates[u'feed']['entry']:
|
||||
status = u''
|
||||
delegateAddress = u''
|
||||
delegateName = u''
|
||||
delegationId = u''
|
||||
for item in delegate[u'apps$property']:
|
||||
if item[u'name'] == u'status':
|
||||
status = item[u'value']
|
||||
elif item[u'name'] == u'address':
|
||||
delegateAddress = item[u'value']
|
||||
elif item[u'name'] == u'delegate':
|
||||
delegateName = item[u'value']
|
||||
elif item[u'name'] == u'delegationId':
|
||||
delegationId = item[u'value']
|
||||
user, gmail = buildGmailGAPIObject(user)
|
||||
if not gmail:
|
||||
continue
|
||||
sys.stderr.write(u"Getting delegates for %s (%s/%s)...\n" % (user, i, count))
|
||||
i += 1
|
||||
delegates = callGAPI(gmail.users().settings().delegates(), u'list', soft_errors=True, userId=u'me')
|
||||
if delegates and u'delegates' in delegates:
|
||||
for delegate in delegates[u'delegates']:
|
||||
delegateAddress = delegate[u'delegateEmail']
|
||||
status = delegate[u'verificationStatus']
|
||||
if csvFormat:
|
||||
row = {u'User': user, u'delegateName': delegateName, u'delegateAddress': delegateAddress, u'delegationStatus': status}
|
||||
row = {u'User': user, u'delegateAddress': delegateAddress, u'delegationStatus': status}
|
||||
csvRows.append(row)
|
||||
else:
|
||||
if csvStyle:
|
||||
print u'%s,%s,%s' % (user, delegateAddress, status)
|
||||
else:
|
||||
print utils.convertUTF8(u"Delegator: %s\n Delegate: %s\n Status: %s\n Delegate Email: %s\n Delegate ID: %s\n" % (user, delegateName, status, delegateAddress, delegationId))
|
||||
print utils.convertUTF8(u"Delegator: %s\n Status: %s\n Delegate Email: %s\n" % (user, status, delegateAddress))
|
||||
if csvFormat:
|
||||
writeCSVfile(csvRows, titles, u'Delegates', todrive)
|
||||
|
||||
def deleteDelegate(users):
|
||||
emailsettings = buildGAPIObject(u'email-settings')
|
||||
delegate = sys.argv[5]
|
||||
if not delegate.find(u'@') > 0:
|
||||
if users[0].find(u'@') > 0:
|
||||
delegatedomain = users[0][users[0].find(u'@')+1:]
|
||||
else:
|
||||
delegatedomain = GC_Values[GC_DOMAIN]
|
||||
delegate = u'%s@%s' % (delegate, delegatedomain)
|
||||
delegate = normalizeEmailAddressOrUID(sys.argv[5], noUid=True)
|
||||
i = 0
|
||||
count = len(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
atLoc = user.find(u'@')
|
||||
if atLoc == -1:
|
||||
domainName = GC_Values[GC_DOMAIN] #make sure it's back at default domain
|
||||
else:
|
||||
domainName = user[atLoc+1:]
|
||||
user = user[:atLoc]
|
||||
print u"Deleting %s delegate access to %s (%s/%s)" % (delegate, user+u'@'+domainName, i, count)
|
||||
callGAPI(emailsettings.delegates(), u'delete', v=u'2.0', delegate=delegate, delegator=user, domainName=domainName)
|
||||
user, gmail = buildGmailGAPIObject(user)
|
||||
if not gmail:
|
||||
continue
|
||||
print u"Deleting %s delegate access to %s (%s/%s)" % (delegate, user, i, count)
|
||||
callGAPI(gmail.users().settings().delegates(), u'delete', soft_errors=True, userId=u'me', delegateEmail=delegate)
|
||||
|
||||
def doAddCourseParticipant():
|
||||
croom = buildGAPIObject(u'classroom')
|
||||
@@ -1648,7 +1595,7 @@ def doAddCourseParticipant():
|
||||
def doSyncCourseParticipants():
|
||||
courseId = addCourseIdScope(sys.argv[2])
|
||||
participant_type = sys.argv[4].lower()
|
||||
diff_entity_type = sys.argv[5]
|
||||
diff_entity_type = sys.argv[5].lower()
|
||||
diff_entity = sys.argv[6]
|
||||
current_course_users = getUsersToModify(entity_type=participant_type, entity=courseId)
|
||||
print
|
||||
@@ -5800,8 +5747,8 @@ def renameLabels(users):
|
||||
except GAPI_aborted:
|
||||
if merge:
|
||||
print u' Merging %s label to existing %s label' % (label[u'name'], new_label_name)
|
||||
q = u'label:"%s"' % label[u'name']
|
||||
messages_to_relabel = callGAPIpages(gmail.users().messages(), u'list', u'messages', userId=user, q=q)
|
||||
messages_to_relabel = callGAPIpages(gmail.users().messages(), u'list', u'messages',
|
||||
userId=user, q=u'label:%s' % label[u'name'].lower().replace(u'/', u'-').replace(u' ', u'-'))
|
||||
if len(messages_to_relabel) > 0:
|
||||
for new_label in labels[u'labels']:
|
||||
if new_label[u'name'].lower() == new_label_name.lower():
|
||||
@@ -6545,7 +6492,7 @@ def doGetUserSchema():
|
||||
schema = callGAPI(cd.schemas(), u'get', customerId=GC_Values[GC_CUSTOMER_ID], schemaKey=schemaKey)
|
||||
_showSchema(schema)
|
||||
|
||||
def getUserAttributes(i, cd, updateCmd=False):
|
||||
def getUserAttributes(i, cd, updateCmd):
|
||||
def getEntryType(i, entry, entryTypes, setTypeCustom=True, customKeyword=u'custom', customTypeKeyword=u'customType'):
|
||||
""" Get attribute entry type
|
||||
entryTypes is list of pre-defined types, a|b|c
|
||||
@@ -6614,7 +6561,6 @@ def getUserAttributes(i, cd, updateCmd=False):
|
||||
i += 1
|
||||
need_password = True
|
||||
need_to_hash_password = True
|
||||
admin_body = {}
|
||||
while i < len(sys.argv):
|
||||
myarg = sys.argv[i].lower()
|
||||
if myarg in [u'firstname', u'givenname']:
|
||||
@@ -6638,7 +6584,9 @@ def getUserAttributes(i, cd, updateCmd=False):
|
||||
need_password = True
|
||||
i += 2
|
||||
elif myarg == u'admin':
|
||||
admin_body[u'status'] = getBoolean(sys.argv[i+1], myarg)
|
||||
value = getBoolean(sys.argv[i+1], myarg)
|
||||
if updateCmd or value:
|
||||
systemErrorExit(2, '%s %s is not a valid argument for "gam %s user"' % (sys.argv[i], value, [u'create', u'update'][updateCmd]))
|
||||
i += 2
|
||||
elif myarg == u'suspended':
|
||||
body[u'suspended'] = getBoolean(sys.argv[i+1], myarg)
|
||||
@@ -7049,7 +6997,7 @@ def getUserAttributes(i, cd, updateCmd=False):
|
||||
if u'password' in body and need_to_hash_password:
|
||||
body[u'password'] = gen_sha512_hash(body[u'password'])
|
||||
body[u'hashFunction'] = u'crypt'
|
||||
return (body, admin_body)
|
||||
return body
|
||||
|
||||
VALIDEMAIL_PATTERN = re.compile(r'^[^@]+@[^@]+\.[^@]+$')
|
||||
|
||||
@@ -7477,6 +7425,20 @@ def doCreateVaultMatter():
|
||||
print u' adding collaborator %s' % collaborator[u'email']
|
||||
callGAPI(v.matters(), u'addPermissions', matterId=matterId, body={u'matterPermission': {u'role': u'COLLABORATOR', u'accountId': collaborator[u'id']}})
|
||||
|
||||
VAULT_SEARCH_METHODS_MAP = {
|
||||
u'account': u'ACCOUNT',
|
||||
u'accounts': u'ACCOUNT',
|
||||
u'entireorg': u'ENTIRE_ORG',
|
||||
u'everyone': u'ENTIRE_ORG',
|
||||
u'orgunit': u'ORG_UNIT',
|
||||
u'ou': u'ORG_UNIT',
|
||||
u'room': u'ROOM',
|
||||
u'rooms': u'ROOM',
|
||||
u'teamdrive': u'TEAM_DRIVE',
|
||||
u'teamdrives': u'TEAM_DRIVE',
|
||||
}
|
||||
VAULT_SEARCH_METHODS_LIST = [u'accounts', u'orgunit', u'teamdrives', u'rooms', u'everyone']
|
||||
|
||||
def doCreateVaultExport():
|
||||
v = buildGAPIObject(u'vault')
|
||||
allowed_corpuses = v._rootDesc[u'schemas'][u'Query'][u'properties'][u'corpus'][u'enum']
|
||||
@@ -7508,38 +7470,37 @@ def doCreateVaultExport():
|
||||
if body[u'query'][u'corpus'] not in allowed_corpuses:
|
||||
systemErrorExit(3, 'corpus must be one of %s. Got %s' % (u', '.join(allowed_corpuses), sys.argv[i+1]))
|
||||
i += 2
|
||||
elif myarg in VAULT_SEARCH_METHODS_MAP:
|
||||
if body[u'query'].get(u'searchMethod'):
|
||||
systemErrorExit(3, 'Multiple search methods ({0}) specified, only one is allowed'.format(u', '.join(VAULT_SEARCH_METHODS_LIST)))
|
||||
searchMethod = VAULT_SEARCH_METHODS_MAP[myarg]
|
||||
body[u'query'][u'searchMethod'] = searchMethod
|
||||
if searchMethod == u'ACCOUNT':
|
||||
body[u'query'][u'accountInfo'] = {u'emails': sys.argv[i+1].split(u',')}
|
||||
i += 2
|
||||
elif searchMethod == u'ORG_UNIT':
|
||||
body[u'query'][u'orgUnitInfo'] = {u'orgUnitId': getOrgUnitId(sys.argv[i+1])[1]}
|
||||
i += 2
|
||||
elif searchMethod == u'TEAM_DRIVE':
|
||||
body[u'query'][u'teamDriveInfo'] = {u'teamDriveIds': sys.argv[i+1].split(u',')}
|
||||
i += 2
|
||||
elif searchMethod == u'ROOM':
|
||||
body[u'query'][u'hangoutsChatInfo'] = {u'roomId': sys.argv[i+1].split(u',')}
|
||||
i += 2
|
||||
else:
|
||||
i += 1
|
||||
elif myarg == u'scope':
|
||||
body[u'query'][u'dataScope'] = sys.argv[i+1].upper()
|
||||
if body[u'query']['dataScope'] not in allowed_scopes:
|
||||
systemErrorExit(3, 'scope must be one of %s. Got %s' % (u', '.join(allowed_scopes), sys.argv[i+1]))
|
||||
i += 2
|
||||
elif myarg in [u'account', u'accounts']:
|
||||
body[u'query'][u'searchMethod'] = u'ACCOUNT'
|
||||
body[u'query'][u'accountInfo'] = {u'emails': sys.argv[i+1].split(u',')}
|
||||
i += 2
|
||||
elif myarg in [u'ou', u'orgunit']:
|
||||
body[u'query'][u'searchMethod'] = u'ORG_UNIT'
|
||||
orgUnitId = getOrgUnitId(sys.argv[i+1])[1]
|
||||
body[u'query'][u'orgUnitInfo'] = {u'orgUnitId': orgUnitId}
|
||||
i += 2
|
||||
elif myarg in [u'teamdrive', u'teamdrives']:
|
||||
body[u'query'][u'searchMethod'] = u'TEAM_DRIVE'
|
||||
body[u'query'][u'teamDriveInfo'] = {u'teamDriveIds': sys.argv[i+1].split(u',')}
|
||||
i += 2
|
||||
elif myarg in [u'room', u'rooms']:
|
||||
body[u'query'][u'searchMethod'] = u'ROOM'
|
||||
body[u'query'][u'hangoutsChatInfo'] = {u'roomId': sys.argv[i+1].split(u',')}
|
||||
i += 2
|
||||
elif myarg in [u'everyone']:
|
||||
body[u'query'][u'searchMethod'] = u'ENTIRE_ORG'
|
||||
i += 2
|
||||
elif myarg in [u'terms']:
|
||||
body[u'query'][u'terms'] = sys.argv[i+1]
|
||||
i += 2
|
||||
elif myarg in [u'start']:
|
||||
elif myarg in [u'start', u'starttime']:
|
||||
body[u'query'][u'startTime'] = getDateZeroTimeOrFullTime(sys.argv[i+1])
|
||||
i += 2
|
||||
elif myarg in [u'end']:
|
||||
elif myarg in [u'end', u'endtime']:
|
||||
body[u'query'][u'endTime'] = getDateZeroTimeOrFullTime(sys.argv[i+1])
|
||||
i += 2
|
||||
elif myarg in [u'timezone']:
|
||||
@@ -7567,14 +7528,13 @@ def doCreateVaultExport():
|
||||
body[u'exportOptions'].setdefault(u'driveOptions', {})[u'includeAccessInfo'] = getBoolean(sys.argv[i+1], myarg)
|
||||
i += 2
|
||||
else:
|
||||
print u'ERROR %s is not a valid argument for "gam create export".' % sys.argv[i]
|
||||
sys.exit(3)
|
||||
systemErrorExit(3, '%s is not a valid argument to "gam create export"' % sys.argv[i])
|
||||
if not matterId:
|
||||
print u'ERROR: you must specify a matterId.'
|
||||
sys.exit(3)
|
||||
systemErrorExit(3, 'you must specify a matter for the new export.')
|
||||
if u'corpus' not in body[u'query']:
|
||||
print u'ERROR: you must specify a corpus type. Choose one of %s' % u', '.join(allowed_corpuses)
|
||||
sys.exit(3)
|
||||
systemErrorExit(3, 'you must specify a corpus for the new export. Choose one of %s' % u', '.join(allowed_corpuses))
|
||||
if u'searchMethod' not in body[u'query']:
|
||||
systemErrorExit(3, 'you must specify a search method for the new export. Choose one of %s' % u', '.join(VAULT_SEARCH_METHODS_LIST))
|
||||
if u'name' not in body:
|
||||
body[u'name'] = u'GAM %s export - %s' % (body[u'query'][u'corpus'], datetime.datetime.now())
|
||||
options_field = None
|
||||
@@ -7585,11 +7545,19 @@ def doCreateVaultExport():
|
||||
elif body[u'query'][u'corpus'] == u'HANGOUTS_CHAT':
|
||||
options_field = u'hangoutsChatOptions'
|
||||
if options_field:
|
||||
body[u'exportOptions'].pop(u'driveOptions', None)
|
||||
body[u'exportOptions'][options_field] = {u'exportFormat': export_format}
|
||||
results = callGAPI(v.matters().exports(), u'create', matterId=matterId, body=body)
|
||||
print_json(None, results)
|
||||
|
||||
def doGetVaultExport():
|
||||
def doDeleteVaultExport():
|
||||
v = buildGAPIObject(u'vault')
|
||||
matterId = getMatterItem(v, sys.argv[3])
|
||||
exportId = convertExportNameToID(v, sys.argv[4], matterId)
|
||||
print u'Deleting export %s / %s' % (sys.argv[4], exportId)
|
||||
callGAPI(v.matters().exports(), u'delete', matterId=matterId, exportId=exportId)
|
||||
|
||||
def doGetVaultExportInfo():
|
||||
v = buildGAPIObject(u'vault')
|
||||
matterId = getMatterItem(v, sys.argv[3])
|
||||
exportId = convertExportNameToID(v, sys.argv[4], matterId)
|
||||
@@ -7604,6 +7572,22 @@ def doDownloadVaultExport():
|
||||
matterId = getMatterItem(v, sys.argv[3])
|
||||
exportId = convertExportNameToID(v, sys.argv[4], matterId)
|
||||
targetFolder = GC_Values[GC_DRIVE_DIR]
|
||||
i = 5
|
||||
while i < len(sys.argv):
|
||||
myarg = sys.argv[i].lower().replace(u'_', u'')
|
||||
if myarg == u'targetfolder':
|
||||
targetFolder = os.path.expanduser(sys.argv[i+1])
|
||||
if not os.path.isdir(targetFolder):
|
||||
os.makedirs(targetFolder)
|
||||
i += 2
|
||||
elif myarg == u'noverify':
|
||||
verifyFiles = False
|
||||
i += 1
|
||||
elif myarg == u'noextract':
|
||||
extractFiles = False
|
||||
i += 1
|
||||
else:
|
||||
systemErrorExit(3, '%s is not a valid argument to "gam download export"' % sys.argv[i])
|
||||
export = callGAPI(v.matters().exports(), u'get', matterId=matterId, exportId=exportId)
|
||||
for s_file in export[u'cloudStorageSink']['files']:
|
||||
bucket = s_file['bucketName']
|
||||
@@ -7651,9 +7635,9 @@ def extract_nested_zip(zippedFile, toFolder, spacing=u' '):
|
||||
inner_files = zfile.infolist()
|
||||
for inner_file in inner_files:
|
||||
print u'%s %s' % (spacing, inner_file.filename)
|
||||
zfile.extract(inner_file)
|
||||
inner_file_path = zfile.extract(inner_file, toFolder)
|
||||
if re.search(r'\.zip$', inner_file.filename):
|
||||
extract_nested_zip(inner_file.filename, toFolder, spacing=spacing+u' ')
|
||||
extract_nested_zip(inner_file_path, toFolder, spacing=spacing+u' ')
|
||||
os.remove(zippedFile)
|
||||
|
||||
def doCreateVaultHold():
|
||||
@@ -7683,13 +7667,12 @@ def doCreateVaultHold():
|
||||
accounts = sys.argv[i+1].split(u',')
|
||||
i += 2
|
||||
elif myarg in [u'orgunit', u'ou']:
|
||||
_, orgUnitId = getOrgUnitId(sys.argv[i+1], None)
|
||||
body[u'orgUnit'] = {u'orgUnitId': orgUnitId}
|
||||
body[u'orgUnit'] = {u'orgUnitId': getOrgUnitId(sys.argv[i+1])[1]}
|
||||
i += 2
|
||||
elif myarg == u'starttime':
|
||||
elif myarg in [u'start', u'starttime']:
|
||||
start_time = getDateZeroTimeOrFullTime(sys.argv[i+1])
|
||||
i += 2
|
||||
elif myarg == u'endtime':
|
||||
elif myarg in [u'end', u'endtime']:
|
||||
end_time = getDateZeroTimeOrFullTime(sys.argv[i+1])
|
||||
i += 2
|
||||
elif myarg == u'matter':
|
||||
@@ -7702,7 +7685,7 @@ def doCreateVaultHold():
|
||||
if not body.get(u'name'):
|
||||
systemErrorExit(3, 'you must specify a name for the new hold.')
|
||||
if not body.get(u'corpus'):
|
||||
systemErrorExit(3, 'you must specify corpus for the new hold. One of %s' % (u', '.join(allowed_corpuses)))
|
||||
systemErrorExit(3, 'you must specify a corpus for the new hold. Choose one of %s' % (u', '.join(allowed_corpuses)))
|
||||
query_type = u'%sQuery' % body[u'corpus'].lower()
|
||||
body[u'query'][query_type] = {}
|
||||
if body[u'corpus'] == u'DRIVE':
|
||||
@@ -7828,13 +7811,12 @@ def doUpdateVaultHold():
|
||||
query = sys.argv[i+1]
|
||||
i += 2
|
||||
elif myarg in [u'orgunit', u'ou']:
|
||||
_, orgUnitId = getOrgUnitId(sys.argv[i+1], None)
|
||||
body[u'orgUnit'] = {u'orgUnitId': orgUnitId}
|
||||
body[u'orgUnit'] = {u'orgUnitId': getOrgUnitId(sys.argv[i+1])[1]}
|
||||
i += 2
|
||||
elif myarg == u'starttime':
|
||||
elif myarg in [u'start', u'starttime']:
|
||||
start_time = getDateZeroTimeOrFullTime(sys.argv[i+1])
|
||||
i += 2
|
||||
elif myarg == u'endtime':
|
||||
elif myarg in [u'end', u'endtime']:
|
||||
end_time = getDateZeroTimeOrFullTime(sys.argv[i+1])
|
||||
i += 2
|
||||
elif myarg in [u'addusers', u'addaccounts', u'addgroups']:
|
||||
@@ -7950,12 +7932,9 @@ def doGetVaultMatterInfo():
|
||||
|
||||
def doCreateUser():
|
||||
cd = buildGAPIObject(u'directory')
|
||||
body, admin_body = getUserAttributes(3, cd, updateCmd=False)
|
||||
body = getUserAttributes(3, cd, False)
|
||||
print u"Creating account for %s" % body[u'primaryEmail']
|
||||
callGAPI(cd.users(), u'insert', body=body, fields=u'primaryEmail')
|
||||
if admin_body:
|
||||
print u' Changing admin status for %s to %s' % (body[u'primaryEmail'], admin_body[u'status'])
|
||||
callGAPI(cd.users(), u'makeAdmin', userKey=body[u'primaryEmail'], body=admin_body)
|
||||
|
||||
def GroupIsAbuseOrPostmaster(emailAddr):
|
||||
return emailAddr.startswith(u'abuse@') or emailAddr.startswith(u'postmaster@')
|
||||
@@ -8336,7 +8315,7 @@ def doUpdateUser(users, i):
|
||||
cd = buildGAPIObject(u'directory')
|
||||
if users is None:
|
||||
users = [normalizeEmailAddressOrUID(sys.argv[3])]
|
||||
body, admin_body = getUserAttributes(i, cd, updateCmd=True)
|
||||
body = getUserAttributes(i, cd, True)
|
||||
vfe = u'primaryEmail' in body and body[u'primaryEmail'][:4].lower() == u'vfe@'
|
||||
for user in users:
|
||||
userKey = user
|
||||
@@ -8350,8 +8329,6 @@ def doUpdateUser(users, i):
|
||||
sys.stdout.write(u'updating user %s...\n' % user)
|
||||
if body:
|
||||
callGAPI(cd.users(), u'update', userKey=userKey, body=body)
|
||||
if admin_body:
|
||||
callGAPI(cd.users(), u'makeAdmin', userKey=userKey, body=admin_body)
|
||||
|
||||
def doRemoveUsersAliases(users):
|
||||
cd = buildGAPIObject(u'directory')
|
||||
@@ -8411,17 +8388,17 @@ def doUpdateGroup():
|
||||
return emailAddress
|
||||
|
||||
def _getRoleAndUsers():
|
||||
checkNotSuspended = False
|
||||
checkSuspended = None
|
||||
role = ROLE_MEMBER
|
||||
i = 5
|
||||
if sys.argv[i].lower() in GROUP_ROLES_MAP:
|
||||
role = GROUP_ROLES_MAP[sys.argv[i].lower()]
|
||||
i += 1
|
||||
if sys.argv[i].lower() == u'notsuspended':
|
||||
checkNotSuspended = True
|
||||
if sys.argv[i].lower() in [u'suspended', u'notsuspended']:
|
||||
checkSuspended = sys.argv[i].lower() == u'suspended'
|
||||
i += 1
|
||||
if sys.argv[i].lower() in usergroup_types:
|
||||
users_email = getUsersToModify(entity_type=sys.argv[i], entity=sys.argv[i+1], checkNotSuspended=checkNotSuspended, groupUserMembersOnly=False)
|
||||
users_email = getUsersToModify(entity_type=sys.argv[i].lower(), entity=sys.argv[i+1], checkSuspended=checkSuspended, groupUserMembersOnly=False)
|
||||
else:
|
||||
users_email = [normalizeEmailAddressOrUID(sys.argv[i], checkForCustomerId=True)]
|
||||
return (role, users_email)
|
||||
@@ -8523,7 +8500,7 @@ def doUpdateGroup():
|
||||
except (GAPI_memberNotFound, GAPI_invalidMember) as e:
|
||||
print u' Group: {0}, {1} Update to {2} Failed: {3}'.format(group, users_email[0], role, str(e))
|
||||
else: # clear
|
||||
suspended = False
|
||||
checkSuspended = None
|
||||
fields = [u'email', u'id']
|
||||
roles = []
|
||||
i = 5
|
||||
@@ -8532,8 +8509,8 @@ def doUpdateGroup():
|
||||
if myarg.upper() in [ROLE_OWNER, ROLE_MANAGER, ROLE_MEMBER]:
|
||||
roles.append(myarg.upper())
|
||||
i += 1
|
||||
elif myarg == u'suspended':
|
||||
suspended = True
|
||||
elif myarg in [u'suspended', u'notsuspended']:
|
||||
checkSuspended = myarg == u'suspended'
|
||||
fields.append(u'status')
|
||||
i += 1
|
||||
else:
|
||||
@@ -8552,12 +8529,14 @@ def doUpdateGroup():
|
||||
page_message=page_message,
|
||||
throw_reasons=GAPI_MEMBERS_THROW_REASONS,
|
||||
groupKey=group, roles=listRoles, fields=listFields, maxResults=GC_Values[GC_MEMBER_MAX_RESULTS])
|
||||
if not suspended:
|
||||
if checkSuspended is None:
|
||||
users_email = [member.get(u'email', member[u'id']) for member in result if not validRoles or member.get(u'role', ROLE_MEMBER) in validRoles]
|
||||
else:
|
||||
elif checkSuspended:
|
||||
users_email = [member.get(u'email', member[u'id']) for member in result if (not validRoles or member.get(u'role', ROLE_MEMBER) in validRoles) and member[u'status'] == u'SUSPENDED']
|
||||
else: # elif not checkSuspended
|
||||
users_email = [member.get(u'email', member[u'id']) for member in result if (not validRoles or member.get(u'role', ROLE_MEMBER) in validRoles) and member[u'status'] != u'SUSPENDED']
|
||||
if len(users_email) > 1:
|
||||
sys.stderr.write(u'Group: {0}, Will remove {1} {2}{3}s.\n'.format(group, len(users_email), [u'', u'suspended '][suspended], roles))
|
||||
sys.stderr.write(u'Group: {0}, Will remove {1} {2}{3}s.\n'.format(group, len(users_email), u'' if checkSuspended is None else [u'Non-suspended ', u'Suspended '][checkSuspended], roles))
|
||||
for user_email in users_email:
|
||||
items.append(['gam', 'update', 'group', group, 'remove', user_email])
|
||||
else:
|
||||
@@ -8629,23 +8608,27 @@ def doUpdateAlias():
|
||||
callGAPI(cd.groups().aliases(), u'insert', groupKey=target_email, body={u'alias': alias})
|
||||
print u'updated alias %s' % alias
|
||||
|
||||
def doUpdateCros():
|
||||
cd = buildGAPIObject(u'directory')
|
||||
deviceId = sys.argv[3]
|
||||
if deviceId[:6].lower() == u'query:':
|
||||
query = deviceId[6:]
|
||||
def getCrOSDeviceEntity(i, cd):
|
||||
myarg = sys.argv[i].lower()
|
||||
if myarg == u'cros_sn':
|
||||
return i+2, getUsersToModify(u'cros_sn', sys.argv[i+1])
|
||||
if myarg == u'query':
|
||||
return i+2, getUsersToModify(u'crosquery', sys.argv[i+1])
|
||||
if myarg[:6] == u'query:':
|
||||
query = sys.argv[i][6:]
|
||||
if query[:12].lower() == u'orgunitpath:':
|
||||
kwargs = {u'orgUnitPath': query[12:]}
|
||||
else:
|
||||
kwargs = {u'query': query}
|
||||
devices_result = callGAPIpages(cd.chromeosdevices(), u'list', u'chromeosdevices',
|
||||
customerId=GC_Values[GC_CUSTOMER_ID], fields=u'chromeosdevices/deviceId,nextPageToken', **kwargs)
|
||||
devices = list()
|
||||
for a_device in devices_result:
|
||||
devices.append(a_device[u'deviceId'])
|
||||
else:
|
||||
devices = [deviceId,]
|
||||
i = 4
|
||||
devices = callGAPIpages(cd.chromeosdevices(), u'list', u'chromeosdevices',
|
||||
customerId=GC_Values[GC_CUSTOMER_ID],
|
||||
fields=u'nextPageToken,chromeosdevices(deviceId)', **kwargs)
|
||||
return i+1, [device[u'deviceId'] for device in devices]
|
||||
return i+1, sys.argv[i].replace(u',', u' ').split()
|
||||
|
||||
def doUpdateCros():
|
||||
cd = buildGAPIObject(u'directory')
|
||||
i, devices = getCrOSDeviceEntity(3, cd)
|
||||
update_body = {}
|
||||
action_body = {}
|
||||
orgUnitPath = None
|
||||
@@ -8744,11 +8727,13 @@ def doUpdateOrg():
|
||||
cd = buildGAPIObject(u'directory')
|
||||
orgUnitPath = getOrgUnitItem(sys.argv[3])
|
||||
if sys.argv[4].lower() in [u'move', u'add']:
|
||||
if sys.argv[5].lower() in usergroup_types:
|
||||
users = getUsersToModify(entity_type=sys.argv[5].lower(), entity=sys.argv[6])
|
||||
entity_type = sys.argv[5].lower()
|
||||
if entity_type in usergroup_types:
|
||||
users = getUsersToModify(entity_type=entity_type, entity=sys.argv[6])
|
||||
else:
|
||||
users = getUsersToModify(entity_type=u'user', entity=sys.argv[5])
|
||||
if (sys.argv[5].lower().startswith(u'cros')) or ((sys.argv[5].lower() == u'all') and (sys.argv[6].lower() == u'cros')):
|
||||
entity_type = u'users'
|
||||
users = getUsersToModify(entity_type=entity_type, entity=sys.argv[5])
|
||||
if (entity_type.startswith(u'cros')) or ((entity_type == u'all') and (sys.argv[6].lower() == u'cros')):
|
||||
for l in range(0, len(users), 50):
|
||||
move_body = {u'deviceIds': users[l:l+50]}
|
||||
print u' moving %s devices to %s' % (len(move_body[u'deviceIds']), orgUnitPath)
|
||||
@@ -9391,20 +9376,7 @@ def _getFilterDate(dateStr):
|
||||
|
||||
def doGetCrosInfo():
|
||||
cd = buildGAPIObject(u'directory')
|
||||
deviceId = sys.argv[3]
|
||||
if deviceId[:6].lower() == u'query:':
|
||||
query = deviceId[6:]
|
||||
if query[:12].lower() == u'orgunitpath:':
|
||||
kwargs = {u'orgUnitPath': query[12:]}
|
||||
else:
|
||||
kwargs = {u'query': query}
|
||||
devices_result = callGAPIpages(cd.chromeosdevices(), u'list', u'chromeosdevices',
|
||||
customerId=GC_Values[GC_CUSTOMER_ID], fields=u'chromeosdevices/deviceId,nextPageToken', **kwargs)
|
||||
devices = list()
|
||||
for a_device in devices_result:
|
||||
devices.append(a_device[u'deviceId'])
|
||||
else:
|
||||
devices = [deviceId,]
|
||||
i, devices = getCrOSDeviceEntity(3, cd)
|
||||
downloadfile = None
|
||||
targetFolder = GC_Values[GC_DRIVE_DIR]
|
||||
projection = None
|
||||
@@ -9412,7 +9384,6 @@ def doGetCrosInfo():
|
||||
noLists = False
|
||||
startDate = endDate = None
|
||||
listLimit = 0
|
||||
i = 4
|
||||
while i < len(sys.argv):
|
||||
myarg = sys.argv[i].lower().replace(u'_', u'')
|
||||
if myarg == u'nolists':
|
||||
@@ -9759,10 +9730,11 @@ def doGetNotifications():
|
||||
print u'--------------'
|
||||
print u''
|
||||
|
||||
def orgUnitPathQuery(path):
|
||||
if path != u'/':
|
||||
return u"orgUnitPath='{0}'".format(path.replace(u"'", u"\\'"))
|
||||
return None
|
||||
def orgUnitPathQuery(path, checkSuspended):
|
||||
query = u"orgUnitPath='{0}'".format(path.replace(u"'", u"\\'")) if path != u'/' else u''
|
||||
if checkSuspended is not None:
|
||||
query += u' isSuspended={0}'.format(checkSuspended)
|
||||
return query
|
||||
|
||||
def makeOrgUnitPathAbsolute(path):
|
||||
if path == u'/':
|
||||
@@ -9830,6 +9802,7 @@ def getTopLevelOrgId(cd, orgUnitPath):
|
||||
|
||||
def doGetOrgInfo(name=None, return_attrib=None):
|
||||
cd = buildGAPIObject(u'directory')
|
||||
checkSuspended = None
|
||||
if not name:
|
||||
name = getOrgUnitItem(sys.argv[3])
|
||||
get_users = True
|
||||
@@ -9843,6 +9816,9 @@ def doGetOrgInfo(name=None, return_attrib=None):
|
||||
elif myarg in [u'children', u'child']:
|
||||
show_children = True
|
||||
i += 1
|
||||
elif myarg in [u'suspended', u'notsuspended']:
|
||||
checkSuspended = myarg == u'suspended'
|
||||
i += 1
|
||||
else:
|
||||
systemErrorExit(2, '%s is not a valid argument for "gam info org"' % sys.argv[i])
|
||||
if name == u'/':
|
||||
@@ -9863,11 +9839,16 @@ def doGetOrgInfo(name=None, return_attrib=None):
|
||||
print_json(None, result)
|
||||
if get_users:
|
||||
name = result[u'orgUnitPath']
|
||||
print u'Users: '
|
||||
page_message = u'Got %%total_items%% Users: %%first_item%% - %%last_item%%\n'
|
||||
users = callGAPIpages(cd.users(), u'list', u'users', page_message=page_message,
|
||||
message_attribute=u'primaryEmail', customer=GC_Values[GC_CUSTOMER_ID], query=orgUnitPathQuery(name),
|
||||
message_attribute=u'primaryEmail', customer=GC_Values[GC_CUSTOMER_ID], query=orgUnitPathQuery(name, checkSuspended),
|
||||
fields=u'users(primaryEmail,orgUnitPath),nextPageToken', maxResults=GC_Values[GC_USER_MAX_RESULTS])
|
||||
if checkSuspended is None:
|
||||
print u'Users:'
|
||||
elif not checkSuspended:
|
||||
print u'Users (Not suspended):'
|
||||
else:
|
||||
print u'Users (Suspended):'
|
||||
for user in users:
|
||||
if show_children or (name.lower() == user[u'orgUnitPath'].lower()):
|
||||
sys.stdout.write(u' %s' % user[u'primaryEmail'])
|
||||
@@ -10919,7 +10900,7 @@ def doPrintGroupMembers():
|
||||
todrive = False
|
||||
membernames = False
|
||||
customer = GC_Values[GC_CUSTOMER_ID]
|
||||
usedomain = usemember = usequery = None
|
||||
checkSuspended = usedomain = usemember = usequery = None
|
||||
roles = []
|
||||
fields = u'nextPageToken,members(email,id,role,status,type)'
|
||||
titles = [u'group']
|
||||
@@ -10927,7 +10908,7 @@ def doPrintGroupMembers():
|
||||
groups_to_get = []
|
||||
i = 3
|
||||
while i < len(sys.argv):
|
||||
myarg = sys.argv[i].lower()
|
||||
myarg = sys.argv[i].lower().replace(u'_', u'')
|
||||
if myarg == u'todrive':
|
||||
todrive = True
|
||||
i += 1
|
||||
@@ -10958,10 +10939,17 @@ def doPrintGroupMembers():
|
||||
else:
|
||||
systemErrorExit(2, '%s is not a valid role for "gam print group-members %s"' % (role, myarg))
|
||||
i += 2
|
||||
elif myarg == u'group':
|
||||
elif myarg in [u'group', u'groupns', u'groupsusp']:
|
||||
group_email = normalizeEmailAddressOrUID(sys.argv[i+1])
|
||||
groups_to_get = [{u'email': group_email}]
|
||||
if myarg == u'groupns':
|
||||
checkSuspended = False
|
||||
elif myarg == u'groupsusp':
|
||||
checkSuspended = True
|
||||
i += 2
|
||||
elif myarg in [u'suspended', u'notsuspended']:
|
||||
checkSuspended = myarg == u'suspended'
|
||||
i += 1
|
||||
else:
|
||||
systemErrorExit(2, '%s is not a valid argument for "gam print group-members"' % sys.argv[i])
|
||||
if not groups_to_get:
|
||||
@@ -10979,10 +10967,8 @@ def doPrintGroupMembers():
|
||||
soft_errors=True,
|
||||
groupKey=group_email, roles=listRoles, fields=listFields, maxResults=GC_Values[GC_MEMBER_MAX_RESULTS])
|
||||
for member in group_members:
|
||||
for unwanted_item in [u'kind', u'etag']:
|
||||
if unwanted_item in member:
|
||||
del member[unwanted_item]
|
||||
if validRoles and member.get(u'role', ROLE_MEMBER) not in validRoles:
|
||||
if ((validRoles and member.get(u'role', ROLE_MEMBER) not in validRoles) or
|
||||
(checkSuspended is not None and ((not checkSuspended and member[u'status'] == u'SUSPENDED') or (checkSuspended and member[u'status'] != u'SUSPENDED')))):
|
||||
continue
|
||||
for title in member:
|
||||
if title not in titles:
|
||||
@@ -11045,6 +11031,43 @@ def doPrintVaultMatters():
|
||||
sortCSVTitles(initialTitles, titles)
|
||||
writeCSVfile(csvRows, titles, u'Vault Matters', todrive)
|
||||
|
||||
def doPrintVaultExports():
|
||||
v = buildGAPIObject(u'vault')
|
||||
todrive = False
|
||||
csvRows = []
|
||||
initialTitles = [u'matterId', u'id', u'name', u'createTime', u'status']
|
||||
titles = initialTitles[:]
|
||||
matters = []
|
||||
matterIds = []
|
||||
i = 3
|
||||
while i < len(sys.argv):
|
||||
myarg = sys.argv[i].lower().replace(u'_', u'')
|
||||
if myarg == u'todrive':
|
||||
todrive = True
|
||||
i += 1
|
||||
elif myarg in [u'matter', u'matters']:
|
||||
matters = sys.argv[i+1].split(u',')
|
||||
i += 2
|
||||
else:
|
||||
systemErrorExit(3, '%s is not a valid a valid argument to "gam print exports"' % myarg)
|
||||
if not matters:
|
||||
matters_results = callGAPIpages(v.matters(), u'list', u'matters', view=u'BASIC', fields=u'matters(matterId,state),nextPageToken')
|
||||
for matter in matters_results:
|
||||
if matter[u'state'] != u'OPEN':
|
||||
print u'ignoring matter %s in state %s' % (matter[u'matterId'], matter[u'state'])
|
||||
continue
|
||||
matterIds.append(matter[u'matterId'])
|
||||
else:
|
||||
for matter in matters:
|
||||
matterIds.append(getMatterItem(v, matter))
|
||||
for matterId in matterIds:
|
||||
sys.stderr.write(u'Retrieving exports for matter %s\n' % matterId)
|
||||
exports = callGAPIpages(v.matters().exports(), u'list', u'exports', matterId=matterId)
|
||||
for export in exports:
|
||||
addRowTitlesToCSVfile(flatten_json(export, flattened={u'matterId': matterId}), csvRows, titles)
|
||||
sortCSVTitles(initialTitles, titles)
|
||||
writeCSVfile(csvRows, titles, u'Vault Exports', todrive)
|
||||
|
||||
def doPrintVaultHolds():
|
||||
v = buildGAPIObject(u'vault')
|
||||
todrive = False
|
||||
@@ -11071,8 +11094,9 @@ def doPrintVaultHolds():
|
||||
print u'ignoring matter %s in state %s' % (matter[u'matterId'], matter[u'state'])
|
||||
continue
|
||||
matterIds.append(matter[u'matterId'])
|
||||
for matter in matters:
|
||||
matterIds.append(convertMatterNameToID(v, matter))
|
||||
else:
|
||||
for matter in matters:
|
||||
matterIds.append(getMatterItem(v, matter))
|
||||
for matterId in matterIds:
|
||||
sys.stderr.write(u'Retrieving holds for matter %s\n' % matterId)
|
||||
holds = callGAPIpages(v.matters().holds(), u'list', u'holds', matterId=matterId)
|
||||
@@ -11728,7 +11752,7 @@ def _getRoleVerification(memberRoles, fields):
|
||||
else:
|
||||
return (set(), memberRoles, fields)
|
||||
|
||||
def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=None, checkNotSuspended=False, groupUserMembersOnly=True):
|
||||
def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=None, checkSuspended=None, groupUserMembersOnly=True):
|
||||
got_uids = False
|
||||
if entity_type is None:
|
||||
entity_type = sys.argv[1].lower()
|
||||
@@ -11739,7 +11763,11 @@ def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=No
|
||||
users = [entity,]
|
||||
elif entity_type == u'users':
|
||||
users = entity.replace(u',', u' ').split()
|
||||
elif entity_type == u'group':
|
||||
elif entity_type in [u'group', u'group_ns', u'group_susp']:
|
||||
if entity_type == u'group_ns':
|
||||
checkSuspended = False
|
||||
elif entity_type == u'group_susp':
|
||||
checkSuspended = True
|
||||
got_uids = True
|
||||
group = entity
|
||||
if member_type is None:
|
||||
@@ -11758,44 +11786,51 @@ def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=No
|
||||
for member in members:
|
||||
if (((not groupUserMembersOnly) or (member[u'type'] == u'USER')) and
|
||||
(not validRoles or member.get(u'role', ROLE_MEMBER) in validRoles) and
|
||||
not (checkNotSuspended and (member[u'status'] == u'SUSPENDED'))):
|
||||
(checkSuspended is None or (not checkSuspended and member[u'status'] != u'SUSPENDED') or (checkSuspended and member[u'status'] == u'SUSPENDED'))):
|
||||
users.append(member.get(u'email', member[u'id']))
|
||||
elif entity_type in [u'ou', u'org']:
|
||||
elif entity_type in [u'ou', u'org', u'ou_ns', u'org_ns', u'ou_susp', u'org_susp',]:
|
||||
if entity_type in [u'ou_ns', u'org_ns']:
|
||||
checkSuspended = False
|
||||
elif entity_type in [u'ou_susp', u'org_susp']:
|
||||
checkSuspended = True
|
||||
got_uids = True
|
||||
ou = makeOrgUnitPathAbsolute(entity)
|
||||
users = []
|
||||
if ou.startswith(u'id:'):
|
||||
ou = callGAPI(cd.orgunits(), u'get',
|
||||
customerId=GC_Values[GC_CUSTOMER_ID], orgUnitPath=ou, fields=u'orgUnitPath')[u'orgUnitPath']
|
||||
query = orgUnitPathQuery(ou)
|
||||
query = orgUnitPathQuery(ou, checkSuspended)
|
||||
page_message = None
|
||||
if not silent:
|
||||
printGettingAllItems(u'Users', query)
|
||||
page_message = u'Got %%total_items%% Users...'
|
||||
members = callGAPIpages(cd.users(), u'list', u'users', page_message=page_message,
|
||||
customer=GC_Values[GC_CUSTOMER_ID], fields=u'nextPageToken,users(primaryEmail,suspended,orgUnitPath)',
|
||||
customer=GC_Values[GC_CUSTOMER_ID], fields=u'nextPageToken,users(primaryEmail,orgUnitPath)',
|
||||
query=query, maxResults=GC_Values[GC_USER_MAX_RESULTS])
|
||||
ou = ou.lower()
|
||||
for member in members:
|
||||
if (ou == member.get(u'orgUnitPath', u'').lower()) and not (checkNotSuspended and member[u'suspended']):
|
||||
if ou == member.get(u'orgUnitPath', u'').lower():
|
||||
users.append(member[u'primaryEmail'])
|
||||
if not silent:
|
||||
sys.stderr.write(u"%s Users are directly in the OU.\n" % len(users))
|
||||
elif entity_type in [u'ou_and_children', u'ou_and_child']:
|
||||
elif entity_type in [u'ou_and_children', u'ou_and_child', u'ou_and_children_ns', u'ou_and_child_ns', u'ou_and_children_susp', u'ou_and_child_susp']:
|
||||
if entity_type in [u'ou_and_children_ns', u'ou_and_child_ns']:
|
||||
checkSuspended = False
|
||||
elif entity_type in [u'ou_and_children_susp', u'ou_and_child_susp']:
|
||||
checkSuspended = True
|
||||
got_uids = True
|
||||
ou = makeOrgUnitPathAbsolute(entity)
|
||||
users = []
|
||||
query = orgUnitPathQuery(ou)
|
||||
query = orgUnitPathQuery(ou, checkSuspended)
|
||||
page_message = None
|
||||
if not silent:
|
||||
printGettingAllItems(u'Users', query)
|
||||
page_message = u'Got %%total_items%% Users...'
|
||||
members = callGAPIpages(cd.users(), u'list', u'users', page_message=page_message,
|
||||
customer=GC_Values[GC_CUSTOMER_ID], fields=u'nextPageToken,users(primaryEmail,suspended)',
|
||||
customer=GC_Values[GC_CUSTOMER_ID], fields=u'nextPageToken,users(primaryEmail)',
|
||||
query=query, maxResults=GC_Values[GC_USER_MAX_RESULTS])
|
||||
for member in members:
|
||||
if not (checkNotSuspended and member[u'suspended']):
|
||||
users.append(member[u'primaryEmail'])
|
||||
users.append(member[u'primaryEmail'])
|
||||
if not silent:
|
||||
sys.stderr.write(u"done.\r\n")
|
||||
elif entity_type in [u'query', u'queries']:
|
||||
@@ -11814,11 +11849,10 @@ def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=No
|
||||
customer=GC_Values[GC_CUSTOMER_ID], fields=u'nextPageToken,users(primaryEmail,suspended)',
|
||||
query=query, maxResults=GC_Values[GC_USER_MAX_RESULTS])
|
||||
for member in members:
|
||||
if not checkNotSuspended or not member[u'suspended']:
|
||||
email = member[u'primaryEmail']
|
||||
if email not in usersSet:
|
||||
usersSet.add(email)
|
||||
users.append(email)
|
||||
email = member[u'primaryEmail']
|
||||
if (checkSuspended is None or checkSuspended == member[u'suspended']) and email not in usersSet:
|
||||
usersSet.add(email)
|
||||
users.append(email)
|
||||
if not silent:
|
||||
sys.stderr.write(u"done.\r\n")
|
||||
elif entity_type in [u'license', u'licenses', u'licence', u'licences']:
|
||||
@@ -11873,15 +11907,15 @@ def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=No
|
||||
users = []
|
||||
entity = entity.lower()
|
||||
if entity == u'users':
|
||||
query = u'isSuspended=False'
|
||||
if not silent:
|
||||
printGettingAllItems(u'Users', None)
|
||||
page_message = u'Got %%total_items%% Users...'
|
||||
all_users = callGAPIpages(cd.users(), u'list', u'users', page_message=page_message,
|
||||
customer=GC_Values[GC_CUSTOMER_ID],
|
||||
fields=u'nextPageToken,users(primaryEmail,suspended)', maxResults=GC_Values[GC_USER_MAX_RESULTS])
|
||||
customer=GC_Values[GC_CUSTOMER_ID], query=query,
|
||||
fields=u'nextPageToken,users(primaryEmail)', maxResults=GC_Values[GC_USER_MAX_RESULTS])
|
||||
for member in all_users:
|
||||
if not member[u'suspended']:
|
||||
users.append(member[u'primaryEmail'])
|
||||
users.append(member[u'primaryEmail'])
|
||||
if not silent:
|
||||
sys.stderr.write(u"done getting %s Users.\r\n" % len(users))
|
||||
elif entity == u'cros':
|
||||
@@ -11900,11 +11934,13 @@ def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=No
|
||||
elif entity_type == u'cros':
|
||||
users = entity.replace(u',', u' ').split()
|
||||
entity = u'cros'
|
||||
elif entity_type in [u'crosquery', u'crosqueries']:
|
||||
if entity_type == u'crosquery':
|
||||
queries = [entity]
|
||||
else:
|
||||
elif entity_type in [u'crosquery', u'crosqueries', u'cros_sn']:
|
||||
if entity_type == u'cros_sn':
|
||||
queries = [u'id:{0}'.format(sn) for sn in shlexSplitList(entity)]
|
||||
elif entity_type == u'crosqueries':
|
||||
queries = shlexSplitList(entity)
|
||||
else:
|
||||
queries = [entity]
|
||||
users = []
|
||||
usersSet = set()
|
||||
for query in queries:
|
||||
@@ -11989,7 +12025,7 @@ def doRequestOAuth(login_hint=None):
|
||||
flags = cmd_flags(noLocalWebserver=GC_Values[GC_NO_BROWSER])
|
||||
scopes = getScopesFromUser()
|
||||
if scopes is None:
|
||||
return
|
||||
systemErrorExit(0, u'')
|
||||
client_id, client_secret = getOAuthClientIDAndSecret()
|
||||
login_hint = getValidateLoginHint(login_hint)
|
||||
flow = oauth2client.client.OAuth2WebServerFlow(client_id=client_id,
|
||||
@@ -12081,9 +12117,6 @@ OAUTH2_SCOPES = [
|
||||
{u'name': u'Directory API - Users',
|
||||
u'subscopes': [u'readonly'],
|
||||
u'scopes': u'https://www.googleapis.com/auth/admin.directory.user'},
|
||||
{u'name': u'Email Settings API - Delegation',
|
||||
u'subscopes': [],
|
||||
u'scopes': u'https://apps-apis.google.com/a/feeds/emailsettings/2.0/'},
|
||||
{u'name': u'Group Settings API',
|
||||
u'subscopes': [],
|
||||
u'scopes': u'https://www.googleapis.com/auth/apps.groups.settings'},
|
||||
@@ -12551,7 +12584,7 @@ def ProcessGAMCommand(args):
|
||||
elif argument in [u'hold', u'vaulthold']:
|
||||
doGetVaultHoldInfo()
|
||||
elif argument in [u'export', u'vaultexport']:
|
||||
doGetVaultExport()
|
||||
doGetVaultExportInfo()
|
||||
elif argument in [u'building']:
|
||||
doGetBuildingInfo()
|
||||
else:
|
||||
@@ -12606,6 +12639,8 @@ def ProcessGAMCommand(args):
|
||||
doUpdateVaultMatter(action=command)
|
||||
elif argument in [u'hold', u'vaulthold']:
|
||||
doDeleteVaultHold()
|
||||
elif argument in [u'export', u'vaultexport']:
|
||||
doDeleteVaultExport()
|
||||
elif argument in [u'building']:
|
||||
doDeleteBuilding()
|
||||
elif argument in [u'feature']:
|
||||
@@ -12682,6 +12717,8 @@ def ProcessGAMCommand(args):
|
||||
doPrintVaultMatters()
|
||||
elif argument in [u'holds', u'vaultholds']:
|
||||
doPrintVaultHolds()
|
||||
elif argument in [u'exports', u'vaultexports']:
|
||||
doPrintVaultExports()
|
||||
elif argument in [u'building', u'buildings']:
|
||||
doPrintBuildings()
|
||||
elif argument in [u'feature', u'features']:
|
||||
|
||||
@@ -10,7 +10,6 @@ for d in a.datas:
|
||||
break
|
||||
a.datas += [('httplib2/cacerts.txt', 'httplib2/cacerts.txt', 'DATA')]
|
||||
a.datas += [('cloudprint-v2.json', 'cloudprint-v2.json', 'DATA')]
|
||||
a.datas += [('email-settings-v2.json', 'email-settings-v2.json', 'DATA')]
|
||||
pyz = PYZ(a.pure)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
|
||||
@@ -10,7 +10,6 @@ for d in a.datas:
|
||||
break
|
||||
a.datas += [('httplib2/cacerts.txt', 'httplib2/cacerts.txt', 'DATA')]
|
||||
a.datas += [('cloudprint-v2.json', 'cloudprint-v2.json', 'DATA')]
|
||||
a.datas += [('email-settings-v2.json', 'email-settings-v2.json', 'DATA')]
|
||||
pyz = PYZ(a.pure)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
|
||||
13
src/var.py
13
src/var.py
@@ -4,7 +4,7 @@ import platform
|
||||
import re
|
||||
|
||||
gam_author = u'Jay Lee <jay0lee@gmail.com>'
|
||||
gam_version = u'4.60'
|
||||
gam_version = u'4.61'
|
||||
gam_license = u'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
|
||||
GAM_URL = u'https://git.io/gam'
|
||||
@@ -24,10 +24,12 @@ TRUE = u'true'
|
||||
FALSE = u'false'
|
||||
true_values = [u'on', u'yes', u'enabled', u'true', u'1']
|
||||
false_values = [u'off', u'no', u'disabled', u'false', u'0']
|
||||
usergroup_types = [u'user', u'users', u'group', u'ou', u'org',
|
||||
u'ou_and_children', u'ou_and_child', u'query', u'queries',
|
||||
u'license', u'licenses', u'licence', u'licences', u'file', u'csv', u'csvfile', u'all',
|
||||
u'cros', u'crosquery', u'crosqueries', u'crosfile', u'croscsv', u'croscsvfile']
|
||||
usergroup_types = [u'user', u'users',
|
||||
u'group', u'group_ns', u'grooup_susp',
|
||||
u'ou', u'org', u'ou_ns', u'org_ns', u'ou_susp', u'org_susp',
|
||||
u'ou_and_children', u'ou_and_child', u'ou_and_children_ns', u'ou_and_child_ns', u'ou_and_children_susp', u'ou_and_child_susp',
|
||||
u'query', u'queries', u'license', u'licenses', u'licence', u'licences', u'file', u'csv', u'csvfile', u'all',
|
||||
u'cros', u'cros_sn', u'crosquery', u'crosqueries', u'crosfile', u'croscsv', u'croscsvfile']
|
||||
ERROR = u'ERROR'
|
||||
ERROR_PREFIX = ERROR+u': '
|
||||
WARNING = u'WARNING'
|
||||
@@ -100,7 +102,6 @@ API_VER_MAPPING = {
|
||||
u'directory': u'directory_v1',
|
||||
u'drive': u'v2',
|
||||
u'drive3': u'v3',
|
||||
u'email-settings': u'v2',
|
||||
u'gmail': u'v1',
|
||||
u'groupssettings': u'v1',
|
||||
u'licensing': u'v1',
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
GAM 4.61
|
||||
- New Gmail delegation API
|
||||
- Remove "admin" command from user create/update to avoid accidental super admins. Still possible to give super admin rights via "gam create admin" command. (Ross)
|
||||
- Vault export fixes by Ross
|
||||
- minor fixes and improvements by Ross and Jay
|
||||
|
||||
GAM 4.60
|
||||
- Google Vault Export API gam support
|
||||
- Ross - add textcolor and backgroundcolor options for Gmail labels
|
||||
- Ross - add owneremail option to print courses
|
||||
- GAM 4.50 had no bugs at all, nothing to fix.
|
||||
- Just kidding, lots of bug fixes and code cleanup. Thanks Ross.
|
||||
|
||||
GAM 4.50
|
||||
- many cleanups, bugfixes and improvements by Ross and ejochman
|
||||
- multiple queries and more options for Chrome OS by Ross
|
||||
|
||||
@@ -11,7 +11,6 @@ for d in a.datas:
|
||||
break
|
||||
a.datas += [('httplib2/cacerts.txt', 'httplib2\cacerts.txt', 'DATA')]
|
||||
a.datas += [('cloudprint-v2.json', 'cloudprint-v2.json', 'DATA')]
|
||||
a.datas += [('email-settings-v2.json', 'email-settings-v2.json', 'DATA')]
|
||||
pyz = PYZ(a.pure)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
|
||||
Reference in New Issue
Block a user