mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-29 10:21:35 +00:00
Compare commits
13 Commits
v7.05.12
...
20250331.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
defac7d9a8 | ||
|
|
d308ad1271 | ||
|
|
09be8b08f7 | ||
|
|
10a91091f2 | ||
|
|
16cef20094 | ||
|
|
e588c8851a | ||
|
|
d14cd1ad56 | ||
|
|
0e82964068 | ||
|
|
6394207c2f | ||
|
|
f12b367019 | ||
|
|
9b130ac8bf | ||
|
|
f35bde4f8b | ||
|
|
9ffabc15ff |
@@ -102,7 +102,7 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
banana|basil|blueberry|flamingo|graphite|grape|
|
banana|basil|blueberry|flamingo|graphite|grape|
|
||||||
lavender|peacock|sage|tangerine|tomato
|
lavender|peacock|sage|tangerine|tomato
|
||||||
<FileFormat> ::=
|
<FileFormat> ::=
|
||||||
csv|doc|dot|docx|dotx|epub|html|jpeg|jpg|mht|odp|ods|odt|
|
csv|doc|dot|docx|dotx|epub|html|jpeg|jpg|json|mht|odp|ods|odt|
|
||||||
pdf|png|ppt|pot|potx|pptx|rtf|svg|tsv|txt|xls|xlt|xlsx|xltx|zip|
|
pdf|png|ppt|pot|potx|pptx|rtf|svg|tsv|txt|xls|xlt|xlsx|xltx|zip|
|
||||||
ms|microsoft|openoffice|
|
ms|microsoft|openoffice|
|
||||||
<LabelColorHex> ::=
|
<LabelColorHex> ::=
|
||||||
@@ -266,6 +266,7 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
appsheetstandard | appsheetenterprisestandard | 1010380002 | AppSheet Enterprise Standard |
|
appsheetstandard | appsheetenterprisestandard | 1010380002 | AppSheet Enterprise Standard |
|
||||||
appsheetplus | appsheetenterpriseplus | 1010380003 | AppSheet Enterprise Plus |
|
appsheetplus | appsheetenterpriseplus | 1010380003 | AppSheet Enterprise Plus |
|
||||||
assuredcontrols | 1010390001 | Assured Controls |
|
assuredcontrols | 1010390001 | Assured Controls |
|
||||||
|
assuredcontrolsplus | 1010390002 | Assured Controls Plus |
|
||||||
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
||||||
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
||||||
cloudidentity | identity | 1010010001 | Cloud Identity |
|
cloudidentity | identity | 1010010001 | Cloud Identity |
|
||||||
@@ -1275,8 +1276,8 @@ If the pattern {{Section}} appears in <FileName>, it will be replaced with the n
|
|||||||
For redirect csv, the optional arguments must appear in the order shown.
|
For redirect csv, the optional arguments must appear in the order shown.
|
||||||
<Redirect> ::=
|
<Redirect> ::=
|
||||||
redirect csv <FileName> [multiprocess] [append] [noheader] [charset <Charset>]
|
redirect csv <FileName> [multiprocess] [append] [noheader] [charset <Charset>]
|
||||||
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
|
[columndelimiter <Character>] [quotechar <Character>] [noescapechar [<Boolean>]]
|
||||||
[sortheaders <StringList>] [timestampcolumn <String>]
|
[sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Bopolean>]]
|
||||||
[todrive <ToDriveAttribute>*] |
|
[todrive <ToDriveAttribute>*] |
|
||||||
redirect stdout <FileName> [multiprocess] [append] |
|
redirect stdout <FileName> [multiprocess] [append] |
|
||||||
redirect stdout null [multiprocess] |
|
redirect stdout null [multiprocess] |
|
||||||
@@ -1907,7 +1908,7 @@ gam calendar|calendars <CalendarEntity> modify <CalendarSettings>+
|
|||||||
|
|
||||||
<ChatContent> ::=
|
<ChatContent> ::=
|
||||||
((text <String>)|
|
((text <String>)|
|
||||||
(textfile <FileName> [charset <CharSet>])|
|
(textfile <FileName> [charset <Charset>])|
|
||||||
(gdoc <UserGoogleDoc>)|
|
(gdoc <UserGoogleDoc>)|
|
||||||
(gcsdoc <StorageBucketObjectName>))
|
(gcsdoc <StorageBucketObjectName>))
|
||||||
|
|
||||||
@@ -3925,6 +3926,10 @@ gam print group-members [todrive <ToDriveAttribute>*]
|
|||||||
|
|
||||||
# Cloud Identity Groups
|
# Cloud Identity Groups
|
||||||
|
|
||||||
|
<CBCMBrowser> ::= id:cbcm-browser.<DeviceId>
|
||||||
|
<ChromeOSDevice> ::= id:chrome-os-device.<DeviceId>
|
||||||
|
<BrowserDeviceList> ::= "(<CBCMBrowser>|<ChromeOSDevice>)(,(<CBCMBrowser>|<ChromeOSDevice>))*"
|
||||||
|
|
||||||
<CIGroupFieldsName> ::=
|
<CIGroupFieldsName> ::=
|
||||||
additionalgroupkeys|
|
additionalgroupkeys|
|
||||||
createtime|
|
createtime|
|
||||||
@@ -3954,12 +3959,12 @@ gam update cigroups <GroupEntity> create|add [<GroupRole>]
|
|||||||
[usersonly|groupsonly]
|
[usersonly|groupsonly]
|
||||||
[notsuspended|suspended] [notarchived|archived]
|
[notsuspended|suspended] [notarchived|archived]
|
||||||
[expire|expires <Time>] [preview] [actioncsv]
|
[expire|expires <Time>] [preview] [actioncsv]
|
||||||
<UserTypeEntity>
|
<UserTypeEntity>|<BrowserDeviceList>
|
||||||
gam update cigroups <GroupEntity> delete|remove [<GroupRole>]
|
gam update cigroups <GroupEntity> delete|remove [<GroupRole>]
|
||||||
[usersonly|groupsonly]
|
[usersonly|groupsonly]
|
||||||
[notsuspended|suspended] [notarchived|archived]
|
[notsuspended|suspended] [notarchived|archived]
|
||||||
[preview] [actioncsv]
|
[preview] [actioncsv]
|
||||||
<UserTypeEntity>
|
<UserTypeEntity>|<BrowserDeviceList>
|
||||||
gam update cigroups <GroupEntity> sync [<GroupRole>|ignorerole]
|
gam update cigroups <GroupEntity> sync [<GroupRole>|ignorerole]
|
||||||
[usersonly|groupsonly] [addonly|removeonly]
|
[usersonly|groupsonly] [addonly|removeonly]
|
||||||
[notsuspended|suspended] [notarchived|archived]
|
[notsuspended|suspended] [notarchived|archived]
|
||||||
@@ -4730,8 +4735,10 @@ gam sendemail [recipient|to] <RecipientEntity>
|
|||||||
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>]
|
||||||
[<MessageContent>] (replace <Tag> <String>)*
|
[<MessageContent>]
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
(replace <Tag> <String>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <String>)*
|
||||||
|
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
@@ -4739,8 +4746,10 @@ gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
|||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>]
|
||||||
[<MessageContent>] (replace <Tag> <String>)*
|
[<MessageContent>]
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
(replace <Tag> <String>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <String>)*
|
||||||
|
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
@@ -4748,8 +4757,10 @@ gam <UserTypeEntity> sendemail from <EmailAddress>
|
|||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>]
|
||||||
[<MessageContent>] (replace <Tag> <String>)*
|
[<MessageContent>]
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
(replace <Tag> <String>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <String>)*
|
||||||
|
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
@@ -5555,7 +5566,9 @@ gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>*
|
|||||||
[mailbox <EmailAaddress>]
|
[mailbox <EmailAaddress>]
|
||||||
[replyto <EmailAaddress>]
|
[replyto <EmailAaddress>]
|
||||||
[<NotifyMessageContent>]
|
[<NotifyMessageContent>]
|
||||||
(replace <Tag> <UserReplacement>)*]
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
|
]
|
||||||
[logpassword <FileName>]
|
[logpassword <FileName>]
|
||||||
[addnumericsuffixonduplicate <Number>]
|
[addnumericsuffixonduplicate <Number>]
|
||||||
|
|
||||||
@@ -5564,7 +5577,7 @@ gam <UserTypeEntity> waitformailbox [retries <Number>]
|
|||||||
gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
|
gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
|
||||||
[verifynotinvitable|alwaysevict] [noactionifalias]
|
[verifynotinvitable|alwaysevict] [noactionifalias]
|
||||||
[updateprimaryemail <RegularExpression> <EmailReplacement>]
|
[updateprimaryemail <RegularExpression> <EmailReplacement>]
|
||||||
[updateoufromgroup <FileName> [charset <CharSet>]
|
[updateoufromgroup <FileName> [charset <Charset>]
|
||||||
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
|
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
|
||||||
[fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
|
[fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
|
||||||
[immutableous <OrgUnitEntity>]|
|
[immutableous <OrgUnitEntity>]|
|
||||||
@@ -5576,10 +5589,12 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
|
|||||||
[subject <String>]
|
[subject <String>]
|
||||||
[notifypassword <String>]
|
[notifypassword <String>]
|
||||||
[from <EmailAaddress>]
|
[from <EmailAaddress>]
|
||||||
[mailbox <EmailAaddress>]
|
[mailbox <EmailAddress>]
|
||||||
[replyto <EmailAaddress>]
|
[replyto <EmailAddress>]
|
||||||
[<NotifyMessageContent>]
|
[<NotifyMessageContent>]
|
||||||
(replace <Tag> <UserReplacement>)*]
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
|
]
|
||||||
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
|
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
|
||||||
[logpassword <FileName>]
|
[logpassword <FileName>]
|
||||||
gam delete user <UserItem> [noactionifalias]
|
gam delete user <UserItem> [noactionifalias]
|
||||||
@@ -5598,9 +5613,9 @@ gam info user [<UserItem>]
|
|||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
|
gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
|
||||||
[verifynotinvitable] [noactionifalias]
|
[verifynotinvitable|alwaysevict] [noactionifalias]
|
||||||
[updateprimaryemail <RegularExpression> <EmailReplacement>]
|
[updateprimaryemail <RegularExpression> <EmailReplacement>]
|
||||||
[updateoufromgroup <FileName> [charset <CharSet>]
|
[updateoufromgroup <FileName> [charset <Charset>]
|
||||||
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
|
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
|
||||||
[fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
|
[fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
|
||||||
[clearschema <SchemaName>|<SchemaNameField>]
|
[clearschema <SchemaName>|<SchemaNameField>]
|
||||||
@@ -5610,13 +5625,15 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
|
|||||||
[notify <EmailAddressList>
|
[notify <EmailAddressList>
|
||||||
[subject <String>]
|
[subject <String>]
|
||||||
[notifypassword <String>]
|
[notifypassword <String>]
|
||||||
[from <EmailAaddress>]
|
[from <EmailAddress>]
|
||||||
[mailbox <EmailAaddress>]
|
[mailbox <EmailAddress>]
|
||||||
|
[replyto <EmailAaddress>]
|
||||||
[<NotifyMessageContent>]
|
[<NotifyMessageContent>]
|
||||||
(replace <Tag> <UserReplacement>)*]
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
|
]
|
||||||
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
|
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
|
||||||
[logpassword <FileName>]
|
[logpassword <FileName>]
|
||||||
[verifynotinvitable]
|
|
||||||
gam delete users <UserTypeEntity> [noactionifalias]
|
gam delete users <UserTypeEntity> [noactionifalias]
|
||||||
gam undelete users <UserEntity> [ou|org|orgunit <OrgUnitPath>]
|
gam undelete users <UserEntity> [ou|org|orgunit <OrgUnitPath>]
|
||||||
gam suspend users <UserTypeEntity> [noactionifalias]
|
gam suspend users <UserTypeEntity> [noactionifalias]
|
||||||
@@ -5633,9 +5650,11 @@ gam info users <UserTypeEntity>
|
|||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
|
gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
|
||||||
[verifynotinvitable] [noactionifalias]
|
[verifynotinvitable|alwaysevict] [noactionifalias]
|
||||||
[updateprimaryemail <RegularExpression> <EmailReplacement>]
|
[updateprimaryemail <RegularExpression> <EmailReplacement>]
|
||||||
[updateoufromgroup <CSVFileInput> [keyfield <FieldName>] [datafield <FieldName>]]
|
[updateoufromgroup <FileName> [charset <Charset>]
|
||||||
|
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
|
||||||
|
[fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
|
||||||
[clearschema <SchemaName>|<SchemaNameField>]
|
[clearschema <SchemaName>|<SchemaNameField>]
|
||||||
[createifnotfound] [notfoundpassword (random [<Integer>])|blocklogin|<Password>]
|
[createifnotfound] [notfoundpassword (random [<Integer>])|blocklogin|<Password>]
|
||||||
(groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)*
|
(groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)*
|
||||||
@@ -5644,12 +5663,14 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
|
|||||||
[subject <String>]
|
[subject <String>]
|
||||||
[notifypassword <String>]
|
[notifypassword <String>]
|
||||||
[from <EmailAaddress>]
|
[from <EmailAaddress>]
|
||||||
[mailbox <EmailAaddress>]
|
[mailbox <EmailAddress>]
|
||||||
|
[replyto <EmailAddress>]
|
||||||
[<NotifyMessageContent>]
|
[<NotifyMessageContent>]
|
||||||
(replace <Tag> <UserReplacement>)*]
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
|
]
|
||||||
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
|
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
|
||||||
[logpassword <FileName>]
|
[logpassword <FileName>]
|
||||||
[verifynotinvitable]
|
|
||||||
gam <UserTypeEntity> delete users [noactionifalias]
|
gam <UserTypeEntity> delete users [noactionifalias]
|
||||||
gam <UserEntity> undelete users [ou|org|orgunit <OrgUnitPath>]
|
gam <UserEntity> undelete users [ou|org|orgunit <OrgUnitPath>]
|
||||||
gam <UserTypeEntity> suspend users [noactionifalias]
|
gam <UserTypeEntity> suspend users [noactionifalias]
|
||||||
@@ -6160,7 +6181,7 @@ gam <UserTypeEntity> print focustime|outofoffice|workinglocation
|
|||||||
|
|
||||||
<ChatContent> ::=
|
<ChatContent> ::=
|
||||||
((text <String>)|
|
((text <String>)|
|
||||||
(textfile <FileName> [charset <CharSet>])|
|
(textfile <FileName> [charset <Charset>])|
|
||||||
(gdoc <UserGoogleDoc>)|
|
(gdoc <UserGoogleDoc>)|
|
||||||
(gcsdoc <StorageBucketObjectName>))
|
(gcsdoc <StorageBucketObjectName>))
|
||||||
|
|
||||||
@@ -6522,7 +6543,7 @@ gam <UserTypeEntity> update drivefile <DriveFileEntity> [copy] [returnidonly|ret
|
|||||||
[timestamp [<Boolean>]] [timeformat <String>]
|
[timestamp [<Boolean>]] [timeformat <String>]
|
||||||
<DriveFileUpdateAttribute>*
|
<DriveFileUpdateAttribute>*
|
||||||
[(gsheet|csvsheet <SheetEntity> [clearfilter])|(addsheet <String>)]
|
[(gsheet|csvsheet <SheetEntity> [clearfilter])|(addsheet <String>)]
|
||||||
[charset <CharSet>] [columndelimiter <Character>]
|
[charset <Charset>] [columndelimiter <Character>]
|
||||||
|
|
||||||
<DriveFileCopyAttribute> ::=
|
<DriveFileCopyAttribute> ::=
|
||||||
(contentrestrictions (readonly false)|(readonly true [reason <String>]) [ownerrestricted [<Boolean>]])|
|
(contentrestrictions (readonly false)|(readonly true [reason <String>]) [ownerrestricted [<Boolean>]])|
|
||||||
@@ -7527,22 +7548,28 @@ gam <UserTypeEntity> print labels|label [todrive <ToDriveAttribute>*]
|
|||||||
(emlfile <FileName> [charset <Charset>])
|
(emlfile <FileName> [charset <Charset>])
|
||||||
|
|
||||||
gam <UserTypeEntity> draft message
|
gam <UserTypeEntity> draft message
|
||||||
<MessageContent> (replace <Tag> <UserReplacement>)*
|
<MessageContent>
|
||||||
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
(attach <FileName> [charset <CharSet>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
gam <UserTypeEntity> import message
|
gam <UserTypeEntity> import message
|
||||||
<MessageContent> (replace <Tag> <UserReplacement>)*
|
<MessageContent>
|
||||||
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
(addlabel <LabelName>)* [labels <LabelNameList>]
|
(addlabel <LabelName>)* [labels <LabelNameList>]
|
||||||
(attach <FileName> [charset <CharSet>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[deleted [<Boolean>]] [checkspam|nevermarkspam [<Boolean>]] [processforcalendar [<Boolean>]]
|
[deleted [<Boolean>]] [checkspam|nevermarkspam [<Boolean>]] [processforcalendar [<Boolean>]]
|
||||||
gam <UserTypeEntity> insert message
|
gam <UserTypeEntity> insert message
|
||||||
<MessageContent> (replace <Tag> <UserReplacement>)*
|
<MessageContent>
|
||||||
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
(addlabel <LabelName>)* [labels <LabelNameList>]
|
(addlabel <LabelName>)* [labels <LabelNameList>]
|
||||||
(attach <FileName> [charset <CharSet>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[deleted [<Boolean>]]
|
[deleted [<Boolean>]]
|
||||||
|
|
||||||
@@ -7621,13 +7648,17 @@ gam <UserTypeEntity> print gmailprofile [todrive <ToDriveAttribute>*]
|
|||||||
# Users - Gmail - Send As/Signature/Vacation
|
# Users - Gmail - Send As/Signature/Vacation
|
||||||
|
|
||||||
gam <UserTypeEntity> [create|add] sendas <EmailAddress> [name] <String>
|
gam <UserTypeEntity> [create|add] sendas <EmailAddress> [name] <String>
|
||||||
[<SendAsContent> (replace <Tag> <UserReplacement>)*]
|
[<SendAsContent>
|
||||||
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
|
||||||
[html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
[html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
||||||
[smtpmsa.host <SMTPHostName> smtpmsa.port 25|465|587
|
[smtpmsa.host <SMTPHostName> smtpmsa.port 25|465|587
|
||||||
smtpmsa.username <UserName> smtpmsa.password <Password>
|
smtpmsa.username <UserName> smtpmsa.password <Password>
|
||||||
[smtpmsa.securitymode none|ssl|starttls]]
|
[smtpmsa.securitymode none|ssl|starttls]]
|
||||||
gam <UserTypeEntity> update sendas <EmailAddress> [name <String>]
|
gam <UserTypeEntity> update sendas <EmailAddress> [name <String>]
|
||||||
[<SendAsContent> (replace <Tag> <UserReplacement>)*]
|
[<SendAsContent>
|
||||||
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
|
||||||
[html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
[html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
||||||
gam <UserTypeEntity> delete sendas <EmailAddressEntity>
|
gam <UserTypeEntity> delete sendas <EmailAddressEntity>
|
||||||
gam <UserTypeEntity> info sendas <EmailAddressEntity> [compact|format|html]
|
gam <UserTypeEntity> info sendas <EmailAddressEntity> [compact|format|html]
|
||||||
@@ -7637,7 +7668,9 @@ gam <UserTypeEntity> print sendas [compact]
|
|||||||
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
||||||
|
|
||||||
gam <UserTypeEntity> signature|sig
|
gam <UserTypeEntity> signature|sig
|
||||||
<SignatureContent> (replace <Tag> <UserReplacement>)*
|
<SignatureContent>
|
||||||
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
[html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
[html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
||||||
[name <String>]
|
[name <String>]
|
||||||
[primary]
|
[primary]
|
||||||
@@ -7647,7 +7680,9 @@ gam <UserTypeEntity> print signature [compact]
|
|||||||
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
||||||
|
|
||||||
gam <UserTypeEntity> vacation [<Boolean>] [subject <String>]
|
gam <UserTypeEntity> vacation [<Boolean>] [subject <String>]
|
||||||
[<VacationMessageContent> (replace <Tag> <UserReplacement>)*]
|
[<VacationMessageContent>
|
||||||
|
(replace <Tag> <UserReplacement>)*
|
||||||
|
(replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
|
||||||
[html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
|
[html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
|
||||||
[start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
|
[start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
|
||||||
gam <UserTypeEntity> show vacation [compact|format|html] [enabledonly]
|
gam <UserTypeEntity> show vacation [compact|format|html] [enabledonly]
|
||||||
@@ -7774,7 +7809,7 @@ gam <UserTypeEntity> check isinvitable [todrive <ToDriveAttribute>*]
|
|||||||
|
|
||||||
<NoteContent> ::=
|
<NoteContent> ::=
|
||||||
((text <String>)|
|
((text <String>)|
|
||||||
(textfile <FileName> [charset <CharSet>])|
|
(textfile <FileName> [charset <Charset>])|
|
||||||
(gdoc <UserGoogleDoc>)|
|
(gdoc <UserGoogleDoc>)|
|
||||||
(gcsdoc <StorageBucketObjectName>)|
|
(gcsdoc <StorageBucketObjectName>)|
|
||||||
<JSONData>)
|
<JSONData>)
|
||||||
|
|||||||
@@ -1,3 +1,94 @@
|
|||||||
|
7.05.19
|
||||||
|
|
||||||
|
Added `replaceregex <RegularExpression> <ReplacementString> <Tag> <String>` to the following commands:
|
||||||
|
```
|
||||||
|
gam sendemail subject <String> <MessageContent>
|
||||||
|
gam <UserTypeEntity> sendemail subject <String> <MessageContent>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `<RegularExpression>` is used as a match pattern against `<String>` to produce `<ReplacementString>`.
|
||||||
|
Instances of `{Tag}` will be replaced by `<ReplacementString>` in the message subject and body.
|
||||||
|
|
||||||
|
Added `replaceregex <RegularExpression> <ReplacementString> <Tag> <UserReplacement>` to the following commands:
|
||||||
|
```
|
||||||
|
gam create user <NotifyMessageContent>
|
||||||
|
gam update user <NotifyMessageContent>
|
||||||
|
gam update users <NotifyMessageContent>
|
||||||
|
gam <UserTypeEntity> update users <NotifyMessageContent>
|
||||||
|
gam <UserTypeEntity> draft message <MessageContent>
|
||||||
|
gam <UserTypeEntity> import message <MessageContent>
|
||||||
|
gam <UserTypeEntity> insert messageo <MessageContent>
|
||||||
|
gam <UserTypeEntity> create sendas <SendAsContent>
|
||||||
|
gam <UserTypeEntity> update sendas <SendAsContent>
|
||||||
|
gam <UserTypeEntity> signature <SignatureContent>
|
||||||
|
gam <UserTypeEntity> vacation subject <String> <VacationMessageContent>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `<RegularExpression>` is used as a match pattern against `<UserReplacement>` to produce `<ReplacementString>`.
|
||||||
|
Instances of `{Tag}` will be replaced by `<ReplacementString>` in the indicated items.
|
||||||
|
|
||||||
|
For example, when adding a phone number to a signature, an unformatted number can be formatted:
|
||||||
|
```
|
||||||
|
replaceregex "(\d{3})(\d{3})(\d{4})" "(\1) \2-\3" Phone "9876543210"
|
||||||
|
replaces 9876543210 with (987) 654-3210
|
||||||
|
|
||||||
|
replaceregex "(\+\d{2})(\d{3})(\d{3})(\d{3})" "\1 \2 \3 \4" Phone "+61987654321"
|
||||||
|
replaces +61421221506 with +61 987 654 321
|
||||||
|
```
|
||||||
|
|
||||||
|
7.05.18
|
||||||
|
|
||||||
|
Updated `gam calendars <CalendarEntity> show events` and `gam <UserTypeEntity> show events`
|
||||||
|
to display the event description according to `show_convert_cr_nl` in `gam.cfg`;
|
||||||
|
previously, GAM assumed `show_convert_cr_nl = true`.
|
||||||
|
```
|
||||||
|
show_convert_cr_nl = false
|
||||||
|
description:
|
||||||
|
Line 1
|
||||||
|
Line 2
|
||||||
|
Line 3
|
||||||
|
|
||||||
|
show_convert_cr_nl = true
|
||||||
|
description: Line 1\nLine 2\nLine 3\n
|
||||||
|
```
|
||||||
|
|
||||||
|
7.05.17
|
||||||
|
|
||||||
|
Updated commands that delete drive ACLs to handle the following error:
|
||||||
|
```
|
||||||
|
ERROR: 403: cannotDeletePermission - The authenticated user does not have the required access to delete the permission.
|
||||||
|
```
|
||||||
|
|
||||||
|
7.05.16
|
||||||
|
|
||||||
|
Added option `transpose [<Boolean>]` to `redirect csv` that causes
|
||||||
|
GAM to transpose CSV output rows and columns. This will most useful
|
||||||
|
when a `countsonly` option is used in a `print` or `report` command.
|
||||||
|
|
||||||
|
7.05.15
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> get drivefile` and `gam <UserTypeEntity> create drivefile`
|
||||||
|
to allow downloading and uploading of Google Apps Scripts.
|
||||||
|
```
|
||||||
|
$ gam user user1@domain.com get drivefile 1ZY-YkS3E0OKipALra_XzfIh9cvxoILSbb8TRdHBFCpyB_mXI_J8FmjHv format json
|
||||||
|
User: user1@domain.com, Download 1 Drive File
|
||||||
|
User: user1@domain.com, Drive File: Test Project, Downloaded to: /Users/gamteam/GamWork/Test Project.json, Type: Google Doc
|
||||||
|
$ gam user user2@domain.com create drivefile localfile "Test Project.json" mimetype application/vnd.google-apps.script+json drivefilename "Test Project"
|
||||||
|
User: user2@domain.com, Drive File: Test Project(1Ok_svw55VTreZ5CzcViJDLfEzVRi-Un8D9eG6I5pIeVyRl2YsmNiy3C_), Created with content from: Test Project.json
|
||||||
|
```
|
||||||
|
|
||||||
|
7.05.14
|
||||||
|
|
||||||
|
Added the following License SKU:
|
||||||
|
```
|
||||||
|
ProductId SKUId Display Name
|
||||||
|
101039 1010390002 Assured Controls Plus
|
||||||
|
```
|
||||||
|
|
||||||
|
7.05.13
|
||||||
|
|
||||||
|
Updated license product names to match Google.
|
||||||
|
|
||||||
7.05.12
|
7.05.12
|
||||||
|
|
||||||
Fixed bug in `gam update chromepolicy` where `appid` was misinterpreted for `chrome.devices.kiosk` policies
|
Fixed bug in `gam update chromepolicy` where `appid` was misinterpreted for `chrome.devices.kiosk` policies
|
||||||
@@ -6,7 +97,7 @@ and an error was generated.
|
|||||||
ERROR: Chrome Policy Schema: customers/C123abc456/policySchemas/<Field>, Does not exist
|
ERROR: Chrome Policy Schema: customers/C123abc456/policySchemas/<Field>, Does not exist
|
||||||
```
|
```
|
||||||
|
|
||||||
!7.05.11
|
7.05.11
|
||||||
|
|
||||||
Added the following License SKUs:
|
Added the following License SKUs:
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ EOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
target_dir="$HOME/bin"
|
target_dir="$HOME/bin"
|
||||||
target_gam="gam7/gam"
|
target_folder="$target_dir/gam7"
|
||||||
gamarch=$(uname -m)
|
gamarch=$(uname -m)
|
||||||
gamos=$(uname -s)
|
gamos=$(uname -s)
|
||||||
osversion=""
|
osversion=""
|
||||||
@@ -36,7 +36,7 @@ while getopts "hd:a:o:b:lp:u:r:v:s" OPTION
|
|||||||
do
|
do
|
||||||
case $OPTION in
|
case $OPTION in
|
||||||
h) usage; exit;;
|
h) usage; exit;;
|
||||||
d) target_dir="$OPTARG";;
|
d) target_dir="${OPTARG%/}"; target_folder="$target_dir/gam7";;
|
||||||
a) gamarch="$OPTARG";;
|
a) gamarch="$OPTARG";;
|
||||||
o) gamos="$OPTARG";;
|
o) gamos="$OPTARG";;
|
||||||
b) osversion="$OPTARG";;
|
b) osversion="$OPTARG";;
|
||||||
@@ -45,13 +45,11 @@ do
|
|||||||
u) adminuser="$OPTARG";;
|
u) adminuser="$OPTARG";;
|
||||||
r) regularuser="$OPTARG";;
|
r) regularuser="$OPTARG";;
|
||||||
v) gamversion="$OPTARG";;
|
v) gamversion="$OPTARG";;
|
||||||
s) strip_gam="--strip-components 1"; target_gam="gam";;
|
s) strip_gam="--strip-components 1"; target_folder="$target_dir";;
|
||||||
?) usage; exit;;
|
?) usage; exit;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
target_gam="$target_folder/gam"
|
||||||
# remove possible / from end of target_dir
|
|
||||||
target_dir=${target_dir%/}
|
|
||||||
|
|
||||||
update_profile() {
|
update_profile() {
|
||||||
[ "$2" -eq 1 ] || [ -f "$1" ] || return 1
|
[ "$2" -eq 1 ] || [ -f "$1" ] || return 1
|
||||||
@@ -328,9 +326,9 @@ echo_yellow "Downloading ${download_url} to $temp_archive_dir ($check_type)..."
|
|||||||
# Save archive to temp w/o losing our path
|
# Save archive to temp w/o losing our path
|
||||||
(cd "$temp_archive_dir" && curl -O -L -s "${curl_opts[@]}" "$download_url")
|
(cd "$temp_archive_dir" && curl -O -L -s "${curl_opts[@]}" "$download_url")
|
||||||
|
|
||||||
mkdir -p "$target_dir"
|
mkdir -p "$target_folder"
|
||||||
echo_yellow "Deleting contents of $target_dir/gam7/lib"
|
echo_yellow "Deleting contents of $target_folder/lib"
|
||||||
rm -frv "$target_dir/gam7/lib"
|
rm -frv "$target_folder/lib"
|
||||||
|
|
||||||
echo_yellow "Extracting archive to $target_dir"
|
echo_yellow "Extracting archive to $target_dir"
|
||||||
if [[ "$name" =~ tar.xz|tar.gz|tar ]]; then
|
if [[ "$name" =~ tar.xz|tar.gz|tar ]]; then
|
||||||
@@ -351,7 +349,7 @@ fi
|
|||||||
|
|
||||||
# Update profile to add gam command
|
# Update profile to add gam command
|
||||||
if [ "$update_profile" = true ]; then
|
if [ "$update_profile" = true ]; then
|
||||||
alias_line="alias gam=\"${target_dir// /\\ }/$target_gam\""
|
alias_line="alias gam=\"$target_gam\""
|
||||||
if [ "$gamos" == "linux" ]; then
|
if [ "$gamos" == "linux" ]; then
|
||||||
update_profile "$HOME/.bash_aliases" 0 || update_profile "$HOME/.bash_profile" 0 || update_profile "$HOME/.bashrc" 0
|
update_profile "$HOME/.bash_aliases" 0 || update_profile "$HOME/.bash_profile" 0 || update_profile "$HOME/.bashrc" 0
|
||||||
update_profile "$HOME/.zshrc" 0
|
update_profile "$HOME/.zshrc" 0
|
||||||
@@ -365,7 +363,7 @@ fi
|
|||||||
|
|
||||||
if [ "$upgrade_only" = true ]; then
|
if [ "$upgrade_only" = true ]; then
|
||||||
echo_green "Here's information about your GAM upgrade:"
|
echo_green "Here's information about your GAM upgrade:"
|
||||||
"$target_dir/$target_gam" version extended
|
"$target_gam" version extended
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc != 0 )); then
|
if (( $rc != 0 )); then
|
||||||
echo_red "ERROR: Failed running GAM for the first time with return code $rc. Please report this error to GAM mailing list. Exiting."
|
echo_red "ERROR: Failed running GAM for the first time with return code $rc. Please report this error to GAM mailing list. Exiting."
|
||||||
@@ -387,7 +385,7 @@ while true; do
|
|||||||
;;
|
;;
|
||||||
[Nn]*)
|
[Nn]*)
|
||||||
# config_cmd="config no_browser true"
|
# config_cmd="config no_browser true"
|
||||||
touch "$target_dir/gam7/nobrowser.txt" > /dev/null 2>&1
|
touch "$target_folder/nobrowser.txt" > /dev/null 2>&1
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@@ -405,8 +403,8 @@ while true; do
|
|||||||
if [ "$adminuser" == "" ]; then
|
if [ "$adminuser" == "" ]; then
|
||||||
read -p "Please enter your Google Workspace admin email address: " adminuser
|
read -p "Please enter your Google Workspace admin email address: " adminuser
|
||||||
fi
|
fi
|
||||||
# "$target_dir/$target_gam" $config_cmd create project $adminuser
|
# "$target_gam" $config_cmd create project $adminuser
|
||||||
"$target_dir/$target_gam" create project $adminuser
|
"$target_gam" create project $adminuser
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc == 0 )); then
|
if (( $rc == 0 )); then
|
||||||
echo_green "Project creation complete."
|
echo_green "Project creation complete."
|
||||||
@@ -431,8 +429,8 @@ while $project_created; do
|
|||||||
read -p "Are you ready to authorize GAM to perform Google Workspace management operations as your admin account? (yes or no) " yn
|
read -p "Are you ready to authorize GAM to perform Google Workspace management operations as your admin account? (yes or no) " yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*)
|
[Yy]*)
|
||||||
# "$target_dir/$target_gam" $config_cmd oauth create $adminuser
|
# "$target_gam" $config_cmd oauth create $adminuser
|
||||||
"$target_dir/$target_gam" oauth create $adminuser
|
"$target_gam" oauth create $adminuser
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc == 0 )); then
|
if (( $rc == 0 )); then
|
||||||
echo_green "Admin authorization complete."
|
echo_green "Admin authorization complete."
|
||||||
@@ -461,8 +459,8 @@ while $admin_authorized; do
|
|||||||
read -p "Please enter the email address of a regular Google Workspace user: " regularuser
|
read -p "Please enter the email address of a regular Google Workspace user: " regularuser
|
||||||
fi
|
fi
|
||||||
echo_yellow "Great! Checking service account scopes.This will fail the first time. Follow the steps to authorize and retry. It can take a few minutes for scopes to PASS after they've been authorized in the admin console."
|
echo_yellow "Great! Checking service account scopes.This will fail the first time. Follow the steps to authorize and retry. It can take a few minutes for scopes to PASS after they've been authorized in the admin console."
|
||||||
# "$target_dir/$target_gam" $config_cmd user $regularuser check serviceaccount
|
# "$target_gam" $config_cmd user $regularuser check serviceaccount
|
||||||
"$target_dir/$target_gam" user $regularuser check serviceaccount
|
"$target_gam" user $regularuser check serviceaccount
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc == 0 )); then
|
if (( $rc == 0 )); then
|
||||||
echo_green "Service account authorization complete."
|
echo_green "Service account authorization complete."
|
||||||
@@ -483,8 +481,8 @@ while $admin_authorized; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo_green "Here's information about your new GAM installation:"
|
echo_green "Here's information about your new GAM installation:"
|
||||||
#"$target_dir/$target_gam" $config_cmd save version extended
|
#"$target_gam" $config_cmd save version extended
|
||||||
"$target_dir/$target_gam" version extended
|
"$target_gam" version extended
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc != 0 )); then
|
if (( $rc != 0 )); then
|
||||||
echo_red "ERROR: Failed running GAM for the first time with $rc. Please report this error to GAM mailing list. Exiting."
|
echo_red "ERROR: Failed running GAM for the first time with $rc. Please report this error to GAM mailing list. Exiting."
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.05.12'
|
__version__ = '7.05.19'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
#pylint: disable=wrong-import-position
|
#pylint: disable=wrong-import-position
|
||||||
@@ -262,6 +262,7 @@ MIMETYPE_GA_JAM = f'{APPLICATION_VND_GOOGLE_APPS}jam'
|
|||||||
MIMETYPE_GA_MAP = f'{APPLICATION_VND_GOOGLE_APPS}map'
|
MIMETYPE_GA_MAP = f'{APPLICATION_VND_GOOGLE_APPS}map'
|
||||||
MIMETYPE_GA_PRESENTATION = f'{APPLICATION_VND_GOOGLE_APPS}presentation'
|
MIMETYPE_GA_PRESENTATION = f'{APPLICATION_VND_GOOGLE_APPS}presentation'
|
||||||
MIMETYPE_GA_SCRIPT = f'{APPLICATION_VND_GOOGLE_APPS}script'
|
MIMETYPE_GA_SCRIPT = f'{APPLICATION_VND_GOOGLE_APPS}script'
|
||||||
|
MIMETYPE_GA_SCRIPT_JSON = f'{APPLICATION_VND_GOOGLE_APPS}script+json'
|
||||||
MIMETYPE_GA_SHORTCUT = f'{APPLICATION_VND_GOOGLE_APPS}shortcut'
|
MIMETYPE_GA_SHORTCUT = f'{APPLICATION_VND_GOOGLE_APPS}shortcut'
|
||||||
MIMETYPE_GA_3P_SHORTCUT = f'{APPLICATION_VND_GOOGLE_APPS}drive-sdk'
|
MIMETYPE_GA_3P_SHORTCUT = f'{APPLICATION_VND_GOOGLE_APPS}drive-sdk'
|
||||||
MIMETYPE_GA_SITE = f'{APPLICATION_VND_GOOGLE_APPS}site'
|
MIMETYPE_GA_SITE = f'{APPLICATION_VND_GOOGLE_APPS}site'
|
||||||
@@ -4087,13 +4088,8 @@ def SetGlobalVariables():
|
|||||||
GC.Values[GC.OUTPUT_DATEFORMAT] = GM.Globals[GM.OUTPUT_DATEFORMAT]
|
GC.Values[GC.OUTPUT_DATEFORMAT] = GM.Globals[GM.OUTPUT_DATEFORMAT]
|
||||||
if not GC.Values[GC.OUTPUT_TIMEFORMAT]:
|
if not GC.Values[GC.OUTPUT_TIMEFORMAT]:
|
||||||
GC.Values[GC.OUTPUT_TIMEFORMAT] = GM.Globals[GM.OUTPUT_TIMEFORMAT]
|
GC.Values[GC.OUTPUT_TIMEFORMAT] = GM.Globals[GM.OUTPUT_TIMEFORMAT]
|
||||||
# Create/set mode for oauth2.txt.lock
|
# Define lockfile: oauth2.txt.lock
|
||||||
if not GM.Globals[GM.OAUTH2_TXT_LOCK]:
|
GM.Globals[GM.OAUTH2_TXT_LOCK] = f'{GC.Values[GC.OAUTH2_TXT]}.lock'
|
||||||
fileName = f'{GC.Values[GC.OAUTH2_TXT]}.lock'
|
|
||||||
if not os.path.isfile(fileName):
|
|
||||||
closeFile(openFile(fileName, mode=DEFAULT_FILE_APPEND_MODE))
|
|
||||||
os.chmod(fileName, 0o666)
|
|
||||||
GM.Globals[GM.OAUTH2_TXT_LOCK] = fileName
|
|
||||||
# Override httplib2 settings
|
# Override httplib2 settings
|
||||||
httplib2.debuglevel = GC.Values[GC.DEBUG_LEVEL]
|
httplib2.debuglevel = GC.Values[GC.DEBUG_LEVEL]
|
||||||
# Reset global variables if required
|
# Reset global variables if required
|
||||||
@@ -4112,8 +4108,8 @@ def SetGlobalVariables():
|
|||||||
if checkArgumentPresent(Cmd.MULTIPROCESSEXIT_CMD):
|
if checkArgumentPresent(Cmd.MULTIPROCESSEXIT_CMD):
|
||||||
_setMultiprocessExit()
|
_setMultiprocessExit()
|
||||||
# redirect csv <FileName> [multiprocess] [append] [noheader] [charset <CharSet>]
|
# redirect csv <FileName> [multiprocess] [append] [noheader] [charset <CharSet>]
|
||||||
# [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]]
|
# [columndelimiter <Character>] [quotechar <Character>]] [noescapechar [<Boolean>]]
|
||||||
# [sortheaders <StringList>] [timestampcolumn <String>]
|
# [sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Boolean>]]
|
||||||
# [todrive <ToDriveAttribute>*]
|
# [todrive <ToDriveAttribute>*]
|
||||||
# redirect stdout <FileName> [multiprocess] [append]
|
# redirect stdout <FileName> [multiprocess] [append]
|
||||||
# redirect stdout null
|
# redirect stdout null
|
||||||
@@ -4138,6 +4134,8 @@ def SetGlobalVariables():
|
|||||||
GM.Globals[GM.CSV_OUTPUT_SORT_HEADERS] = GC.Values[GC.CSV_OUTPUT_SORT_HEADERS] = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
|
GM.Globals[GM.CSV_OUTPUT_SORT_HEADERS] = GC.Values[GC.CSV_OUTPUT_SORT_HEADERS] = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
|
||||||
if checkArgumentPresent('timestampcolumn'):
|
if checkArgumentPresent('timestampcolumn'):
|
||||||
GM.Globals[GM.CSV_OUTPUT_TIMESTAMP_COLUMN] = GC.Values[GC.CSV_OUTPUT_TIMESTAMP_COLUMN] = getString(Cmd.OB_STRING, minLen=0)
|
GM.Globals[GM.CSV_OUTPUT_TIMESTAMP_COLUMN] = GC.Values[GC.CSV_OUTPUT_TIMESTAMP_COLUMN] = getString(Cmd.OB_STRING, minLen=0)
|
||||||
|
if checkArgumentPresent('transpose'):
|
||||||
|
GM.Globals[GM.CSV_OUTPUT_TRANSPOSE] = getBoolean()
|
||||||
_setCSVFile(filename, mode, encoding, writeHeader, multi)
|
_setCSVFile(filename, mode, encoding, writeHeader, multi)
|
||||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF] = CSVPrintFile()
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF] = CSVPrintFile()
|
||||||
if checkArgumentPresent('todrive'):
|
if checkArgumentPresent('todrive'):
|
||||||
@@ -4446,7 +4444,7 @@ def handleOAuthTokenError(e, softErrors, displayError=False, i=0, count=0):
|
|||||||
if not GM.Globals[GM.CURRENT_SVCACCT_USER]:
|
if not GM.Globals[GM.CURRENT_SVCACCT_USER]:
|
||||||
ClientAPIAccessDeniedExit()
|
ClientAPIAccessDeniedExit()
|
||||||
if softErrors:
|
if softErrors:
|
||||||
entityDoesNotExistWarning(Ent.USER, GM.Globals[GM.CURRENT_SVCACCT_USER], i, count)
|
entityActionFailedWarning([Ent.USER, GM.Globals[GM.CURRENT_SVCACCT_USER], Ent.USER, None], errMsg, i, count)
|
||||||
return None
|
return None
|
||||||
systemErrorExit(SERVICE_NOT_APPLICABLE_RC, Msg.SERVICE_NOT_APPLICABLE_THIS_ADDRESS.format(GM.Globals[GM.CURRENT_SVCACCT_USER]))
|
systemErrorExit(SERVICE_NOT_APPLICABLE_RC, Msg.SERVICE_NOT_APPLICABLE_THIS_ADDRESS.format(GM.Globals[GM.CURRENT_SVCACCT_USER]))
|
||||||
if errMsg in API.OAUTH2_UNAUTHORIZED_ERRORS:
|
if errMsg in API.OAUTH2_UNAUTHORIZED_ERRORS:
|
||||||
@@ -7793,6 +7791,7 @@ class CSVPrintFile():
|
|||||||
def __init__(self, titles=None, sortTitles=None, indexedTitles=None):
|
def __init__(self, titles=None, sortTitles=None, indexedTitles=None):
|
||||||
self.rows = []
|
self.rows = []
|
||||||
self.rowCount = 0
|
self.rowCount = 0
|
||||||
|
self.outputTranspose = GM.Globals[GM.CSV_OUTPUT_TRANSPOSE]
|
||||||
self.todrive = GM.Globals[GM.CSV_TODRIVE]
|
self.todrive = GM.Globals[GM.CSV_TODRIVE]
|
||||||
self.titlesSet = set()
|
self.titlesSet = set()
|
||||||
self.titlesList = []
|
self.titlesList = []
|
||||||
@@ -8992,6 +8991,22 @@ class CSVPrintFile():
|
|||||||
self.JSONtitlesList = self.orderHeaders(self.JSONtitlesList)
|
self.JSONtitlesList = self.orderHeaders(self.JSONtitlesList)
|
||||||
titlesList = self.JSONtitlesList
|
titlesList = self.JSONtitlesList
|
||||||
normalizeSortHeaders()
|
normalizeSortHeaders()
|
||||||
|
if self.outputTranspose:
|
||||||
|
newRows = []
|
||||||
|
pivotKey = titlesList[0]
|
||||||
|
newTitlesList = [pivotKey]
|
||||||
|
newTitlesSet = set(newTitlesList)
|
||||||
|
for title in titlesList[1:]:
|
||||||
|
newRow = {pivotKey: title}
|
||||||
|
for row in self.rows:
|
||||||
|
pivotValue = row[pivotKey]
|
||||||
|
if pivotValue not in newTitlesSet:
|
||||||
|
newTitlesSet.add(pivotValue)
|
||||||
|
newTitlesList.append(pivotValue)
|
||||||
|
newRow[pivotValue] = row.get(title)
|
||||||
|
newRows.append(newRow)
|
||||||
|
titlesList = newTitlesList
|
||||||
|
self.rows = newRows
|
||||||
if (not self.todrive) or self.todrive['localcopy']:
|
if (not self.todrive) or self.todrive['localcopy']:
|
||||||
if GM.Globals[GM.CSVFILE][GM.REDIRECT_NAME] == '-':
|
if GM.Globals[GM.CSVFILE][GM.REDIRECT_NAME] == '-':
|
||||||
if GM.Globals[GM.STDOUT][GM.REDIRECT_MULTI_FD]:
|
if GM.Globals[GM.STDOUT][GM.REDIRECT_MULTI_FD]:
|
||||||
@@ -14502,7 +14517,13 @@ def _initTagReplacements():
|
|||||||
'fieldsSet': set(), 'fields': '',
|
'fieldsSet': set(), 'fields': '',
|
||||||
'schemasSet': set(), 'customFieldMask': None}
|
'schemasSet': set(), 'customFieldMask': None}
|
||||||
|
|
||||||
def _getTagReplacement(tagReplacements, allowSubs):
|
def _getTagReplacement(myarg, tagReplacements, allowSubs):
|
||||||
|
if myarg == 'replace':
|
||||||
|
trregex = None
|
||||||
|
elif myarg == 'replaceregex':
|
||||||
|
trregex = (getREPattern(re.IGNORECASE), getString(Cmd.OB_STRING, minLen=0))
|
||||||
|
else:
|
||||||
|
return False
|
||||||
matchTag = getString(Cmd.OB_TAG)
|
matchTag = getString(Cmd.OB_TAG)
|
||||||
matchReplacement = getString(Cmd.OB_STRING, minLen=0)
|
matchReplacement = getString(Cmd.OB_STRING, minLen=0)
|
||||||
if matchReplacement.startswith('field:'):
|
if matchReplacement.startswith('field:'):
|
||||||
@@ -14547,7 +14568,8 @@ def _getTagReplacement(tagReplacements, allowSubs):
|
|||||||
tagReplacements['fieldsSet'].add(field)
|
tagReplacements['fieldsSet'].add(field)
|
||||||
tagReplacements['fields'] = ','.join(tagReplacements['fieldsSet'])
|
tagReplacements['fields'] = ','.join(tagReplacements['fieldsSet'])
|
||||||
tagReplacements['tags'][matchTag] = {'field': field, 'subfield': subfield,
|
tagReplacements['tags'][matchTag] = {'field': field, 'subfield': subfield,
|
||||||
'matchfield': matchfield, 'matchvalue': matchvalue, 'value': ''}
|
'matchfield': matchfield, 'matchvalue': matchvalue, 'value': '',
|
||||||
|
'trregex': trregex}
|
||||||
if field == 'locations' and subfield == 'buildingName':
|
if field == 'locations' and subfield == 'buildingName':
|
||||||
_makeBuildingIdNameMap()
|
_makeBuildingIdNameMap()
|
||||||
elif matchReplacement.startswith('schema:'):
|
elif matchReplacement.startswith('schema:'):
|
||||||
@@ -14565,15 +14587,24 @@ def _getTagReplacement(tagReplacements, allowSubs):
|
|||||||
tagReplacements['fields'] = ','.join(tagReplacements['fieldsSet'])
|
tagReplacements['fields'] = ','.join(tagReplacements['fieldsSet'])
|
||||||
tagReplacements['schemasSet'].add(schemaName)
|
tagReplacements['schemasSet'].add(schemaName)
|
||||||
tagReplacements['customFieldMask'] = ','.join(tagReplacements['schemasSet'])
|
tagReplacements['customFieldMask'] = ','.join(tagReplacements['schemasSet'])
|
||||||
tagReplacements['tags'][matchTag] = {'schema': schemaName, 'schemafield': schemaField, 'value': ''}
|
tagReplacements['tags'][matchTag] = {'schema': schemaName, 'schemafield': schemaField, 'value': '',
|
||||||
|
'trregex': trregex}
|
||||||
elif ((matchReplacement.find('#') >= 0) and
|
elif ((matchReplacement.find('#') >= 0) and
|
||||||
(matchReplacement.find('#user#') >= 0) or (matchReplacement.find('#email#') >= 0) or (matchReplacement.find('#username#') >= 0)):
|
(matchReplacement.find('#user#') >= 0) or (matchReplacement.find('#email#') >= 0) or (matchReplacement.find('#username#') >= 0)):
|
||||||
if not allowSubs:
|
if not allowSubs:
|
||||||
usageErrorExit(Msg.USER_SUBS_NOT_ALLOWED_TAG_REPLACEMENT)
|
usageErrorExit(Msg.USER_SUBS_NOT_ALLOWED_TAG_REPLACEMENT)
|
||||||
tagReplacements['subs'] = True
|
tagReplacements['subs'] = True
|
||||||
tagReplacements['tags'][matchTag] = {'template': matchReplacement, 'value': ''}
|
tagReplacements['tags'][matchTag] = {'template': matchReplacement, 'value': '',
|
||||||
|
'trregex': trregex}
|
||||||
else:
|
else:
|
||||||
tagReplacements['tags'][matchTag] = {'value': matchReplacement}
|
if trregex is None:
|
||||||
|
tagReplacements['tags'][matchTag] = {'value': matchReplacement}
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
tagReplacements['tags'][matchTag] = {'value': re.sub(trregex[0], trregex[1], matchReplacement)}
|
||||||
|
except re.error as e:
|
||||||
|
systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(trregex[1], str(e)))
|
||||||
|
return True
|
||||||
|
|
||||||
def _getTagReplacementFieldValues(user, i, count, tagReplacements, results=None):
|
def _getTagReplacementFieldValues(user, i, count, tagReplacements, results=None):
|
||||||
if results is None:
|
if results is None:
|
||||||
@@ -14655,6 +14686,12 @@ def _getTagReplacementFieldValues(user, i, count, tagReplacements, results=None)
|
|||||||
tag['value'] = str(results.get('customSchemas', {}).get(tag['schema'], {}).get(tag['schemafield'], ''))
|
tag['value'] = str(results.get('customSchemas', {}).get(tag['schema'], {}).get(tag['schemafield'], ''))
|
||||||
elif tag.get('template'):
|
elif tag.get('template'):
|
||||||
tag['value'] = _substituteForUser(tag['template'], user, userName)
|
tag['value'] = _substituteForUser(tag['template'], user, userName)
|
||||||
|
trregex = tag.get('trregex', None)
|
||||||
|
if trregex is not None:
|
||||||
|
try:
|
||||||
|
tag['value'] = re.sub(trregex[0], trregex[1], tag['value'])
|
||||||
|
except re.error as e:
|
||||||
|
systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(trregex[1], str(e)))
|
||||||
|
|
||||||
RTL_PATTERN = re.compile(r'(?s){RTL}.*?{/RTL}')
|
RTL_PATTERN = re.compile(r'(?s){RTL}.*?{/RTL}')
|
||||||
RT_PATTERN = re.compile(r'(?s){RT}.*?{/RT}')
|
RT_PATTERN = re.compile(r'(?s){RT}.*?{/RT}')
|
||||||
@@ -14907,7 +14944,9 @@ def getRecipients():
|
|||||||
# gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
# gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
||||||
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
# [subject <String>]
|
# [subject <String>]
|
||||||
# [<MessageContent>] (replace <Tag> <String>)*
|
# [<MessageContent>]
|
||||||
|
# (replace <Tag> <String>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <String>)*
|
||||||
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
||||||
# (embedimage <FileName> <String>)*
|
# (embedimage <FileName> <String>)*
|
||||||
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
@@ -14915,7 +14954,9 @@ def getRecipients():
|
|||||||
# gam <UserTypeEntity> sendemail recipient <RecipientEntity> [replyto <EmailAddress>]
|
# gam <UserTypeEntity> sendemail recipient <RecipientEntity> [replyto <EmailAddress>]
|
||||||
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
# [subject <String>]
|
# [subject <String>]
|
||||||
# [<MessageContent>] (replace <Tag> <String>)*
|
# [<MessageContent>]
|
||||||
|
# (replace <Tag> <String>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <String>)*
|
||||||
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
||||||
# (embedimage <FileName> <String>)*
|
# (embedimage <FileName> <String>)*
|
||||||
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
@@ -14923,7 +14964,9 @@ def getRecipients():
|
|||||||
# gam <UserTypeEntity> sendemail from <EmailAddress> [replyto <EmailAddress>]
|
# gam <UserTypeEntity> sendemail from <EmailAddress> [replyto <EmailAddress>]
|
||||||
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
# [subject <String>]
|
# [subject <String>]
|
||||||
# [<MessageContent>] (replace <Tag> <String>)*
|
# [<MessageContent>]
|
||||||
|
# (replace <Tag> <String>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <String>)*
|
||||||
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
||||||
# (embedimage <FileName> <String>)*
|
# (embedimage <FileName> <String>)*
|
||||||
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
@@ -14986,8 +15029,8 @@ def doSendEmail(users=None):
|
|||||||
body['name']['familyName'] = getString(Cmd.OB_STRING, minLen=0, maxLen=60)
|
body['name']['familyName'] = getString(Cmd.OB_STRING, minLen=0, maxLen=60)
|
||||||
elif myarg in {'password', 'notifypassword'}:
|
elif myarg in {'password', 'notifypassword'}:
|
||||||
body['password'] = notify['password'] = getString(Cmd.OB_PASSWORD, maxLen=100)
|
body['password'] = notify['password'] = getString(Cmd.OB_PASSWORD, maxLen=100)
|
||||||
elif myarg == 'replace':
|
elif _getTagReplacement(myarg, tagReplacements, False):
|
||||||
_getTagReplacement(tagReplacements, False)
|
pass
|
||||||
elif myarg == 'attach':
|
elif myarg == 'attach':
|
||||||
attachments.append((getFilename(), getCharSet()))
|
attachments.append((getFilename(), getCharSet()))
|
||||||
elif myarg == 'embedimage':
|
elif myarg == 'embedimage':
|
||||||
@@ -39066,7 +39109,10 @@ def _updateCalendarEvents(origUser, user, origCal, calIds, count, calendarEventE
|
|||||||
if 'description' in updateFieldList and 'description' in event:
|
if 'description' in updateFieldList and 'description' in event:
|
||||||
body['description'] = event['description']
|
body['description'] = event['description']
|
||||||
for replacement in parameters['replaceDescription']:
|
for replacement in parameters['replaceDescription']:
|
||||||
body['description'] = re.sub(replacement[0], replacement[1], body['description'])
|
try:
|
||||||
|
body['description'] = re.sub(replacement[0], replacement[1], body['description'])
|
||||||
|
except re.error as e:
|
||||||
|
systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(replacement[1], str(e)))
|
||||||
if 'attendees' in updateFieldList:
|
if 'attendees' in updateFieldList:
|
||||||
if not parameters['clearAttendees']:
|
if not parameters['clearAttendees']:
|
||||||
if 'attendees' in event:
|
if 'attendees' in event:
|
||||||
@@ -39390,7 +39436,10 @@ def _showCalendarEvent(primaryEmail, calId, eventEntityType, event, k, kcount, F
|
|||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
for field in EVENT_SHOW_ORDER:
|
for field in EVENT_SHOW_ORDER:
|
||||||
if field in event:
|
if field in event:
|
||||||
showJSON(field, event[field], skipObjects, EVENT_TIME_OBJECTS)
|
if field != 'description':
|
||||||
|
showJSON(field, event[field], skipObjects, EVENT_TIME_OBJECTS)
|
||||||
|
else:
|
||||||
|
printKeyValueWithCRsNLs(field, event[field])
|
||||||
skipObjects.add(field)
|
skipObjects.add(field)
|
||||||
showJSON(None, event, skipObjects)
|
showJSON(None, event, skipObjects)
|
||||||
Ind.Decrement()
|
Ind.Decrement()
|
||||||
@@ -42817,8 +42866,8 @@ def getUserAttributes(cd, updateCmd, noUid=False):
|
|||||||
notify['mailbox'] = getString(Cmd.OB_EMAIL_ADDRESS)
|
notify['mailbox'] = getString(Cmd.OB_EMAIL_ADDRESS)
|
||||||
elif PwdOpts.ProcessArgument(myarg, notify, notFoundBody):
|
elif PwdOpts.ProcessArgument(myarg, notify, notFoundBody):
|
||||||
pass
|
pass
|
||||||
elif myarg == 'replace':
|
elif _getTagReplacement(myarg, tagReplacements, True):
|
||||||
_getTagReplacement(tagReplacements, True)
|
pass
|
||||||
elif myarg == 'admin':
|
elif myarg == 'admin':
|
||||||
value = getBoolean()
|
value = getBoolean()
|
||||||
if updateCmd or value:
|
if updateCmd or value:
|
||||||
@@ -43235,9 +43284,9 @@ def createUserAddAliases(cd, user, aliasList, i, count):
|
|||||||
# [from <EmailAaddress>]
|
# [from <EmailAaddress>]
|
||||||
# [replyto <EmailAaddress>]
|
# [replyto <EmailAaddress>]
|
||||||
# [<NotifyMessageContent>]
|
# [<NotifyMessageContent>]
|
||||||
# (replace <Tag> <UserReplacement>)*]
|
# (replace <Tag> <UserReplacement>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
|
||||||
# [logpassword <FileName>] [ignorenullpassword]
|
# [logpassword <FileName>] [ignorenullpassword]
|
||||||
# [verifynotinvitable]
|
|
||||||
# [addnumericsuffixonduplicate <Number>]
|
# [addnumericsuffixonduplicate <Number>]
|
||||||
def doCreateUser():
|
def doCreateUser():
|
||||||
cd = buildGAPIObject(API.DIRECTORY)
|
cd = buildGAPIObject(API.DIRECTORY)
|
||||||
@@ -43336,8 +43385,9 @@ def verifyUserPrimaryEmail(cd, user, createIfNotFound, i, count):
|
|||||||
# [notifypassword <String>]
|
# [notifypassword <String>]
|
||||||
# [from <EmailAaddress>]
|
# [from <EmailAaddress>]
|
||||||
# [replyto <EmailAaddress>]
|
# [replyto <EmailAaddress>]
|
||||||
# [<NotifyMessageContent>]
|
# [<NotifyMessageContent>
|
||||||
# (replace <Tag> <UserReplacement>)*]
|
# (replace <Tag> <UserReplacement>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
|
||||||
# [notifyonupdate [<Boolean>]]
|
# [notifyonupdate [<Boolean>]]
|
||||||
# [logpassword <FileName>] [ignorenullpassword]
|
# [logpassword <FileName>] [ignorenullpassword]
|
||||||
def updateUsers(entityList):
|
def updateUsers(entityList):
|
||||||
@@ -57330,7 +57380,10 @@ def writeReturnIdLink(returnIdLink, mimeType, result):
|
|||||||
|
|
||||||
def processFilenameReplacements(name, replacements):
|
def processFilenameReplacements(name, replacements):
|
||||||
for replacement in replacements:
|
for replacement in replacements:
|
||||||
name = re.sub(replacement[0], replacement[1], name)
|
try:
|
||||||
|
name = re.sub(replacement[0], replacement[1], name)
|
||||||
|
except re.error as e:
|
||||||
|
systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(replacement[1], str(e)))
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def addTimestampToFilename(parameters, body):
|
def addTimestampToFilename(parameters, body):
|
||||||
@@ -57402,6 +57455,8 @@ def createDriveFile(users):
|
|||||||
if parameters[DFA_LOCALFILEPATH]:
|
if parameters[DFA_LOCALFILEPATH]:
|
||||||
if parameters[DFA_LOCALFILEPATH] != '-' and parameters[DFA_PRESERVE_FILE_TIMES]:
|
if parameters[DFA_LOCALFILEPATH] != '-' and parameters[DFA_PRESERVE_FILE_TIMES]:
|
||||||
setPreservedFileTimes(body, parameters, False)
|
setPreservedFileTimes(body, parameters, False)
|
||||||
|
if body.get('mimeType') == MIMETYPE_GA_SCRIPT_JSON:
|
||||||
|
parameters[DFA_LOCALMIMETYPE] = body['mimeType']
|
||||||
media_body = getMediaBody(parameters)
|
media_body = getMediaBody(parameters)
|
||||||
elif parameters[DFA_URL]:
|
elif parameters[DFA_URL]:
|
||||||
media_body = getMediaBody(parameters)
|
media_body = getMediaBody(parameters)
|
||||||
@@ -58723,7 +58778,7 @@ def _copyPermissions(drive, user, i, count, j, jcount,
|
|||||||
except (GAPI.notFound, GAPI.permissionNotFound,
|
except (GAPI.notFound, GAPI.permissionNotFound,
|
||||||
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
||||||
@@ -59754,7 +59809,7 @@ def _updateMoveFilePermissions(drive, user, i, count,
|
|||||||
except (GAPI.notFound, GAPI.permissionNotFound,
|
except (GAPI.notFound, GAPI.permissionNotFound,
|
||||||
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
||||||
@@ -60439,6 +60494,7 @@ GOOGLEDOC_VALID_EXTENSIONS_MAP = {
|
|||||||
MIMETYPE_GA_DOCUMENT: ['.docx', '.epub', '.html', '.odt', '.pdf', '.rtf', '.txt', '.zip'],
|
MIMETYPE_GA_DOCUMENT: ['.docx', '.epub', '.html', '.odt', '.pdf', '.rtf', '.txt', '.zip'],
|
||||||
MIMETYPE_GA_JAM: ['.pdf'],
|
MIMETYPE_GA_JAM: ['.pdf'],
|
||||||
MIMETYPE_GA_PRESENTATION: ['.pdf', '.pptx', '.odp', '.txt'],
|
MIMETYPE_GA_PRESENTATION: ['.pdf', '.pptx', '.odp', '.txt'],
|
||||||
|
MIMETYPE_GA_SCRIPT: ['.json'],
|
||||||
MIMETYPE_GA_SPREADSHEET: ['.csv', '.ods', '.pdf', '.tsv', '.xlsx', '.zip'],
|
MIMETYPE_GA_SPREADSHEET: ['.csv', '.ods', '.pdf', '.tsv', '.xlsx', '.zip'],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60474,6 +60530,7 @@ DOCUMENT_FORMATS_MAP = {
|
|||||||
'html': [{'mime': 'text/html', 'ext': '.html'}],
|
'html': [{'mime': 'text/html', 'ext': '.html'}],
|
||||||
'jpeg': [{'mime': 'image/jpeg', 'ext': '.jpeg'}],
|
'jpeg': [{'mime': 'image/jpeg', 'ext': '.jpeg'}],
|
||||||
'jpg': [{'mime': 'image/jpeg', 'ext': '.jpg'}],
|
'jpg': [{'mime': 'image/jpeg', 'ext': '.jpg'}],
|
||||||
|
'json': [{'mime': MIMETYPE_GA_SCRIPT_JSON, 'ext': '.json'}],
|
||||||
'mht': [{'mime': 'message/rfc822', 'ext': 'mht'}],
|
'mht': [{'mime': 'message/rfc822', 'ext': 'mht'}],
|
||||||
'odp': [{'mime': 'application/vnd.oasis.opendocument.presentation', 'ext': '.odp'}],
|
'odp': [{'mime': 'application/vnd.oasis.opendocument.presentation', 'ext': '.odp'}],
|
||||||
'ods': [{'mime': 'application/x-vnd.oasis.opendocument.spreadsheet', 'ext': '.ods'},
|
'ods': [{'mime': 'application/x-vnd.oasis.opendocument.spreadsheet', 'ext': '.ods'},
|
||||||
@@ -61455,7 +61512,7 @@ def transferDrive(users):
|
|||||||
if showRetentionMessages:
|
if showRetentionMessages:
|
||||||
entityActionPerformed([Ent.USER, sourceUser, childFileType, childFileName, Ent.ROLE, ownerRetainRoleBody['role']], j, jcount)
|
entityActionPerformed([Ent.USER, sourceUser, childFileType, childFileName, Ent.ROLE, ownerRetainRoleBody['role']], j, jcount)
|
||||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotRemoveOwner) as e:
|
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotRemoveOwner, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning([Ent.USER, sourceUser, childFileType, childFileName], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, sourceUser, childFileType, childFileName], str(e), j, jcount)
|
||||||
except GAPI.permissionNotFound:
|
except GAPI.permissionNotFound:
|
||||||
entityDoesNotHaveItemWarning([Ent.USER, sourceUser, childFileType, childFileName, Ent.PERMISSION_ID, sourcePermissionId], j, jcount)
|
entityDoesNotHaveItemWarning([Ent.USER, sourceUser, childFileType, childFileName, Ent.PERMISSION_ID, sourcePermissionId], j, jcount)
|
||||||
@@ -61508,7 +61565,7 @@ def transferDrive(users):
|
|||||||
if showRetentionMessages:
|
if showRetentionMessages:
|
||||||
entityActionPerformed([Ent.USER, sourceUser, childFileType, childFileName, Ent.ROLE, sourceUpdateRole['role']], j, jcount)
|
entityActionPerformed([Ent.USER, sourceUser, childFileType, childFileName, Ent.ROLE, sourceUpdateRole['role']], j, jcount)
|
||||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotRemoveOwner) as e:
|
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotRemoveOwner, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], str(e), j, jcount)
|
||||||
except GAPI.permissionNotFound:
|
except GAPI.permissionNotFound:
|
||||||
entityDoesNotHaveItemWarning([Ent.USER, ownerUser, childFileType, childFileName, Ent.PERMISSION_ID, sourcePermissionId], j, jcount)
|
entityDoesNotHaveItemWarning([Ent.USER, ownerUser, childFileType, childFileName, Ent.PERMISSION_ID, sourcePermissionId], j, jcount)
|
||||||
@@ -61532,7 +61589,7 @@ def transferDrive(users):
|
|||||||
if showRetentionMessages:
|
if showRetentionMessages:
|
||||||
entityActionPerformed([Ent.USER, targetUser, childFileType, childFileName, Ent.ROLE, targetInsertBody['role']], j, jcount)
|
entityActionPerformed([Ent.USER, targetUser, childFileType, childFileName, Ent.ROLE, targetInsertBody['role']], j, jcount)
|
||||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded) as e:
|
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], str(e), j, jcount)
|
||||||
except GAPI.invalidSharingRequest as e:
|
except GAPI.invalidSharingRequest as e:
|
||||||
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], Ent.TypeNameMessage(Ent.PERMISSION_ID, targetPermissionId, str(e)), j, jcount)
|
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], Ent.TypeNameMessage(Ent.PERMISSION_ID, targetPermissionId, str(e)), j, jcount)
|
||||||
@@ -62275,7 +62332,7 @@ def claimOwnership(users):
|
|||||||
entityActionPerformed([Ent.USER, oldOwner, entityType, fileDesc, Ent.ROLE, sourceRetainRoleBody['role']], l, lcount)
|
entityActionPerformed([Ent.USER, oldOwner, entityType, fileDesc, Ent.ROLE, sourceRetainRoleBody['role']], l, lcount)
|
||||||
except GAPI.permissionNotFound:
|
except GAPI.permissionNotFound:
|
||||||
entityDoesNotHaveItemWarning([Ent.USER, oldOwner, entityType, fileDesc, Ent.PERMISSION_ID, oldOwnerPermissionId], l, lcount)
|
entityDoesNotHaveItemWarning([Ent.USER, oldOwner, entityType, fileDesc, Ent.PERMISSION_ID, oldOwnerPermissionId], l, lcount)
|
||||||
except (GAPI.badRequest, GAPI.insufficientFilePermissions) as e:
|
except (GAPI.badRequest, GAPI.insufficientFilePermissions, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning([Ent.USER, oldOwner, entityType, fileDesc], str(e), l, lcount)
|
entityActionFailedWarning([Ent.USER, oldOwner, entityType, fileDesc], str(e), l, lcount)
|
||||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
||||||
@@ -63447,7 +63504,7 @@ def deleteDriveFileACLs(users, useDomainAdminAccess=False):
|
|||||||
_updateSheetProtectedRangesACLchange(sheet, user, i, count, j, jcount, fileId, fileName, False, permission)
|
_updateSheetProtectedRangesACLchange(sheet, user, i, count, j, jcount, fileId, fileName, False, permission)
|
||||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
|
||||||
except GAPI.notFound as e:
|
except GAPI.notFound as e:
|
||||||
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE, fileName], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE, fileName], str(e), j, jcount)
|
||||||
@@ -63503,7 +63560,7 @@ def deletePermissions(users, useDomainAdminAccess=False):
|
|||||||
entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.permissionNotFound,
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.permissionNotFound, GAPI.cannotDeletePermission,
|
||||||
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
entityActionFailedWarning([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
entityActionFailedWarning([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
if int(ri[RI_J]) == int(ri[RI_JCOUNT]):
|
if int(ri[RI_J]) == int(ri[RI_JCOUNT]):
|
||||||
@@ -69969,8 +70026,8 @@ def _draftImportInsertMessage(users, operation):
|
|||||||
internalDateSource = 'dateHeader'
|
internalDateSource = 'dateHeader'
|
||||||
if checkArgumentPresent('emlutf8'):
|
if checkArgumentPresent('emlutf8'):
|
||||||
emlEncoding = UTF8
|
emlEncoding = UTF8
|
||||||
elif myarg == 'replace':
|
elif _getTagReplacement(myarg, tagReplacements, True):
|
||||||
_getTagReplacement(tagReplacements, True)
|
pass
|
||||||
elif operation in IMPORT_INSERT and myarg == 'addlabel':
|
elif operation in IMPORT_INSERT and myarg == 'addlabel':
|
||||||
addLabelNames.append(getString(Cmd.OB_LABEL_NAME, minLen=1))
|
addLabelNames.append(getString(Cmd.OB_LABEL_NAME, minLen=1))
|
||||||
elif operation in IMPORT_INSERT and myarg == 'labels':
|
elif operation in IMPORT_INSERT and myarg == 'labels':
|
||||||
@@ -70105,7 +70162,9 @@ def _draftImportInsertMessage(users, operation):
|
|||||||
userGmailServiceNotEnabledWarning(user, i, count)
|
userGmailServiceNotEnabledWarning(user, i, count)
|
||||||
|
|
||||||
# gam <UserTypeEntity> draft message
|
# gam <UserTypeEntity> draft message
|
||||||
# <MessageContent> (replace <Tag> <UserReplacement>)*
|
# <MessageContent>
|
||||||
|
# (replace <Tag> <UserReplacement>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
# (attach <FileName> [charset <CharSet>])*
|
# (attach <FileName> [charset <CharSet>])*
|
||||||
# (embedimage <FileName> <String>)*
|
# (embedimage <FileName> <String>)*
|
||||||
@@ -70113,7 +70172,9 @@ def draftMessage(users):
|
|||||||
_draftImportInsertMessage(users, 'draft')
|
_draftImportInsertMessage(users, 'draft')
|
||||||
|
|
||||||
# gam <UserTypeEntity> import message
|
# gam <UserTypeEntity> import message
|
||||||
# <MessageContent> (replace <Tag> <UserReplacement>)*
|
# <MessageContent>
|
||||||
|
# (replace <Tag> <UserReplacement>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
# (addlabel <LabelName>)* [labels <LabelNameList>]
|
# (addlabel <LabelName>)* [labels <LabelNameList>]
|
||||||
# (attach <FileName> [charset <CharSet>])*
|
# (attach <FileName> [charset <CharSet>])*
|
||||||
@@ -70123,7 +70184,9 @@ def importMessage(users):
|
|||||||
_draftImportInsertMessage(users, 'import')
|
_draftImportInsertMessage(users, 'import')
|
||||||
|
|
||||||
# gam <UserTypeEntity> insert message
|
# gam <UserTypeEntity> insert message
|
||||||
# <MessageContent> (replace <Tag> <UserReplacement>)*
|
# <MessageContent>
|
||||||
|
# (replace <Tag> <UserReplacement>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
|
||||||
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
# (addlabel <LabelName>)* [labels <LabelNameList>]
|
# (addlabel <LabelName>)* [labels <LabelNameList>]
|
||||||
# (attach <FileName> [charset <CharSet>])*
|
# (attach <FileName> [charset <CharSet>])*
|
||||||
@@ -72410,8 +72473,8 @@ def _processSendAs(user, i, count, entityType, emailAddress, j, jcount, gmail, f
|
|||||||
return userDefined
|
return userDefined
|
||||||
|
|
||||||
def getSendAsAttributes(myarg, body, tagReplacements):
|
def getSendAsAttributes(myarg, body, tagReplacements):
|
||||||
if myarg == 'replace':
|
if _getTagReplacement(myarg, tagReplacements, True):
|
||||||
_getTagReplacement(tagReplacements, True)
|
pass
|
||||||
elif myarg == 'name':
|
elif myarg == 'name':
|
||||||
body['displayName'] = getString(Cmd.OB_NAME, minLen=0)
|
body['displayName'] = getString(Cmd.OB_NAME, minLen=0)
|
||||||
elif myarg == 'replyto':
|
elif myarg == 'replyto':
|
||||||
@@ -72430,13 +72493,17 @@ SMTPMSA_SECURITY_MODES = ['none', 'ssl', 'starttls']
|
|||||||
SMTPMSA_REQUIRED_FIELDS = ['host', 'port', 'username', 'password']
|
SMTPMSA_REQUIRED_FIELDS = ['host', 'port', 'username', 'password']
|
||||||
|
|
||||||
# gam <UserTypeEntity> [create] sendas <EmailAddress> [name] <String>
|
# gam <UserTypeEntity> [create] sendas <EmailAddress> [name] <String>
|
||||||
# [<SendAsContent> (replace <Tag> <UserReplacement>)*]
|
# [<SendAsContent>
|
||||||
|
# (replace <Tag> <UserReplacement>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
|
||||||
# [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
# [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
||||||
# [smtpmsa.host <SMTPHostName> smtpmsa.port 25|465|587
|
# [smtpmsa.host <SMTPHostName> smtpmsa.port 25|465|587
|
||||||
# smtpmsa.username <UserName> smtpmsa.password <Password>
|
# smtpmsa.username <UserName> smtpmsa.password <Password>
|
||||||
# [smtpmsa.securitymode none|ssl|starttls]]
|
# [smtpmsa.securitymode none|ssl|starttls]]
|
||||||
# gam <UserTypeEntity> update sendas <EmailAddress> [name <String>]
|
# gam <UserTypeEntity> update sendas <EmailAddress> [name <String>]
|
||||||
# [<SendAsContent> (replace <Tag> <UserReplacement>)*]
|
# [<SendAsContent>
|
||||||
|
# (replace <Tag> <UserReplacement>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
|
||||||
# [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
# [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
||||||
def createUpdateSendAs(users):
|
def createUpdateSendAs(users):
|
||||||
updateCmd = Act.Get() == Act.UPDATE
|
updateCmd = Act.Get() == Act.UPDATE
|
||||||
@@ -73273,6 +73340,7 @@ def printShowCSEKeyPairs(users):
|
|||||||
# gam <UserTypeEntity> signature|sig
|
# gam <UserTypeEntity> signature|sig
|
||||||
# <SignatureContent>
|
# <SignatureContent>
|
||||||
# (replace <Tag> <String>)*
|
# (replace <Tag> <String>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <String>)*
|
||||||
# [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
# [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
|
||||||
# [name <String>]
|
# [name <String>]
|
||||||
# [primary]
|
# [primary]
|
||||||
@@ -73366,7 +73434,9 @@ def _showVacation(user, i, count, result, showDisabled, sigReplyFormat):
|
|||||||
Ind.Decrement()
|
Ind.Decrement()
|
||||||
|
|
||||||
# gam <UserTypeEntity> vacation [<Boolean>] [subject <String>]
|
# gam <UserTypeEntity> vacation [<Boolean>] [subject <String>]
|
||||||
# [<VacationMessageContent> (replace <Tag> <UserReplacement>)*]
|
# [<VacationMessageContent>
|
||||||
|
# (replace <Tag> <UserReplacement>)*
|
||||||
|
# (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
|
||||||
# [html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
|
# [html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
|
||||||
# [start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
|
# [start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
|
||||||
def setVacation(users):
|
def setVacation(users):
|
||||||
@@ -73384,8 +73454,8 @@ def setVacation(users):
|
|||||||
message, _, html = getStringOrFile(myarg)
|
message, _, html = getStringOrFile(myarg)
|
||||||
if html:
|
if html:
|
||||||
responseBodyType = 'responseBodyHtml'
|
responseBodyType = 'responseBodyHtml'
|
||||||
elif myarg == 'replace':
|
elif _getTagReplacement(myarg, tagReplacements, True):
|
||||||
_getTagReplacement(tagReplacements, True)
|
pass
|
||||||
elif myarg == 'html':
|
elif myarg == 'html':
|
||||||
if getBoolean():
|
if getBoolean():
|
||||||
responseBodyType = 'responseBodyHtml'
|
responseBodyType = 'responseBodyHtml'
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class MockHttpClient(atom.http_interface.GenericHttpClient):
|
|||||||
for recording in self.recordings:
|
for recording in self.recordings:
|
||||||
if recording[0].operation == operation and recording[0].url == url:
|
if recording[0].operation == operation and recording[0].url == url:
|
||||||
return recording[1]
|
return recording[1]
|
||||||
raise NoRecordingFound('No recodings found for %s %s' % (
|
raise NoRecordingFound('No recordings found for %s %s' % (
|
||||||
operation, url))
|
operation, url))
|
||||||
else:
|
else:
|
||||||
# There is a real HTTP client, so make the request, and record the
|
# There is a real HTTP client, so make the request, and record the
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ CANNOT_CHANGE_OWNER_ACL = 'cannotChangeOwnerAcl'
|
|||||||
CANNOT_CHANGE_OWN_PRIMARY_SUBSCRIPTION = 'cannotChangeOwnPrimarySubscription'
|
CANNOT_CHANGE_OWN_PRIMARY_SUBSCRIPTION = 'cannotChangeOwnPrimarySubscription'
|
||||||
CANNOT_COPY_FILE = 'cannotCopyFile'
|
CANNOT_COPY_FILE = 'cannotCopyFile'
|
||||||
CANNOT_DELETE_ONLY_REVISION = 'cannotDeleteOnlyRevision'
|
CANNOT_DELETE_ONLY_REVISION = 'cannotDeleteOnlyRevision'
|
||||||
|
CANNOT_DELETE_PERMISSION = 'cannotDeletePermission'
|
||||||
CANNOT_DELETE_PRIMARY_CALENDAR = 'cannotDeletePrimaryCalendar'
|
CANNOT_DELETE_PRIMARY_CALENDAR = 'cannotDeletePrimaryCalendar'
|
||||||
CANNOT_DELETE_PRIMARY_SENDAS = 'cannotDeletePrimarySendAs'
|
CANNOT_DELETE_PRIMARY_SENDAS = 'cannotDeletePrimarySendAs'
|
||||||
CANNOT_DELETE_RESOURCE_WITH_CHILDREN = 'cannotDeleteResourceWithChildren'
|
CANNOT_DELETE_RESOURCE_WITH_CHILDREN = 'cannotDeleteResourceWithChildren'
|
||||||
@@ -246,7 +247,7 @@ DRIVE3_UPDATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID_OWNERSHIP_TRANSFER, CANN
|
|||||||
DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER,
|
DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER,
|
||||||
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION,
|
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION,
|
||||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
|
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
|
||||||
NOT_FOUND, PERMISSION_NOT_FOUND]
|
NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_DELETE_PERMISSION]
|
||||||
DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
||||||
FILE_NEVER_WRITABLE, APPLY_LABEL_FORBIDDEN,
|
FILE_NEVER_WRITABLE, APPLY_LABEL_FORBIDDEN,
|
||||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,
|
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,
|
||||||
@@ -382,6 +383,8 @@ class cannotCopyFile(Exception):
|
|||||||
pass
|
pass
|
||||||
class cannotDeleteOnlyRevision(Exception):
|
class cannotDeleteOnlyRevision(Exception):
|
||||||
pass
|
pass
|
||||||
|
class cannotDeletePermission(Exception):
|
||||||
|
pass
|
||||||
class cannotDeletePrimaryCalendar(Exception):
|
class cannotDeletePrimaryCalendar(Exception):
|
||||||
pass
|
pass
|
||||||
class cannotDeletePrimarySendAs(Exception):
|
class cannotDeletePrimarySendAs(Exception):
|
||||||
@@ -676,6 +679,7 @@ REASON_EXCEPTION_MAP = {
|
|||||||
CANNOT_CHANGE_OWN_PRIMARY_SUBSCRIPTION: cannotChangeOwnPrimarySubscription,
|
CANNOT_CHANGE_OWN_PRIMARY_SUBSCRIPTION: cannotChangeOwnPrimarySubscription,
|
||||||
CANNOT_COPY_FILE: cannotCopyFile,
|
CANNOT_COPY_FILE: cannotCopyFile,
|
||||||
CANNOT_DELETE_ONLY_REVISION: cannotDeleteOnlyRevision,
|
CANNOT_DELETE_ONLY_REVISION: cannotDeleteOnlyRevision,
|
||||||
|
CANNOT_DELETE_PERMISSION: cannotDeletePermission,
|
||||||
CANNOT_DELETE_PRIMARY_CALENDAR: cannotDeletePrimaryCalendar,
|
CANNOT_DELETE_PRIMARY_CALENDAR: cannotDeletePrimaryCalendar,
|
||||||
CANNOT_DELETE_PRIMARY_SENDAS: cannotDeletePrimarySendAs,
|
CANNOT_DELETE_PRIMARY_SENDAS: cannotDeletePrimarySendAs,
|
||||||
CANNOT_DELETE_RESOURCE_WITH_CHILDREN: cannotDeleteResourceWithChildren,
|
CANNOT_DELETE_RESOURCE_WITH_CHILDREN: cannotDeleteResourceWithChildren,
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ CSV_OUTPUT_ROW_FILTER_MODE = 'corm'
|
|||||||
CSV_OUTPUT_ROW_LIMIT = 'corl'
|
CSV_OUTPUT_ROW_LIMIT = 'corl'
|
||||||
# Add timestamp column to CSV output file
|
# Add timestamp column to CSV output file
|
||||||
CSV_OUTPUT_TIMESTAMP_COLUMN = 'cotc'
|
CSV_OUTPUT_TIMESTAMP_COLUMN = 'cotc'
|
||||||
|
# Transpose output rows/columns
|
||||||
|
CSV_OUTPUT_TRANSPOSE = 'cotr'
|
||||||
# Output sort headers
|
# Output sort headers
|
||||||
CSV_OUTPUT_SORT_HEADERS = 'cosh'
|
CSV_OUTPUT_SORT_HEADERS = 'cosh'
|
||||||
# CSV todrive options
|
# CSV todrive options
|
||||||
@@ -250,6 +252,7 @@ Globals = {
|
|||||||
CSV_OUTPUT_ROW_LIMIT: 0,
|
CSV_OUTPUT_ROW_LIMIT: 0,
|
||||||
CSV_OUTPUT_SORT_HEADERS: [],
|
CSV_OUTPUT_SORT_HEADERS: [],
|
||||||
CSV_OUTPUT_TIMESTAMP_COLUMN: None,
|
CSV_OUTPUT_TIMESTAMP_COLUMN: None,
|
||||||
|
CSV_OUTPUT_TRANSPOSE: False,
|
||||||
CSV_TODRIVE: {},
|
CSV_TODRIVE: {},
|
||||||
CURRENT_API_SERVICES: {},
|
CURRENT_API_SERVICES: {},
|
||||||
CURRENT_CLIENT_API: None,
|
CURRENT_CLIENT_API: None,
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ Your workspace is configured to disable service account private key uploads.
|
|||||||
|
|
||||||
Please go to:
|
Please go to:
|
||||||
|
|
||||||
https://github.com/taers232c/GAMADV-XTD3/wiki/Authorization#authorize-service-account-key-uploads
|
https://github.com/GAM-team/GAM/wiki/Authorization#authorize-service-account-key-uploads
|
||||||
|
|
||||||
Follow the steps to allow a service account private key upload for the project ({0}) just created.
|
Follow the steps to allow a service account private key upload for the project ({0}) just created.
|
||||||
Once those steps are completed, you can continue with your project authentication.
|
Once those steps are completed, you can continue with your project authentication.
|
||||||
@@ -322,7 +322,7 @@ INVALID_NUMBER_OF_CHAT_SPACE_MEMBERS = '{0} type {1} number of members, {2}, mus
|
|||||||
INVALID_ORGUNIT = 'Invalid Organizational Unit'
|
INVALID_ORGUNIT = 'Invalid Organizational Unit'
|
||||||
INVALID_PATH = 'Invalid Path'
|
INVALID_PATH = 'Invalid Path'
|
||||||
INVALID_PERMISSION_ATTRIBUTE_TYPE = 'permission attribute {0} not allowed with type {1}'
|
INVALID_PERMISSION_ATTRIBUTE_TYPE = 'permission attribute {0} not allowed with type {1}'
|
||||||
INVALID_REGION = 'See: https://github.com/taers232c/GAMADV-XTD3/wiki/Context-Aware-Access-Levels#caa-region-codes'
|
INVALID_REGION = 'See: https://github.com/GAM-team/GAM/wiki/Context-Aware-Access-Levels#caa-region-codes'
|
||||||
INVALID_QUERY = 'Invalid Query'
|
INVALID_QUERY = 'Invalid Query'
|
||||||
INVALID_RE = 'Invalid RE'
|
INVALID_RE = 'Invalid RE'
|
||||||
INVALID_REQUEST = 'Invalid Request'
|
INVALID_REQUEST = 'Invalid Request'
|
||||||
@@ -465,6 +465,7 @@ REASON_ONLY_VALID_WITH_CONTENTRESTRICTIONS_READONLY_TRUE = 'reason only valid wi
|
|||||||
REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create'
|
REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create'
|
||||||
RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n'
|
RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n'
|
||||||
REFUSING_TO_DEPROVISION_DEVICES = 'Refusing to deprovision {0} devices because acknowledge_device_touch_requirement not specified.\nDeprovisioning a device means the device will have to be physically wiped and re-enrolled to be managed by your domain again.\nThis requires physical access to the device and is very time consuming to perform for each device.\nPlease add "acknowledge_device_touch_requirement" to the GAM command if you understand this and wish to proceed with the deprovision.\nPlease also be aware that deprovisioning can have an effect on your device license count.\nSee https://support.google.com/chrome/a/answer/3523633 for full details.'
|
REFUSING_TO_DEPROVISION_DEVICES = 'Refusing to deprovision {0} devices because acknowledge_device_touch_requirement not specified.\nDeprovisioning a device means the device will have to be physically wiped and re-enrolled to be managed by your domain again.\nThis requires physical access to the device and is very time consuming to perform for each device.\nPlease add "acknowledge_device_touch_requirement" to the GAM command if you understand this and wish to proceed with the deprovision.\nPlease also be aware that deprovisioning can have an effect on your device license count.\nSee https://support.google.com/chrome/a/answer/3523633 for full details.'
|
||||||
|
REGEX_REPLACEMENT_ERROR = 'Regular expression replacement string "{0}" error: {1}'
|
||||||
REPLY_TO_CUSTOM_REQUIRES_EMAIL_ADDRESS = 'replyto REPLY_TO_CUSTOM requires customReplyTo <EmailAddress>'
|
REPLY_TO_CUSTOM_REQUIRES_EMAIL_ADDRESS = 'replyto REPLY_TO_CUSTOM requires customReplyTo <EmailAddress>'
|
||||||
REQUEST_COMPLETED_NO_FILES = 'Request completed but no results/files were returned, try requesting again'
|
REQUEST_COMPLETED_NO_FILES = 'Request completed but no results/files were returned, try requesting again'
|
||||||
REQUEST_NOT_COMPLETE = 'Request needs to be completed before downloading, current status is: {0}'
|
REQUEST_NOT_COMPLETE = 'Request needs to be completed before downloading, current status is: {0}'
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
# Products/SKUs
|
# Products/SKUs
|
||||||
_PRODUCTS = {
|
_PRODUCTS = {
|
||||||
'101001': 'Cloud Identity Free',
|
'101001': 'Cloud Identity',
|
||||||
'101005': 'Cloud Identity Premium',
|
'101005': 'Cloud Identity Premium',
|
||||||
'101031': 'Google Workspace for Education',
|
'101031': 'Google Workspace for Education',
|
||||||
'101033': 'Google Voice',
|
'101033': 'Google Voice',
|
||||||
@@ -87,6 +87,8 @@ _SKUS = {
|
|||||||
'product': '101038', 'aliases': ['appsheetplus', 'appsheetenterpriseplus'], 'displayName': 'AppSheet Enterprise Plus'},
|
'product': '101038', 'aliases': ['appsheetplus', 'appsheetenterpriseplus'], 'displayName': 'AppSheet Enterprise Plus'},
|
||||||
'1010390001': {
|
'1010390001': {
|
||||||
'product': '101039', 'aliases': ['assuredcontrols'], 'displayName': 'Assured Controls'},
|
'product': '101039', 'aliases': ['assuredcontrols'], 'displayName': 'Assured Controls'},
|
||||||
|
'1010390002': {
|
||||||
|
'product': '101039', 'aliases': ['assuredcontrolsplus'], 'displayName': 'Assured Controls Plus'},
|
||||||
'1010400001': {
|
'1010400001': {
|
||||||
'product': '101040', 'aliases': ['beyondcorp', 'beyondcorpenterprise', 'bce', 'cep', 'chromeenterprisepremium'], 'displayName': 'Chrome Enterprise Premium'},
|
'product': '101040', 'aliases': ['beyondcorp', 'beyondcorpenterprise', 'bce', 'cep', 'chromeenterprisepremium'], 'displayName': 'Chrome Enterprise Premium'},
|
||||||
'1010430001': {
|
'1010430001': {
|
||||||
@@ -127,7 +129,7 @@ _SKUS = {
|
|||||||
'product': 'Google-Apps', 'aliases': ['gau', 'gsb', 'unlimited', 'gsuitebusiness'], 'displayName': 'G Suite Business'},
|
'product': 'Google-Apps', 'aliases': ['gau', 'gsb', 'unlimited', 'gsuitebusiness'], 'displayName': 'G Suite Business'},
|
||||||
'1010020020': {
|
'1010020020': {
|
||||||
'product': 'Google-Apps', 'aliases': ['gae', 'gse', 'enterprise', 'gsuiteenterprise',
|
'product': 'Google-Apps', 'aliases': ['gae', 'gse', 'enterprise', 'gsuiteenterprise',
|
||||||
'wsentplus', 'workspaceenterpriseplus'], 'displayName': 'Google Workspace Enterprise Plus'},
|
'wsentplus', 'workspaceenterpriseplus'], 'displayName': 'Google Workspace Enterprise Plus (formerly G Suite Enterprise)'},
|
||||||
'1010020025': {
|
'1010020025': {
|
||||||
'product': 'Google-Apps', 'aliases': ['wsbizplus', 'workspacebusinessplus'], 'displayName': 'Google Workspace Business Plus'},
|
'product': 'Google-Apps', 'aliases': ['wsbizplus', 'workspacebusinessplus'], 'displayName': 'Google Workspace Business Plus'},
|
||||||
'1010020026': {
|
'1010020026': {
|
||||||
@@ -159,11 +161,11 @@ _SKUS = {
|
|||||||
'1010060001': {
|
'1010060001': {
|
||||||
'product': '101006', 'aliases': ['gsuiteessentials', 'essentials',
|
'product': '101006', 'aliases': ['gsuiteessentials', 'essentials',
|
||||||
'd4e', 'driveenterprise', 'drive4enterprise',
|
'd4e', 'driveenterprise', 'drive4enterprise',
|
||||||
'wsess', 'workspaceesentials'], 'displayName': 'Google Workspace Essentials'},
|
'wsess', 'workspaceesentials'], 'displayName': 'Google Workspace Essentials (formerly G Suite Essentials)'},
|
||||||
'1010060003': {
|
'1010060003': {
|
||||||
'product': 'Google-Apps', 'aliases': ['wsentess', 'workspaceenterpriseessentials'], 'displayName': 'Google Workspace Enterprise Essentials'},
|
'product': 'Google-Apps', 'aliases': ['wsentess', 'workspaceenterpriseessentials'], 'displayName': 'Google Workspace Enterprise Essentials'},
|
||||||
'1010060005': {
|
'1010060005': {
|
||||||
'product': 'Google-Apps', 'aliases': ['wsessplus', 'workspaceessentialsplus'], 'displayName': 'Google Workspace Essentials Plus'},
|
'product': 'Google-Apps', 'aliases': ['wsessplus', 'workspaceessentialsplus'], 'displayName': 'Google Workspace Enterprise Essentials Plus'},
|
||||||
'Google-Drive-storage-20GB': {
|
'Google-Drive-storage-20GB': {
|
||||||
'product': 'Google-Drive-storage', 'aliases': ['drive20gb', '20gb', 'googledrivestorage20gb'], 'displayName': 'Google Drive Storage 20GB'},
|
'product': 'Google-Drive-storage', 'aliases': ['drive20gb', '20gb', 'googledrivestorage20gb'], 'displayName': 'Google Drive Storage 20GB'},
|
||||||
'Google-Drive-storage-50GB': {
|
'Google-Drive-storage-50GB': {
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
accesscontextmanager.googleapis.com
|
|
||||||
admin.googleapis.com
|
|
||||||
alertcenter.googleapis.com
|
|
||||||
calendar-json.googleapis.com
|
|
||||||
chat.googleapis.com
|
|
||||||
chromemanagement.googleapis.com
|
|
||||||
chromepolicy.googleapis.com
|
|
||||||
classroom.googleapis.com
|
|
||||||
cloudidentity.googleapis.com
|
|
||||||
cloudresourcemanager.googleapis.com
|
|
||||||
contacts.googleapis.com
|
|
||||||
drive.googleapis.com
|
|
||||||
driveactivity.googleapis.com
|
|
||||||
iap.googleapis.com
|
|
||||||
gmail.googleapis.com
|
|
||||||
groupssettings.googleapis.com
|
|
||||||
iam.googleapis.com
|
|
||||||
licensing.googleapis.com
|
|
||||||
reseller.googleapis.com
|
|
||||||
sheets.googleapis.com
|
|
||||||
siteverification.googleapis.com
|
|
||||||
storage-api.googleapis.com
|
|
||||||
vault.googleapis.com
|
|
||||||
Reference in New Issue
Block a user