ability to pull list of orgs and verify membership
This commit is contained in:
parent
0c3f9e5bde
commit
c324d66872
3 changed files with 49 additions and 5 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue