mirror of
https://github.com/vx3r/wg-gen-web.git
synced 2024-11-09 18:21:22 +00:00
implement github oauth, set demo to github auth
This commit is contained in:
parent
dd99358f8f
commit
6fcd70bf80
4
.env
4
.env
@ -32,10 +32,10 @@ OAUTH2_REDIRECT_URL=
|
|||||||
|
|
||||||
# example with github
|
# example with github
|
||||||
OAUTH2_PROVIDER_NAME=github
|
OAUTH2_PROVIDER_NAME=github
|
||||||
OAUTH2_PROVIDER=
|
OAUTH2_PROVIDER=https://github.com
|
||||||
OAUTH2_CLIENT_ID=
|
OAUTH2_CLIENT_ID=
|
||||||
OAUTH2_CLIENT_SECRET=
|
OAUTH2_CLIENT_SECRET=
|
||||||
OAUTH2_REDIRECT_URL=
|
OAUTH2_REDIRECT_URL=https://wg-gen-web-demo.127-0-0-1.fr
|
||||||
|
|
||||||
# set provider name to fake to disable auth, also the default
|
# set provider name to fake to disable auth, also the default
|
||||||
OAUTH2_PROVIDER_NAME=fake
|
OAUTH2_PROVIDER_NAME=fake
|
||||||
|
34
auth/auth.go
34
auth/auth.go
@ -1,8 +1,14 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/auth/fake"
|
||||||
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/auth/github"
|
||||||
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/auth/oauth2oidc"
|
||||||
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/model"
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/model"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Auth interface {
|
type Auth interface {
|
||||||
@ -11,3 +17,31 @@ type Auth interface {
|
|||||||
Exchange(code string) (*oauth2.Token, error)
|
Exchange(code string) (*oauth2.Token, error)
|
||||||
UserInfo(oauth2Token *oauth2.Token) (*model.User, error)
|
UserInfo(oauth2Token *oauth2.Token) (*model.User, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAuthProvider() (Auth, error) {
|
||||||
|
var oauth2Client Auth
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch os.Getenv("OAUTH2_PROVIDER_NAME") {
|
||||||
|
case "fake":
|
||||||
|
log.Warn("Oauth is set to fake, no actual authentication will be performed")
|
||||||
|
oauth2Client = &fake.Fake{}
|
||||||
|
|
||||||
|
case "oauth2oidc":
|
||||||
|
log.Warn("Oauth is set to oauth2oidc, must be RFC implementation on server side")
|
||||||
|
oauth2Client = &oauth2oidc.Oauth2idc{}
|
||||||
|
|
||||||
|
case "github":
|
||||||
|
log.Warn("Oauth is set to github, no openid will be used")
|
||||||
|
oauth2Client = &github.Github{}
|
||||||
|
|
||||||
|
case "google":
|
||||||
|
return nil, fmt.Errorf("auth provider name %s not yet implemented", os.Getenv("OAUTH2_PROVIDER_NAME"))
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("auth provider name %s unknown", os.Getenv("OAUTH2_PROVIDER_NAME"))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = oauth2Client.Setup()
|
||||||
|
|
||||||
|
return oauth2Client, err
|
||||||
|
}
|
||||||
|
@ -1 +1,102 @@
|
|||||||
package github
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/model"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
oauth2Github "golang.org/x/oauth2/github"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Github struct{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
oauth2Config *oauth2.Config
|
||||||
|
)
|
||||||
|
|
||||||
|
// Setup validate provider
|
||||||
|
func (o *Github) Setup() error {
|
||||||
|
oauth2Config = &oauth2.Config{
|
||||||
|
ClientID: os.Getenv("OAUTH2_CLIENT_ID"),
|
||||||
|
ClientSecret: os.Getenv("OAUTH2_CLIENT_SECRET"),
|
||||||
|
RedirectURL: os.Getenv("OAUTH2_REDIRECT_URL"),
|
||||||
|
Scopes: []string{"user"},
|
||||||
|
Endpoint: oauth2Github.Endpoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CodeUrl get url to redirect client for auth
|
||||||
|
func (o *Github) CodeUrl(state string) string {
|
||||||
|
return oauth2Config.AuthCodeURL(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exchange exchange code for Oauth2 token
|
||||||
|
func (o *Github) Exchange(code string) (*oauth2.Token, error) {
|
||||||
|
oauth2Token, err := oauth2Config.Exchange(context.TODO(), code)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return oauth2Token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserInfo get token user
|
||||||
|
func (o *Github) UserInfo(oauth2Token *oauth2.Token) (*model.User, error) {
|
||||||
|
// https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/
|
||||||
|
|
||||||
|
// we have the token, lets get user information
|
||||||
|
req, err := http.NewRequest("GET", "https://api.github.com/user", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Authorization", fmt.Sprintf("token %s", oauth2Token.AccessToken))
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return nil, fmt.Errorf("http status %s expect 200 OK", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var data map[string]interface{}
|
||||||
|
err = json.Unmarshal(bodyBytes, &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// get some infos about user
|
||||||
|
user := &model.User{}
|
||||||
|
|
||||||
|
if val, ok := data["name"]; ok && val != nil {
|
||||||
|
user.Name = val.(string)
|
||||||
|
}
|
||||||
|
if val, ok := data["email"]; ok && val != nil {
|
||||||
|
user.Email = val.(string)
|
||||||
|
}
|
||||||
|
if val, ok := data["html_url"]; ok && val != nil {
|
||||||
|
user.Profile = val.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// openid specific
|
||||||
|
user.Sub = "github is not an openid provider"
|
||||||
|
user.Issuer = "https://github.com"
|
||||||
|
user.IssuedAt = time.Now().UTC()
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
@ -11,8 +11,6 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/api"
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/api"
|
||||||
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/auth"
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/auth"
|
||||||
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/auth/fake"
|
|
||||||
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/auth/oauth2oidc"
|
|
||||||
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/core"
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/core"
|
||||||
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/util"
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/util"
|
||||||
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/version"
|
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/version"
|
||||||
@ -20,6 +18,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -106,45 +105,14 @@ func main() {
|
|||||||
// serve static files
|
// serve static files
|
||||||
app.Use(static.Serve("/", static.LocalFile("./ui/dist", false)))
|
app.Use(static.Serve("/", static.LocalFile("./ui/dist", false)))
|
||||||
|
|
||||||
// setup Oauth2 client if enabled
|
// setup Oauth2 client
|
||||||
var oauth2Client auth.Auth
|
oauth2Client, err := auth.GetAuthProvider()
|
||||||
|
if err != nil {
|
||||||
switch os.Getenv("OAUTH2_PROVIDER_NAME") {
|
|
||||||
case "fake":
|
|
||||||
log.Warn("Oauth is set to fake, no actual authentication will be performed")
|
|
||||||
oauth2Client = &fake.Fake{}
|
|
||||||
err = oauth2Client.Setup()
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"OAUTH2_PROVIDER_NAME": "oauth2oidc",
|
|
||||||
"err": err,
|
|
||||||
}).Fatal("failed to setup Oauth2")
|
|
||||||
}
|
|
||||||
case "oauth2oidc":
|
|
||||||
log.Warn("Oauth is set to oauth2oidc, must be RFC implementation on server side")
|
|
||||||
oauth2Client = &oauth2oidc.Oauth2idc{}
|
|
||||||
err = oauth2Client.Setup()
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"OAUTH2_PROVIDER_NAME": "oauth2oidc",
|
|
||||||
"err": err,
|
|
||||||
}).Fatal("failed to setup Oauth2")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"OAUTH2_PROVIDER_NAME": os.Getenv("OAUTH2_PROVIDER_NAME"),
|
"err": err,
|
||||||
}).Fatal("auth provider name unknown")
|
}).Fatal("failed to setup Oauth2")
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("OAUTH2_ENABLE") == "true" {
|
|
||||||
oauth2Client = &oauth2oidc.Oauth2idc{}
|
|
||||||
err = oauth2Client.Setup()
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"err": err,
|
|
||||||
}).Fatal("failed to setup Oauth2")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
app.Use(func(ctx *gin.Context) {
|
app.Use(func(ctx *gin.Context) {
|
||||||
ctx.Set("oauth2Client", oauth2Client)
|
ctx.Set("oauth2Client", oauth2Client)
|
||||||
ctx.Next()
|
ctx.Next()
|
||||||
@ -167,6 +135,12 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// avoid 401 page for refresh after logout
|
||||||
|
if !strings.Contains(c.Request.URL.Path, "/api/") {
|
||||||
|
c.Redirect(301, "/index.html")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.AbortWithStatus(http.StatusUnauthorized)
|
c.AbortWithStatus(http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
|
6
go.mod
6
go.mod
@ -3,17 +3,11 @@ module gitlab.127-0-0-1.fr/vx3r/wg-gen-web
|
|||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/appleboy/gin-jwt/v2 v2.6.3 // indirect
|
|
||||||
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
|
|
||||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||||
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e
|
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e
|
||||||
github.com/gin-contrib/cors v1.3.1
|
github.com/gin-contrib/cors v1.3.1
|
||||||
github.com/gin-contrib/sessions v0.0.3
|
|
||||||
github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2
|
github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2
|
||||||
github.com/gin-gonic/contrib v0.0.0-20191209060500-d6e26eeaa607 // indirect
|
|
||||||
github.com/gin-gonic/gin v1.6.2
|
github.com/gin-gonic/gin v1.6.2
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
|
|
||||||
github.com/gorilla/sessions v1.2.0 // indirect
|
|
||||||
github.com/joho/godotenv v1.3.0
|
github.com/joho/godotenv v1.3.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
||||||
|
Loading…
Reference in New Issue
Block a user