-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathoauth.go
84 lines (72 loc) · 2.2 KB
/
oauth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package oauth
import (
"context"
"crypto/rand"
"net/http"
"encoding/base64"
"fmt"
"github.com/captncraig/caddy-oauth/providers"
"golang.org/x/oauth2"
)
func (o *oathPlugin) stripHeaders(r *http.Request) {
for _, p := range o.providers {
for _, h := range p.HeadersUsed() {
r.Header.Del(h)
}
}
}
func (o *oathPlugin) loginPage(w http.ResponseWriter, r *http.Request) (int, error) {
return 0, nil
}
func (o *oathPlugin) logout(w http.ResponseWriter, r *http.Request) (int, error) {
for _, p := range o.providerConfigs {
o.cookies.ClearCookie(w, p.CookieName)
}
//TODO: customizable?
http.Redirect(w, r, "/", http.StatusFound)
return http.StatusFound, nil
}
func (o *oathPlugin) start(w http.ResponseWriter, r *http.Request, p providers.Provider) (int, error) {
dat := make([]byte, 9)
rand.Read(dat)
state := base64.StdEncoding.EncodeToString(dat)
o.cookies.SetCookie(w, "oauth-state", 120, state)
url := p.OauthConfig().AuthCodeURL(state)
http.Redirect(w, r, url, http.StatusFound)
return http.StatusFound, nil
}
func (o *oathPlugin) callback(w http.ResponseWriter, r *http.Request, p providers.Provider, cfg *providers.ProviderConfig) (int, error) {
fail := func(e error) (int, error) {
fmt.Println("FIAIL", e)
return 200, nil
}
var err error
code, state := r.URL.Query().Get("code"), r.URL.Query().Get("state")
var foundState string
if err = o.cookies.ReadCookie(r, "oauth-state", 120, &foundState); err != nil {
return fail(err)
}
o.cookies.ClearCookie(w, "oauth-state")
if foundState != state {
return fail(fmt.Errorf("state does not match"))
}
var tok *oauth2.Token
if tok, err = p.OauthConfig().Exchange(context.Background(), code); err != nil {
return fail(err)
}
headers, err := p.GetUserData(tok)
if err != nil {
return fail(err)
}
if err = o.cookies.SetCookie(w, cfg.CookieName, cookieDuration, headers); err != nil {
return fail(err)
}
return o.successRedirect(w, r)
}
var cookieDuration = 60 * 60 * 24 * 30
func (o *oathPlugin) successRedirect(w http.ResponseWriter, r *http.Request) (int, error) {
//TODO: read cookie and redirect to that url.
// Otherwise / (or maybe a configurable path)
http.Redirect(w, r, "/", http.StatusFound)
return http.StatusFound, nil
}