github.com/greenpau/go-authcrunch@v1.1.4/pkg/idp/oauth/user_groups.go (about) 1 // Copyright 2022 Paul Greenberg greenpau@outlook.com 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package oauth 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "io/ioutil" 21 "net/http" 22 "net/url" 23 24 "go.uber.org/zap" 25 ) 26 27 type googleResponse struct { 28 Response struct { 29 Groups []struct { 30 DisplayName string `json:"displayName"` 31 } `json:"groups"` 32 } `json:"response"` 33 } 34 35 func (b *IdentityProvider) fetchUserGroups(tokenData, userData map[string]interface{}) error { 36 var userURL string 37 var req *http.Request 38 var err error 39 40 if b.config.Driver != "google" || !b.ScopeExists( 41 "https://www.googleapis.com/auth/cloud-identity.groups.readonly", 42 "https://www.googleapis.com/auth/cloud-identity.groups", 43 ) { 44 return nil 45 } 46 if tokenData == nil || userData == nil { 47 return nil 48 } 49 50 if _, exists := tokenData["access_token"]; !exists { 51 return fmt.Errorf("access_token not found") 52 } 53 54 cli, err := b.newBrowser() 55 if err != nil { 56 return err 57 } 58 59 switch b.config.Driver { 60 case "google": 61 userURL = "https://cloudidentity.googleapis.com/v1/groups/-/memberships:getMembershipGraph?query=" 62 userURL += url.QueryEscape("'cloudidentity.googleapis.com/groups.discussion_forum' in labels && member_key_id=='" + userData["email"].(string) + "'") 63 64 req, err = http.NewRequest("GET", userURL, nil) 65 if err != nil { 66 return err 67 } 68 req.Header.Add("Authorization", "Bearer "+tokenData["access_token"].(string)) 69 default: 70 return fmt.Errorf("provider %s is unsupported for fetching user groups", b.config.Driver) 71 } 72 73 req.Header.Set("Accept", "application/json") 74 75 resp, err := cli.Do(req) 76 if err != nil { 77 return err 78 } 79 80 respBody, err := ioutil.ReadAll(resp.Body) 81 resp.Body.Close() 82 if err != nil { 83 return err 84 } 85 86 b.logger.Debug( 87 "User groups received", 88 zap.Any("body", respBody), 89 zap.String("url", userURL), 90 ) 91 92 switch b.config.Driver { 93 case "google": 94 var respParsed googleResponse 95 err = json.Unmarshal(respBody, &respParsed) 96 if err != nil { 97 return err 98 } 99 userGroups := []string{} 100 for _, group := range respParsed.Response.Groups { 101 userGroups = append(userGroups, group.DisplayName) 102 } 103 104 if userRoles, exists := userData["roles"]; exists { 105 userData["roles"] = append(userRoles.([]string), userGroups...) 106 } else { 107 userData["roles"] = userGroups 108 } 109 110 default: 111 return fmt.Errorf("provider %s is unsupported for fetching user groups", b.config.Driver) 112 } 113 114 return nil 115 }