diff --git a/go.sum b/go.sum index fba82c893..da7cb6f25 100644 --- a/go.sum +++ b/go.sum @@ -714,6 +714,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -766,10 +767,12 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cookieo9/resources-go.v2 v2.0.0-20150225115733-d27c04069d0d h1:YjTGSRV59gG1DHCq68v2B771I9dGFxvMkugf7OKglpk= gopkg.in/cookieo9/resources-go.v2 v2.0.0-20150225115733-d27c04069d0d/go.mod h1:kbUs813+JgwKQdecaTv87br/FZUaSEuPj8vbr2vq8sY= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -782,6 +785,7 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= diff --git a/internal/identity/oauth/github/github.go b/internal/identity/oauth/github/github.go index 906c44415..2752b08d9 100644 --- a/internal/identity/oauth/github/github.go +++ b/internal/identity/oauth/github/github.go @@ -30,7 +30,6 @@ const ( defaultProviderURL = "https://github.com" githubAPIURL = "https://api.github.com" userPath = "/user" - teamPath = "/user/teams" revokePath = "/applications/%s/grant" emailPath = "/user/emails" // https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps @@ -41,6 +40,8 @@ const ( refreshDeadline = time.Minute * 60 ) +var maxTime = time.Unix(1<<63-1, 0) + // https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/ var defaultScopes = []string{"user:email", "read:org"} @@ -82,6 +83,9 @@ func (p *Provider) Authenticate(ctx context.Context, code string, v interface{}) return nil, fmt.Errorf("github: token exchange failed %v", err) } + // github tokens never expire + oauth2Token.Expiry = maxTime + err = p.UpdateUserInfo(ctx, oauth2Token, v) if err != nil { return nil, err @@ -94,7 +98,6 @@ func (p *Provider) Authenticate(ctx context.Context, code string, v interface{}) // // https://developer.github.com/v3/users/#get-the-authenticated-user func (p *Provider) UpdateUserInfo(ctx context.Context, t *oauth2.Token, v interface{}) error { - err := p.userInfo(ctx, t, v) if err != nil { return fmt.Errorf("github: could not retrieve user info %w", err) @@ -105,56 +108,15 @@ func (p *Provider) UpdateUserInfo(ctx context.Context, t *oauth2.Token, v interf return fmt.Errorf("github: could not retrieve user email %w", err) } - err = p.userTeams(ctx, t, v) - if err != nil { - return fmt.Errorf("github: could not retrieve groups %w", err) - } - return nil } // Refresh is a no-op for github, because github sessions never expire. func (p *Provider) Refresh(ctx context.Context, t *oauth2.Token, v interface{}) (*oauth2.Token, error) { + t.Expiry = time.Now().Add(refreshDeadline) return t, nil } -// userTeams returns a slice of teams the user belongs by making a request -// to github API -// -// https://developer.github.com/v3/teams/#list-user-teams -// https://developer.github.com/v3/auth/ -func (p *Provider) userTeams(ctx context.Context, t *oauth2.Token, v interface{}) error { - - var response []struct { - ID json.Number `json:"id"` - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` - Slug string `json:"slug"` - Description string `json:"description,omitempty"` - ReposURL string `json:"repos_url,omitempty"` - Privacy string `json:"privacy,omitempty"` - } - - headers := map[string]string{"Authorization": fmt.Sprintf("token %s", t.AccessToken)} - teamURL := githubAPIURL + teamPath - err := httputil.Client(ctx, http.MethodGet, teamURL, version.UserAgent(), headers, nil, &response) - if err != nil { - return err - } - log.Debug().Interface("teams", response).Msg("github: user teams") - var out struct { - Groups []string `json:"groups"` - } - for _, org := range response { - out.Groups = append(out.Groups, org.ID.String()) - } - b, err := json.Marshal(out) - if err != nil { - return err - } - return json.Unmarshal(b, v) -} - // userEmail returns the primary email of the user by making // a query to github API. // @@ -216,15 +178,19 @@ func (p *Provider) userInfo(ctx context.Context, t *oauth2.Token, v interface{}) User string `json:"user"` Picture string `json:"picture,omitempty"` // needs to be set manually - Expiry *jwt.NumericDate `json:"exp,omitempty"` + Expiry *jwt.NumericDate `json:"exp,omitempty"` + NotBefore *jwt.NumericDate `json:"nbf,omitempty"` + IssuedAt *jwt.NumericDate `json:"iat,omitempty"` } + out.Expiry = jwt.NewNumericDate(time.Now().Add(refreshDeadline)) + out.NotBefore = jwt.NewNumericDate(time.Now()) + out.IssuedAt = jwt.NewNumericDate(time.Now()) + out.User = response.Login out.Subject = response.Login out.Name = response.Name out.Picture = response.AvatarURL - // set the session expiry - out.Expiry = jwt.NewNumericDate(time.Now().Add(refreshDeadline)) b, err := json.Marshal(out) if err != nil { return err