Private GIT

Skip to content
Snippets Groups Projects
Commit 6fcd70bf authored by vx3r's avatar vx3r
Browse files

implement github oauth, set demo to github auth

parent dd99358f
No related branches found
No related tags found
No related merge requests found
......@@ -32,10 +32,10 @@ OAUTH2_REDIRECT_URL=
# example with github
OAUTH2_PROVIDER_NAME=github
OAUTH2_PROVIDER=
OAUTH2_PROVIDER=https://github.com
OAUTH2_CLIENT_ID=
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
OAUTH2_PROVIDER_NAME=fake
package auth
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"
"golang.org/x/oauth2"
"os"
)
type Auth interface {
......@@ -11,3 +17,31 @@ type Auth interface {
Exchange(code string) (*oauth2.Token, 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
}
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"
"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/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/util"
"gitlab.127-0-0-1.fr/vx3r/wg-gen-web/version"
......@@ -20,6 +18,7 @@ import (
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
......@@ -106,45 +105,14 @@ func main() {
// serve static files
app.Use(static.Serve("/", static.LocalFile("./ui/dist", false)))
// setup Oauth2 client if enabled
var oauth2Client auth.Auth
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()
// setup Oauth2 client
oauth2Client, err := auth.GetAuthProvider()
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{
"OAUTH2_PROVIDER_NAME": os.Getenv("OAUTH2_PROVIDER_NAME"),
}).Fatal("auth provider name unknown")
}
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) {
ctx.Set("oauth2Client", oauth2Client)
ctx.Next()
......@@ -167,6 +135,12 @@ func main() {
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)
return
})
......
......@@ -3,17 +3,11 @@ module gitlab.127-0-0-1.fr/vx3r/wg-gen-web
go 1.14
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/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e
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-gonic/contrib v0.0.0-20191209060500-d6e26eeaa607 // indirect
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/patrickmn/go-cache v2.1.0+incompatible
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment