ability to pull list of orgs and verify membership

This commit is contained in:
Brad Rydzewski 2015-04-15 00:20:00 -07:00
parent 0c3f9e5bde
commit c324d66872
3 changed files with 49 additions and 5 deletions

View file

@ -26,8 +26,6 @@ type GitHub struct {
Secret string
PrivateMode bool
SkipVerify bool
Orgs []string
Open bool
cache *lru.Cache
}
@ -40,8 +38,6 @@ func New(service *settings.Service) *GitHub {
Secret: service.OAuth.Secret,
PrivateMode: service.PrivateMode,
SkipVerify: service.SkipVerify,
Orgs: service.Orgs,
Open: service.Open,
}
var err error
github.cache, err = lru.New(1028)
@ -81,6 +77,20 @@ func (g *GitHub) Login(token, secret string) (*common.User, error) {
return &user, nil
}
// Orgs fetches the organizations for the given user.
func (g *GitHub) Orgs(u *common.User) ([]string, error) {
client := NewClient(g.API, u.Token, g.SkipVerify)
orgs_ := []string{}
orgs, err := GetOrgs(client)
if err != nil {
return orgs_, err
}
for _, org := range orgs {
orgs_ = append(orgs_, *org.Login)
}
return orgs_, nil
}
// Repo fetches the named repository from the remote system.
func (g *GitHub) Repo(u *common.User, owner, name string) (*common.Repo, error) {
client := NewClient(g.API, u.Token, g.SkipVerify)

View file

@ -11,6 +11,13 @@ type Remote interface {
// remote user details.
Login(token, secret string) (*common.User, error)
// Orgs fetches the organizations for the given user.
//
// TODO(bradrydzewski) consider consolidating this to return
// the list of organizations along with
// the user Login info.
Orgs(u *common.User) ([]string, error)
// Repo fetches the named repository from the remote system.
Repo(u *common.User, owner, repo string) (*common.Repo, error)

View file

@ -23,6 +23,7 @@ import (
func GetLogin(c *gin.Context) {
settings := ToSettings(c)
session := ToSession(c)
remote := ToRemote(c)
store := ToDatastore(c)
// when dealing with redirects we may need
@ -49,8 +50,18 @@ func GetLogin(c *gin.Context) {
return
}
// get the user from the database
login := ToUser(c)
// check organization membership, if applicable
if len(settings.Service.Orgs) != 0 {
orgs, _ := remote.Orgs(login)
if !checkMembership(orgs, settings.Service.Orgs) {
c.Redirect(303, "/login#error=access_denied_org")
return
}
}
// get the user from the database
u, err := store.User(login.Login)
if err != nil {
count, err := store.UserCount()
@ -193,3 +204,19 @@ func getLoginBasic(c *gin.Context) {
// add the user to the request
c.Set("user", user)
}
// checkMembership is a helper function that compares the user's
// organization list to a whitelist of organizations that are
// approved to use the system.
func checkMembership(orgs, whitelist []string) bool {
orgs_ := make(map[string]struct{}, len(orgs))
for _, org := range orgs {
orgs_[org] = struct{}{}
}
for _, org := range whitelist {
if _, ok := orgs_[org]; ok {
return true
}
}
return false
}