OAuth: return GitLab groups as a part of user info (enable team sync) (#18388)

* GitLab OAuth: GetGroups refactor

* GitLab OAuth: fetch groups into UserInfo

* GitLab OAuth: minor refactor

* GitLab OAuth: team sync docs
This commit is contained in:
Alexander Zobnin
2019-08-07 17:05:35 +03:00
committed by GitHub
parent b424e12a5a
commit b47f0ff07f
2 changed files with 37 additions and 13 deletions
+11
View File
@@ -116,3 +116,14 @@ api_url = https://gitlab.com/api/v4
allowed_groups = example, foo/bar
```
### Team Sync (Enterprise only)
> Only available in Grafana Enterprise v6.4+
With Team Sync you can map your GitLab groups to teams in Grafana so that your users will automatically be added to
the correct teams.
Your GitLab groups can be referenced in the same way as `allowed_groups`, like `example` or `foo/bar`.
[Learn more about Team Sync]({{< relref "auth/enhanced_ldap.md" >}})
+26 -13
View File
@@ -35,17 +35,15 @@ func (s *SocialGitlab) IsSignupAllowed() bool {
return s.allowSignup
}
func (s *SocialGitlab) IsGroupMember(client *http.Client) bool {
func (s *SocialGitlab) IsGroupMember(groups []string) bool {
if len(s.allowedGroups) == 0 {
return true
}
for groups, url := s.GetGroups(client, s.apiUrl+"/groups"); groups != nil; groups, url = s.GetGroups(client, url) {
for _, allowedGroup := range s.allowedGroups {
for _, group := range groups {
if group == allowedGroup {
return true
}
for _, allowedGroup := range s.allowedGroups {
for _, group := range groups {
if group == allowedGroup {
return true
}
}
}
@@ -53,7 +51,18 @@ func (s *SocialGitlab) IsGroupMember(client *http.Client) bool {
return false
}
func (s *SocialGitlab) GetGroups(client *http.Client, url string) ([]string, string) {
func (s *SocialGitlab) GetGroups(client *http.Client) []string {
groups := make([]string, 0)
for page, url := s.GetGroupsPage(client, s.apiUrl+"/groups"); page != nil; page, url = s.GetGroupsPage(client, url) {
groups = append(groups, page...)
}
return groups
}
// GetGroupsPage returns groups and link to the next page if response is paginated
func (s *SocialGitlab) GetGroupsPage(client *http.Client, url string) ([]string, string) {
type Group struct {
FullPath string `json:"full_path"`
}
@@ -83,6 +92,7 @@ func (s *SocialGitlab) GetGroups(client *http.Client, url string) ([]string, str
fullPaths[i] = group.FullPath
}
// GitLab uses Link header with "rel" set to prev/next/first/last page. We need "next".
if link, ok := response.Headers["Link"]; ok {
pattern := regexp.MustCompile(`<([^>]+)>; rel="next"`)
if matches := pattern.FindStringSubmatch(link[0]); matches != nil {
@@ -117,14 +127,17 @@ func (s *SocialGitlab) UserInfo(client *http.Client, token *oauth2.Token) (*Basi
return nil, fmt.Errorf("User %s is inactive", data.Username)
}
groups := s.GetGroups(client)
userInfo := &BasicUserInfo{
Id: fmt.Sprintf("%d", data.Id),
Name: data.Name,
Login: data.Username,
Email: data.Email,
Id: fmt.Sprintf("%d", data.Id),
Name: data.Name,
Login: data.Username,
Email: data.Email,
Groups: groups,
}
if !s.IsGroupMember(client) {
if !s.IsGroupMember(groups) {
return nil, ErrMissingGroupMembership
}