Skip to content

Commit 6c3be33

Browse files
Merge branch 'google:master' into junit-5-tests-for-oauth
2 parents 9ec84bb + 81ced79 commit 6c3be33

File tree

7 files changed

+99
-124
lines changed

7 files changed

+99
-124
lines changed

go/sendgmail/README.md

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ send-email`.
2525
`https://oauth2.dance/` as an authorised redirect URI. This is necessary
2626
for seeing the authorisation code on a page in your browser.
2727

28-
* When you download the credentials as JSON, save the file to your home
29-
directory as `.sendgmail.json` with file mode `0600`.
28+
* When you download the credentials as JSON, create the
29+
`${XDG_CONFIG_HOME:-${HOME}/.config}/sendgmail` directory with file mode
30+
`0700` and then save the file to that directory as `config.json` with
31+
file mode `0600`.
3032

31-
If complying with the XDG Base Directory Specification, instead create
32-
the `${XDG_CONFIG_HOME:-${HOME}/.config}/sendgmail` directory with file
33-
mode `0700` and then save the file to that directory as `config.json`
34-
with file mode `0600`.
33+
For historical reasons, when the file named `config.json` does not exist
34+
under your config directory, sendgmail will try looking for a file named
35+
`.sendgmail.json` in your home directory.
3536

3637
3. Go back to **APIs & Services > OAuth consent screen** in the Google Cloud
3738
console.
@@ -51,12 +52,6 @@ Run the following command to build and install sendgmail to
5152
go install github.com/google/gmail-oauth2-tools/go/sendgmail@latest
5253
```
5354

54-
If complying with the XDG Base Directory Specification, instead run:
55-
56-
```shell
57-
go install -tags xdg github.com/google/gmail-oauth2-tools/go/sendgmail@latest
58-
```
59-
6055
## Obtaining OAuth2 credentials for yourself
6156

6257
Run the following command to perform the OAuth2 dance:

go/sendgmail/go.mod

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ module github.com/google/gmail-oauth2-tools/go/sendgmail
33
go 1.20
44

55
require (
6-
github.com/google/uuid v1.3.0
7-
golang.org/x/oauth2 v0.5.0
6+
github.com/google/uuid v1.4.0
7+
golang.org/x/oauth2 v0.14.0
88
)
99

1010
require (
11-
cloud.google.com/go/compute v1.18.0 // indirect
11+
cloud.google.com/go/compute v1.23.3 // indirect
1212
cloud.google.com/go/compute/metadata v0.2.3 // indirect
13-
github.com/golang/protobuf v1.5.2 // indirect
14-
golang.org/x/net v0.7.0 // indirect
15-
google.golang.org/appengine v1.6.7 // indirect
16-
google.golang.org/protobuf v1.28.1 // indirect
13+
github.com/golang/protobuf v1.5.3 // indirect
14+
google.golang.org/appengine v1.6.8 // indirect
15+
google.golang.org/protobuf v1.33.0 // indirect
1716
)

go/sendgmail/go.sum

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,45 @@
1-
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
2-
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
1+
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
2+
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
33
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
44
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
5-
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
65
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
7-
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
86
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
7+
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
8+
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
99
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
10-
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
11-
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
12-
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
10+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
11+
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
12+
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
13+
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
1314
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
14-
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
15-
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
16-
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
17-
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
18-
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
15+
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
16+
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
17+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
18+
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
19+
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
20+
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
21+
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
22+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
23+
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
1924
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
25+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
26+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
27+
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
28+
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
29+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
30+
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
2031
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
21-
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
32+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
33+
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
34+
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
2235
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
36+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
37+
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
38+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
2339
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
24-
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
25-
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
40+
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
41+
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
2642
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
2743
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
28-
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
29-
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
44+
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
45+
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=

go/sendgmail/main.go

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ import (
2828
"encoding/json"
2929
"flag"
3030
"fmt"
31-
"io/ioutil"
31+
"io"
3232
"log"
3333
"net/smtp"
3434
"os"
35+
"path/filepath"
3536
"strings"
37+
"sync"
3638

3739
"github.com/google/uuid"
3840
"golang.org/x/oauth2"
@@ -73,7 +75,7 @@ func main() {
7375
}
7476

7577
func configJSON() []byte {
76-
configJSON, err := ioutil.ReadFile(configPath())
78+
configJSON, err := os.ReadFile(configPath())
7779
if err != nil {
7880
log.Fatalf("Failed to read config: %v.", err)
7981
}
@@ -139,7 +141,7 @@ func sendMessage(config *oauth2.Config) {
139141
log.Fatalf("Failed to read token: %v.", err)
140142
}
141143
tokenSource := config.TokenSource(context.Background(), &token)
142-
message, err := ioutil.ReadAll(os.Stdin)
144+
message, err := io.ReadAll(os.Stdin)
143145
if err != nil {
144146
log.Fatalf("Failed to read message: %v.", err)
145147
}
@@ -174,3 +176,47 @@ func (a *auth) Next(fromServer []byte, more bool) ([]byte, error) {
174176
}
175177
return nil, nil
176178
}
179+
180+
func userConfigDir() string {
181+
if dir := os.Getenv("XDG_CONFIG_HOME"); dir != "" {
182+
return dir
183+
}
184+
if dir := os.Getenv("HOME"); dir != "" {
185+
return filepath.Join(dir, ".config")
186+
}
187+
panic("Neither $XDG_CONFIG_HOME nor $HOME is defined.")
188+
}
189+
190+
func userHomeDir() string {
191+
dir, err := os.UserHomeDir()
192+
if err != nil {
193+
log.Fatalf("Failed to get user home directory: %v.", err)
194+
}
195+
return dir
196+
}
197+
198+
var isXDG = sync.OnceValue(func() bool {
199+
if _, err := os.Stat(filepath.Join(userConfigDir(), "sendgmail", "config.json")); err == nil {
200+
return true
201+
}
202+
if _, err := os.Stat(filepath.Join(userHomeDir(), ".sendgmail.json")); err == nil {
203+
return false
204+
}
205+
return true
206+
})
207+
208+
func configPath() string {
209+
if isXDG() {
210+
return filepath.Join(userConfigDir(), "sendgmail", "config.json")
211+
} else {
212+
return filepath.Join(userHomeDir(), ".sendgmail.json")
213+
}
214+
}
215+
216+
func tokenPath() string {
217+
if isXDG() {
218+
return filepath.Join(userConfigDir(), "sendgmail", "token."+sender+".json")
219+
} else {
220+
return filepath.Join(userHomeDir(), ".sendgmail."+sender+".json")
221+
}
222+
}

go/sendgmail/paths.go

Lines changed: 0 additions & 39 deletions
This file was deleted.

go/sendgmail/paths_xdg.go

Lines changed: 0 additions & 40 deletions
This file was deleted.

python/oauth2.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,12 @@ def GenerateOAuth2String(username, access_token, base64_encode=True):
267267
return auth_string
268268

269269

270-
def TestImapAuthentication(user, auth_string):
270+
def TestImapAuthentication(auth_string):
271271
"""Authenticates to IMAP with the given auth_string.
272272
273273
Prints a debug trace of the attempted IMAP connection.
274274
275275
Args:
276-
user: The Gmail username (full email address)
277276
auth_string: A valid OAuth2 string, as returned by GenerateOAuth2String.
278277
Must not be base64-encoded, since imaplib does its own base64-encoding.
279278
"""
@@ -284,11 +283,10 @@ def TestImapAuthentication(user, auth_string):
284283
imap_conn.select('INBOX')
285284

286285

287-
def TestSmtpAuthentication(user, auth_string):
286+
def TestSmtpAuthentication(auth_string):
288287
"""Authenticates to SMTP with the given auth_string.
289288
290289
Args:
291-
user: The Gmail username (full email address)
292290
auth_string: A valid OAuth2 string, not base64-encoded, as returned by
293291
GenerateOAuth2String.
294292
"""
@@ -337,12 +335,12 @@ def main(argv):
337335
print('Access Token Expiration Seconds: %s' % response['expires_in'])
338336
elif options.test_imap_authentication:
339337
RequireOptions(options, 'user', 'access_token')
340-
TestImapAuthentication(options.user,
338+
TestImapAuthentication(
341339
GenerateOAuth2String(options.user, options.access_token,
342340
base64_encode=False))
343341
elif options.test_smtp_authentication:
344342
RequireOptions(options, 'user', 'access_token')
345-
TestSmtpAuthentication(options.user,
343+
TestSmtpAuthentication(
346344
GenerateOAuth2String(options.user, options.access_token,
347345
base64_encode=False))
348346
else:

0 commit comments

Comments
 (0)