package provider import ( "context" "net/http" "time" json "github.com/json-iterator/go" "golang.org/x/oauth2" "golang.org/x/oauth2/github" ) type GithubProvider struct{} func (p GithubProvider) Provider() OAuth2Provider { return "github" } func (p GithubProvider) NewConfig(ClientID, ClientSecret string) *oauth2.Config { return &oauth2.Config{ ClientID: ClientID, ClientSecret: ClientSecret, Scopes: []string{"user"}, Endpoint: github.Endpoint, } } func (p GithubProvider) GetUserInfo(ctx context.Context, config *oauth2.Config, code string) (*UserInfo, error) { oauth2Token, err := config.Exchange(ctx, code) if err != nil { return nil, err } client := config.Client(ctx, oauth2Token) req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.github.com/user", nil) if err != nil { return nil, err } resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() ui := githubUserInfo{} err = json.NewDecoder(resp.Body).Decode(&ui) if err != nil { return nil, err } return &UserInfo{ Username: ui.Login, ProviderUserID: ui.ID, }, nil } func init() { RegisterProvider(GithubProvider{}) } type githubUserInfo struct { Login string `json:"login"` ID uint `json:"id"` NodeID string `json:"node_id"` AvatarURL string `json:"avatar_url"` GravatarID string `json:"gravatar_id"` URL string `json:"url"` HTMLURL string `json:"html_url"` FollowersURL string `json:"followers_url"` FollowingURL string `json:"following_url"` GistsURL string `json:"gists_url"` StarredURL string `json:"starred_url"` SubscriptionsURL string `json:"subscriptions_url"` OrganizationsURL string `json:"organizations_url"` ReposURL string `json:"repos_url"` EventsURL string `json:"events_url"` ReceivedEventsURL string `json:"received_events_url"` Type string `json:"type"` SiteAdmin bool `json:"site_admin"` Name string `json:"name"` Company interface{} `json:"company"` Blog string `json:"blog"` Location string `json:"location"` Email interface{} `json:"email"` Hireable interface{} `json:"hireable"` Bio string `json:"bio"` TwitterUsername interface{} `json:"twitter_username"` PublicRepos int `json:"public_repos"` PublicGists int `json:"public_gists"` Followers int `json:"followers"` Following int `json:"following"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` PrivateGists int `json:"private_gists"` TotalPrivateRepos int `json:"total_private_repos"` OwnedPrivateRepos int `json:"owned_private_repos"` DiskUsage int `json:"disk_usage"` Collaborators int `json:"collaborators"` TwoFactorAuthentication bool `json:"two_factor_authentication"` Plan Plan `json:"plan"` } type Plan struct { Name string `json:"name"` Space int `json:"space"` Collaborators int `json:"collaborators"` PrivateRepos int `json:"private_repos"` }