Files
remark42/backend/vendor/github.com/go-pkgz/auth/provider/providers.go
T

150 lines
4.3 KiB
Go

// Package provider implements all oauth2, oauth1 as well as custom and direct providers
package provider
import (
"crypto/sha1"
"encoding/json"
"fmt"
"golang.org/x/oauth2/facebook"
"golang.org/x/oauth2/github"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/yandex"
"github.com/dghubble/oauth1"
"github.com/dghubble/oauth1/twitter"
"github.com/go-pkgz/auth/token"
)
// NewGoogle makes google oauth2 provider
func NewGoogle(p Params) Oauth2Handler {
return initOauth2Handler(p, Oauth2Handler{
name: "google",
endpoint: google.Endpoint,
scopes: []string{"https://www.googleapis.com/auth/userinfo.profile"},
infoURL: "https://www.googleapis.com/oauth2/v3/userinfo",
mapUser: func(data UserData, _ []byte) token.User {
userInfo := token.User{
// encode email with provider name to avoid collision if same id returned by other provider
ID: "google_" + token.HashID(sha1.New(), data.Value("sub")),
Name: data.Value("name"),
Picture: data.Value("picture"),
}
if userInfo.Name == "" {
userInfo.Name = "noname_" + userInfo.ID[8:12]
}
return userInfo
},
})
}
// NewGithub makes github oauth2 provider
func NewGithub(p Params) Oauth2Handler {
return initOauth2Handler(p, Oauth2Handler{
name: "github",
endpoint: github.Endpoint,
scopes: []string{},
infoURL: "https://api.github.com/user",
mapUser: func(data UserData, _ []byte) token.User {
userInfo := token.User{
ID: "github_" + token.HashID(sha1.New(), data.Value("login")),
Name: data.Value("name"),
Picture: data.Value("avatar_url"),
}
// github may have no user name, use login in this case
if userInfo.Name == "" {
userInfo.Name = data.Value("login")
}
return userInfo
},
})
}
// NewFacebook makes facebook oauth2 provider
func NewFacebook(p Params) Oauth2Handler {
// response format for fb /me call
type uinfo struct {
ID string `json:"id"`
Name string `json:"name"`
Picture struct {
Data struct {
URL string `json:"url"`
} `json:"data"`
} `json:"picture"`
}
return initOauth2Handler(p, Oauth2Handler{
name: "facebook",
endpoint: facebook.Endpoint,
scopes: []string{"public_profile"},
infoURL: "https://graph.facebook.com/me?fields=id,name,picture",
mapUser: func(data UserData, bdata []byte) token.User {
userInfo := token.User{
ID: "facebook_" + token.HashID(sha1.New(), data.Value("id")),
Name: data.Value("name"),
}
if userInfo.Name == "" {
userInfo.Name = userInfo.ID[0:16]
}
uinfoJSON := uinfo{}
if err := json.Unmarshal(bdata, &uinfoJSON); err == nil {
userInfo.Picture = uinfoJSON.Picture.Data.URL
}
return userInfo
},
})
}
// NewYandex makes yandex oauth2 provider
func NewYandex(p Params) Oauth2Handler {
return initOauth2Handler(p, Oauth2Handler{
name: "yandex",
endpoint: yandex.Endpoint,
scopes: []string{},
// See https://tech.yandex.com/passport/doc/dg/reference/response-docpage/
infoURL: "https://login.yandex.ru/info?format=json",
mapUser: func(data UserData, _ []byte) token.User {
userInfo := token.User{
ID: "yandex_" + token.HashID(sha1.New(), data.Value("id")),
Name: data.Value("display_name"), // using Display Name by default
}
if userInfo.Name == "" {
userInfo.Name = data.Value("real_name") // using Real Name (== full name) if Display Name is empty
}
if userInfo.Name == "" {
userInfo.Name = data.Value("login") // otherwise using login
}
if data.Value("default_avatar_id") != "" {
userInfo.Picture = fmt.Sprintf("https://avatars.yandex.net/get-yapic/%s/islands-200", data.Value("default_avatar_id"))
}
return userInfo
},
})
}
// NewTwitter makes twitter oauth2 provider
func NewTwitter(p Params) Oauth1Handler {
return initOauth1Handler(p, Oauth1Handler{
name: "twitter",
conf: oauth1.Config{
Endpoint: twitter.AuthorizeEndpoint,
},
infoURL: "https://api.twitter.com/1.1/account/verify_credentials.json",
mapUser: func(data UserData, _ []byte) token.User {
userInfo := token.User{
ID: "twitter_" + token.HashID(sha1.New(), data.Value("id_str")),
Name: data.Value("screen_name"),
Picture: data.Value("profile_image_url_https"),
}
if userInfo.Name == "" {
userInfo.Name = data.Value("name")
}
return userInfo
},
})
}