Skip to content

Instantly share code, notes, and snippets.

@dewski
Created April 29, 2015 03:11
Show Gist options
  • Save dewski/bbf2069e3a2c25bc3524 to your computer and use it in GitHub Desktop.
Save dewski/bbf2069e3a2c25bc3524 to your computer and use it in GitHub Desktop.
diff --git a/conf/defaults.ini b/conf/defaults.ini
index 6bb3fb8..7345f18 100644
--- a/conf/defaults.ini
+++ b/conf/defaults.ini
@@ -140,6 +140,7 @@ enabled = false
client_id = some_id
client_secret = some_secret
scopes = user:email
+team_ids =
auth_url = https://github.com/login/oauth/authorize
token_url = https://github.com/login/oauth/access_token
api_url = https://api.github.com/user
diff --git a/pkg/api/login_oauth.go b/pkg/api/login_oauth.go
index 11d6275..d89a723 100644
--- a/pkg/api/login_oauth.go
+++ b/pkg/api/login_oauth.go
@@ -45,7 +45,11 @@ func OAuthLogin(ctx *middleware.Context) {
userInfo, err := connect.UserInfo(token)
if err != nil {
- ctx.Handle(500, fmt.Sprintf("login.OAuthLogin(get info from %s)", name), err)
+ if err == social.ErrMissingTeamMembership {
+ ctx.Redirect(setting.AppSubUrl + "/login?missing_team_membership=1")
+ } else {
+ ctx.Handle(500, fmt.Sprintf("login.OAuthLogin(get info from %s)", name), err)
+ }
return
}
diff --git a/pkg/social/social.go b/pkg/social/social.go
index 47c7ea5..638232b 100644
--- a/pkg/social/social.go
+++ b/pkg/social/social.go
@@ -5,6 +5,8 @@ import (
"fmt"
"strconv"
"strings"
+ "errors"
+ "net/http"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
@@ -75,7 +77,8 @@ func NewOAuthService() {
// GitHub.
if name == "github" {
setting.OAuthService.GitHub = true
- SocialMap["github"] = &SocialGithub{Config: &config, allowedDomains: info.AllowedDomains, ApiUrl: info.ApiUrl, allowSignup: info.AllowSignup}
+ teamIds := sec.Key("team_ids").Ints(",")
+ SocialMap["github"] = &SocialGithub{Config: &config, allowedDomains: info.AllowedDomains, ApiUrl: info.ApiUrl, allowSignup: info.AllowSignup, teamIds: teamIds}
}
// Google.
@@ -105,8 +108,13 @@ type SocialGithub struct {
allowedDomains []string
ApiUrl string
allowSignup bool
+ teamIds []int
}
+var (
+ ErrMissingTeamMembership = errors.New("User not a member of one of the required teams")
+)
+
func (s *SocialGithub) Type() int {
return int(models.GITHUB)
}
@@ -119,6 +127,29 @@ func (s *SocialGithub) IsSignupAllowed() bool {
return s.allowSignup
}
+func (s *SocialGithub) IsTeamMember(client *http.Client, username string, teamId int) bool {
+ var data struct {
+ Url string `json:"url"`
+ State string `json:"state"`
+ }
+
+ membershipUrl := fmt.Sprintf("https://api.github.com/teams/%d/memberships/%s", teamId, username)
+ r, err := client.Get(membershipUrl)
+ if err != nil {
+ return false
+ }
+
+ defer r.Body.Close()
+
+ if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
+ return false
+ }
+
+ active := data.State == "active"
+
+ return active
+}
+
func (s *SocialGithub) UserInfo(token *oauth2.Token) (*BasicUserInfo, error) {
var data struct {
Id int `json:"id"`
@@ -139,11 +170,23 @@ func (s *SocialGithub) UserInfo(token *oauth2.Token) (*BasicUserInfo, error) {
return nil, err
}
- return &BasicUserInfo{
+ userInfo := &BasicUserInfo{
Identity: strconv.Itoa(data.Id),
Name: data.Name,
Email: data.Email,
- }, nil
+ }
+
+ if len(s.teamIds) > 0 {
+ for _, teamId := range s.teamIds {
+ if s.IsTeamMember(client, data.Name, teamId) {
+ return userInfo, nil
+ }
+ }
+
+ return nil, ErrMissingTeamMembership
+ } else {
+ return userInfo, nil
+ }
}
// ________ .__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment