Merge branch 'gnet-oauth'
This commit is contained in:
+6
-4
@@ -25,10 +25,12 @@ func LoginView(c *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
viewData.Settings["googleAuthEnabled"] = setting.OAuthService.Google
|
||||
viewData.Settings["githubAuthEnabled"] = setting.OAuthService.GitHub
|
||||
viewData.Settings["genericOAuthEnabled"] = setting.OAuthService.Generic
|
||||
viewData.Settings["oauthProviderName"] = setting.OAuthService.OAuthProviderName
|
||||
enabledOAuths := make(map[string]interface{})
|
||||
for key, oauth := range setting.OAuthService.OAuthInfos {
|
||||
enabledOAuths[key] = map[string]string{"name": oauth.Name}
|
||||
}
|
||||
|
||||
viewData.Settings["oauth"] = enabledOAuths
|
||||
viewData.Settings["disableUserSignUp"] = !setting.AllowUserSignUp
|
||||
viewData.Settings["loginHint"] = setting.LoginHint
|
||||
viewData.Settings["allowUserPassLogin"] = setting.AllowUserPassLogin
|
||||
|
||||
@@ -82,10 +82,11 @@ func OAuthLogin(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
cmd := m.CreateUserCommand{
|
||||
Login: userInfo.Email,
|
||||
Email: userInfo.Email,
|
||||
Name: userInfo.Name,
|
||||
Company: userInfo.Company,
|
||||
Login: userInfo.Email,
|
||||
Email: userInfo.Email,
|
||||
Name: userInfo.Name,
|
||||
Company: userInfo.Company,
|
||||
DefaultOrgRole: userInfo.Role,
|
||||
}
|
||||
|
||||
if err = bus.Dispatch(&cmd); err != nil {
|
||||
|
||||
@@ -7,4 +7,5 @@ const (
|
||||
GOOGLE
|
||||
TWITTER
|
||||
GENERIC
|
||||
GRAFANANET
|
||||
)
|
||||
|
||||
+10
-9
@@ -44,15 +44,16 @@ func (u *User) NameOrFallback() string {
|
||||
// COMMANDS
|
||||
|
||||
type CreateUserCommand struct {
|
||||
Email string
|
||||
Login string
|
||||
Name string
|
||||
Company string
|
||||
OrgName string
|
||||
Password string
|
||||
EmailVerified bool
|
||||
IsAdmin bool
|
||||
SkipOrgSetup bool
|
||||
Email string
|
||||
Login string
|
||||
Name string
|
||||
Company string
|
||||
OrgName string
|
||||
Password string
|
||||
EmailVerified bool
|
||||
IsAdmin bool
|
||||
SkipOrgSetup bool
|
||||
DefaultOrgRole string
|
||||
|
||||
Result User
|
||||
}
|
||||
|
||||
@@ -128,7 +128,11 @@ func CreateUser(cmd *m.CreateUserCommand) error {
|
||||
}
|
||||
|
||||
if setting.AutoAssignOrg && !user.IsAdmin {
|
||||
orgUser.Role = m.RoleType(setting.AutoAssignOrgRole)
|
||||
if len(cmd.DefaultOrgRole) > 0 {
|
||||
orgUser.Role = m.RoleType(cmd.DefaultOrgRole)
|
||||
} else {
|
||||
orgUser.Role = m.RoleType(setting.AutoAssignOrgRole)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = sess.Insert(&orgUser); err != nil {
|
||||
|
||||
@@ -8,12 +8,11 @@ type OAuthInfo struct {
|
||||
AllowedDomains []string
|
||||
ApiUrl string
|
||||
AllowSignup bool
|
||||
Name string
|
||||
}
|
||||
|
||||
type OAuther struct {
|
||||
GitHub, Google, Twitter, Generic bool
|
||||
OAuthInfos map[string]*OAuthInfo
|
||||
OAuthProviderName string
|
||||
OAuthInfos map[string]*OAuthInfo
|
||||
}
|
||||
|
||||
var OAuthService *OAuther
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package social
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
type SocialGrafanaNet struct {
|
||||
*oauth2.Config
|
||||
url string
|
||||
allowedOrganizations []string
|
||||
allowSignup bool
|
||||
}
|
||||
|
||||
func (s *SocialGrafanaNet) Type() int {
|
||||
return int(models.GRAFANANET)
|
||||
}
|
||||
|
||||
func (s *SocialGrafanaNet) IsEmailAllowed(email string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *SocialGrafanaNet) IsSignupAllowed() bool {
|
||||
return s.allowSignup
|
||||
}
|
||||
|
||||
func (s *SocialGrafanaNet) IsOrganizationMember(client *http.Client) bool {
|
||||
if len(s.allowedOrganizations) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
organizations, err := s.FetchOrganizations(client)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, allowedOrganization := range s.allowedOrganizations {
|
||||
for _, organization := range organizations {
|
||||
if organization == allowedOrganization {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *SocialGrafanaNet) FetchOrganizations(client *http.Client) ([]string, error) {
|
||||
type Record struct {
|
||||
Login string `json:"login"`
|
||||
}
|
||||
|
||||
url := fmt.Sprintf(s.url + "/api/oauth2/user/orgs")
|
||||
r, err := client.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer r.Body.Close()
|
||||
|
||||
var records []Record
|
||||
|
||||
if err = json.NewDecoder(r.Body).Decode(&records); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var logins = make([]string, len(records))
|
||||
for i, record := range records {
|
||||
logins[i] = record.Login
|
||||
}
|
||||
|
||||
return logins, nil
|
||||
}
|
||||
|
||||
func (s *SocialGrafanaNet) UserInfo(token *oauth2.Token) (*BasicUserInfo, error) {
|
||||
var data struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"login"`
|
||||
Email string `json:"email"`
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
var err error
|
||||
client := s.Client(oauth2.NoContext, token)
|
||||
r, err := client.Get(s.url + "/api/oauth2/user")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer r.Body.Close()
|
||||
|
||||
if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userInfo := &BasicUserInfo{
|
||||
Identity: strconv.Itoa(data.Id),
|
||||
Name: data.Name,
|
||||
Email: data.Email,
|
||||
Role: data.Role,
|
||||
}
|
||||
|
||||
if !s.IsOrganizationMember(client) {
|
||||
return nil, ErrMissingOrganizationMembership
|
||||
}
|
||||
|
||||
return userInfo, nil
|
||||
}
|
||||
+27
-13
@@ -15,6 +15,7 @@ type BasicUserInfo struct {
|
||||
Email string
|
||||
Login string
|
||||
Company string
|
||||
Role string
|
||||
}
|
||||
|
||||
type SocialConnector interface {
|
||||
@@ -36,7 +37,7 @@ func NewOAuthService() {
|
||||
setting.OAuthService = &setting.OAuther{}
|
||||
setting.OAuthService.OAuthInfos = make(map[string]*setting.OAuthInfo)
|
||||
|
||||
allOauthes := []string{"github", "google", "generic_oauth"}
|
||||
allOauthes := []string{"github", "google", "generic_oauth", "grafananet"}
|
||||
|
||||
for _, name := range allOauthes {
|
||||
sec := setting.Cfg.Section("auth." + name)
|
||||
@@ -50,6 +51,7 @@ func NewOAuthService() {
|
||||
Enabled: sec.Key("enabled").MustBool(),
|
||||
AllowedDomains: sec.Key("allowed_domains").Strings(" "),
|
||||
AllowSignup: sec.Key("allow_sign_up").MustBool(),
|
||||
Name: sec.Key("name").MustString(name),
|
||||
}
|
||||
|
||||
if !info.Enabled {
|
||||
@@ -70,22 +72,18 @@ func NewOAuthService() {
|
||||
|
||||
// GitHub.
|
||||
if name == "github" {
|
||||
setting.OAuthService.GitHub = true
|
||||
teamIds := sec.Key("team_ids").Ints(",")
|
||||
allowedOrganizations := sec.Key("allowed_organizations").Strings(" ")
|
||||
SocialMap["github"] = &SocialGithub{
|
||||
Config: &config,
|
||||
allowedDomains: info.AllowedDomains,
|
||||
apiUrl: info.ApiUrl,
|
||||
allowSignup: info.AllowSignup,
|
||||
teamIds: teamIds,
|
||||
allowedOrganizations: allowedOrganizations,
|
||||
teamIds: sec.Key("team_ids").Ints(","),
|
||||
allowedOrganizations: sec.Key("allowed_organizations").Strings(" "),
|
||||
}
|
||||
}
|
||||
|
||||
// Google.
|
||||
if name == "google" {
|
||||
setting.OAuthService.Google = true
|
||||
SocialMap["google"] = &SocialGoogle{
|
||||
Config: &config, allowedDomains: info.AllowedDomains,
|
||||
apiUrl: info.ApiUrl,
|
||||
@@ -95,17 +93,33 @@ func NewOAuthService() {
|
||||
|
||||
// Generic - Uses the same scheme as Github.
|
||||
if name == "generic_oauth" {
|
||||
setting.OAuthService.Generic = true
|
||||
setting.OAuthService.OAuthProviderName = sec.Key("oauth_provider_name").String()
|
||||
teamIds := sec.Key("team_ids").Ints(",")
|
||||
allowedOrganizations := sec.Key("allowed_organizations").Strings(" ")
|
||||
SocialMap["generic_oauth"] = &GenericOAuth{
|
||||
Config: &config,
|
||||
allowedDomains: info.AllowedDomains,
|
||||
apiUrl: info.ApiUrl,
|
||||
allowSignup: info.AllowSignup,
|
||||
teamIds: teamIds,
|
||||
allowedOrganizations: allowedOrganizations,
|
||||
teamIds: sec.Key("team_ids").Ints(","),
|
||||
allowedOrganizations: sec.Key("allowed_organizations").Strings(" "),
|
||||
}
|
||||
}
|
||||
|
||||
if name == "grafananet" {
|
||||
config := oauth2.Config{
|
||||
ClientID: info.ClientId,
|
||||
ClientSecret: info.ClientSecret,
|
||||
Endpoint: oauth2.Endpoint{
|
||||
AuthURL: setting.GrafanaNetUrl + "/oauth2/authorize",
|
||||
TokenURL: setting.GrafanaNetUrl + "/api/oauth2/token",
|
||||
},
|
||||
RedirectURL: strings.TrimSuffix(setting.AppUrl, "/") + SocialBaseUrl + name,
|
||||
Scopes: info.Scopes,
|
||||
}
|
||||
|
||||
SocialMap["grafananet"] = &SocialGrafanaNet{
|
||||
Config: &config,
|
||||
url: setting.GrafanaNetUrl,
|
||||
allowSignup: info.AllowSignup,
|
||||
allowedOrganizations: sec.Key("allowed_organizations").Strings(" "),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user