Skip to content

Commit d905524

Browse files
committed
Preliminary OAuth flow
1 parent e2767b4 commit d905524

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
bin/gh
22
/gh-cli
3+
.envrc

auth/oauth.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io/ioutil"
7+
"net/http"
8+
"net/url"
9+
"os"
10+
"os/exec"
11+
"time"
12+
)
13+
14+
func main() {
15+
port := 3999 // TODO: find available port number
16+
state := "TODO" // replace with random unguessable value
17+
18+
clientID := os.Getenv("GH_OAUTH_CLIENT_ID")
19+
clientSecret := os.Getenv("GH_OAUTH_CLIENT_SECRET")
20+
21+
q := url.Values{}
22+
q.Set("client_id", clientID)
23+
q.Set("redirect_uri", fmt.Sprintf("http://localhost:%d", port))
24+
q.Set("scope", "repo")
25+
q.Set("state", state)
26+
27+
cmd := exec.Command("open", fmt.Sprintf("https://github.com/login/oauth/authorize?%s", q.Encode()))
28+
err := cmd.Run()
29+
if err != nil {
30+
panic(err)
31+
}
32+
33+
code := ""
34+
srv := &http.Server{Addr: fmt.Sprintf(":%d", port)}
35+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
36+
rq := r.URL.Query()
37+
code = rq.Get("code")
38+
// TODO: rq.Get("state")
39+
w.Header().Add("content-type", "text/html")
40+
fmt.Fprintf(w, "<p>You have authenticated <strong>GitHub CLI</strong>. You may now close this page.</p>")
41+
time.AfterFunc(10*time.Millisecond, func() {
42+
srv.Shutdown(context.TODO())
43+
})
44+
})
45+
srv.ListenAndServe()
46+
47+
resp, err := http.PostForm("https://github.com/login/oauth/access_token",
48+
url.Values{
49+
"client_id": {clientID},
50+
"client_secret": {clientSecret},
51+
"code": {code},
52+
"state": {state},
53+
})
54+
if err != nil {
55+
panic(err)
56+
}
57+
58+
defer resp.Body.Close()
59+
body, err := ioutil.ReadAll(resp.Body)
60+
if err != nil {
61+
panic(err)
62+
}
63+
tokenValues, err := url.ParseQuery(string(body))
64+
if err != nil {
65+
panic(err)
66+
}
67+
fmt.Printf("OAuth access token: %s\n", tokenValues.Get("access_token"))
68+
}

0 commit comments

Comments
 (0)