111 lines
2.6 KiB
Go
111 lines
2.6 KiB
Go
package router
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/coreos/go-oidc"
|
|
"github.com/gin-gonic/gin"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
var (
|
|
// clientID = os.Getenv("GOOGLE_OAUTH2_CLIENT_ID")
|
|
// clientSecret = os.Getenv("GOOGLE_OAUTH2_CLIENT_SECRET")
|
|
clientID = "godopu-dev"
|
|
clientSecret = "mydwxdd-c2hbo6zcmab1mzj232zx4"
|
|
)
|
|
var config oauth2.Config
|
|
var provider *oidc.Provider
|
|
|
|
func init() {
|
|
var err error
|
|
provider, err = oidc.NewProvider(context.Background(), "https://auth.godopu.com")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
config = oauth2.Config{
|
|
ClientID: clientID,
|
|
ClientSecret: clientSecret,
|
|
Endpoint: provider.Endpoint(),
|
|
RedirectURL: "http://localhost:4000/auth/oidc.callback",
|
|
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
|
|
}
|
|
}
|
|
|
|
func randString(nByte int) (string, error) {
|
|
b := make([]byte, nByte)
|
|
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
|
return "", err
|
|
}
|
|
return base64.RawURLEncoding.EncodeToString(b), nil
|
|
}
|
|
|
|
func setCallbackCookie(ctx *gin.Context, name, value string) {
|
|
// ctx.SetCookie(name, value, int(time.Hour.Seconds()), "", "", ctx.Request.TLS != nil, true)
|
|
c := &http.Cookie{
|
|
Name: name,
|
|
Value: value,
|
|
MaxAge: int(time.Hour.Seconds()),
|
|
Secure: ctx.Request.TLS != nil,
|
|
HttpOnly: true,
|
|
}
|
|
|
|
http.SetCookie(ctx.Writer, c)
|
|
}
|
|
|
|
func authStart(ctx *gin.Context) {
|
|
state, err := randString(16)
|
|
if err != nil {
|
|
http.Error(ctx.Writer, "Internal error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
setCallbackCookie(ctx, "state", state)
|
|
rurl := config.AuthCodeURL(state)
|
|
ctx.Redirect(http.StatusPermanentRedirect, rurl)
|
|
}
|
|
|
|
func authCallback(ctx *gin.Context) {
|
|
state, err := ctx.Cookie("state")
|
|
if err != nil {
|
|
http.Error(ctx.Writer, "state not found", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if ctx.Query("state") != state {
|
|
http.Error(ctx.Writer, "state did not match", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
oauth2Token, err := config.Exchange(ctx, ctx.Query("code"))
|
|
if err != nil {
|
|
http.Error(ctx.Writer, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
userInfo, err := provider.UserInfo(ctx, oauth2.StaticTokenSource(oauth2Token))
|
|
if err != nil {
|
|
http.Error(ctx.Writer, "Failed to get userinfo: "+err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
_ = userInfo
|
|
|
|
c := &http.Cookie{
|
|
Name: "__edit_access_token_",
|
|
Value: "value",
|
|
MaxAge: int(time.Hour.Seconds()),
|
|
Secure: ctx.Request.TLS != nil,
|
|
HttpOnly: true,
|
|
Path: "/",
|
|
}
|
|
|
|
ctx.Set("__edit_access_token_", "^^")
|
|
http.SetCookie(ctx.Writer, c)
|
|
ctx.Redirect(http.StatusFound, "/edit")
|
|
}
|