github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/jwt/github/provider.go (about) 1 package github 2 3 import ( 4 "errors" 5 "net/http" 6 "strings" 7 "sync" 8 9 "github.com/dgrijalva/jwt-go" 10 "github.com/google/go-github/github" 11 12 "github.com/hellofresh/janus/pkg/config" 13 "github.com/hellofresh/janus/pkg/jwt/provider" 14 ) 15 16 func init() { 17 provider.Register("github", &Provider{}) 18 } 19 20 // Provider abstracts the authentication for github 21 type Provider struct { 22 provider.Verifier 23 24 teams []Team 25 config config.Credentials 26 } 27 28 // Build acts like the constructor for a provider 29 func (gp *Provider) Build(config config.Credentials) provider.Provider { 30 client := NewClient() 31 teams := gp.teamConfigsToTeam(config.Github.Teams) 32 33 return &Provider{ 34 Verifier: provider.NewVerifierBasket( 35 NewTeamVerifier(teams, client), 36 NewOrganizationVerifier(config.Github.Organizations, client), 37 ), 38 teams: teams, 39 config: config, 40 } 41 } 42 43 // GetClaims returns a JWT Map Claim 44 func (gp *Provider) GetClaims(httpClient *http.Client) (jwt.MapClaims, error) { 45 client := NewClient() 46 47 var ( 48 wg sync.WaitGroup 49 user *github.User 50 usersOrgTeams OrganizationTeams 51 errs []string 52 ) 53 54 wg.Add(2) 55 go func() { 56 defer wg.Done() 57 var err error 58 user, err = client.CurrentUser(httpClient) 59 if err != nil { 60 errs = append(errs, "failed to get github users") 61 } 62 }() 63 64 go func() { 65 defer wg.Done() 66 var err error 67 usersOrgTeams, err = client.Teams(httpClient) 68 if err != nil { 69 errs = append(errs, "failed to get github teams") 70 } 71 }() 72 wg.Wait() 73 74 if len(errs) > 0 { 75 return nil, errors.New(strings.Join(errs, ", ")) 76 } 77 78 return jwt.MapClaims{ 79 "sub": *user.Login, 80 "is_admin": gp.isAdmin(usersOrgTeams), 81 }, nil 82 } 83 84 func (gp *Provider) teamConfigsToTeam(configTeams map[string]string) []Team { 85 var teams []Team 86 for org, team := range configTeams { 87 teams = append(teams, Team{ 88 Name: team, 89 Organization: org, 90 }) 91 } 92 return teams 93 } 94 95 func (gp *Provider) isAdmin(usersOrgTeams OrganizationTeams) bool { 96 for _, team := range gp.teams { 97 if teams, ok := usersOrgTeams[team.Organization]; ok { 98 for _, teamUserBelongsTo := range teams { 99 if teamUserBelongsTo == gp.config.JanusAdminTeam { 100 return true 101 } 102 } 103 } 104 } 105 return false 106 }