14type GitHubProvider struct {
20func NewGitHubProvider(p *ProviderData) *GitHubProvider {
21 p.ProviderName = "GitHub"
22 if p.LoginURL == nil || p.LoginURL.String() == "" {
23 p.LoginURL = &url.URL{
26 Path: "/login/oauth/authorize",
29 if p.RedeemURL == nil || p.RedeemURL.String() == "" {
30 p.RedeemURL = &url.URL{
33 Path: "/login/oauth/access_token",
36 // ValidationURL is the API Base URL
37 if p.ValidateURL == nil || p.ValidateURL.String() == "" {
38 p.ValidateURL = &url.URL{
40 Host: "api.github.com",
45 p.Scope = "user:email"
47 return &GitHubProvider{ProviderData: p}
49func (p *GitHubProvider) SetOrgTeam(org, team string) {
52 if org != "" || team != "" {
53 p.Scope += " read:org"
57func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) {
58 // https://developer.github.com/v3/orgs/#list-your-organizations
61 Login string `json:"login"`
65 "access_token": {accessToken},
70 Scheme: p.ValidateURL.Scheme,
71 Host: p.ValidateURL.Host,
72 Path: path.Join(p.ValidateURL.Path, "/user/orgs"),
73 RawQuery: params.Encode(),
75 req, _ := http.NewRequest("GET", endpoint.String(), nil)
76 req.Header.Set("Accept", "application/vnd.github.v3+json")
77 resp, err := http.DefaultClient.Do(req)
82 body, err := ioutil.ReadAll(resp.Body)
87 if resp.StatusCode != 200 {
88 return false, fmt.Errorf(
89 "got %d from %q %s", resp.StatusCode, stripToken(endpoint.String()), body)
92 if err := json.Unmarshal(body, &orgs); err != nil {
96 var presentOrgs []string
97 for _, org := range orgs {
98 if p.Org == org.Login {
99 log.Printf("Found Github Organization: %q", org.Login)
102 presentOrgs = append(presentOrgs, org.Login)
105 log.Printf("Missing Organization:%q in %v", p.Org, presentOrgs)
109func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) {
110 // https://developer.github.com/v3/orgs/teams/#list-user-teams
113 Name string `json:"name"`
114 Slug string `json:"slug"`
116 Login string `json:"login"`
117 } `json:"organization"`
120 params := url.Values{
121 "access_token": {accessToken},
125 endpoint := &url.URL{
126 Scheme: p.ValidateURL.Scheme,
127 Host: p.ValidateURL.Host,
128 Path: path.Join(p.ValidateURL.Path, "/user/teams"),
129 RawQuery: params.Encode(),
131 req, _ := http.NewRequest("GET", endpoint.String(), nil)
132 req.Header.Set("Accept", "application/vnd.github.v3+json")
133 resp, err := http.DefaultClient.Do(req)
138 body, err := ioutil.ReadAll(resp.Body)
143 if resp.StatusCode != 200 {
144 return false, fmt.Errorf(
145 "got %d from %q %s", resp.StatusCode, stripToken(endpoint.String()), body)
148 if err := json.Unmarshal(body, &teams); err != nil {
149 return false, fmt.Errorf("%s unmarshaling %s", err, body)
153 presentOrgs := make(map[string]bool)
154 var presentTeams []string
155 for _, team := range teams {
156 presentOrgs[team.Org.Login] = true
157 if p.Org == team.Org.Login {
159 ts := strings.Split(p.Team, ",")
160 for _, t := range ts {
162 log.Printf("Found Github Organization:%q Team:%q (Name:%q)", team.Org.Login, team.Slug, team.Name)
166 presentTeams = append(presentTeams, team.Slug)
170 log.Printf("Missing Team:%q from Org:%q in teams: %v", p.Team, p.Org, presentTeams)
173 for org, _ := range presentOrgs {
174 allOrgs = append(allOrgs, org)
176 log.Printf("Missing Organization:%q in %#v", p.Org, allOrgs)
181func (p *GitHubProvider) GetEmailAddress(s *SessionState) (string, error) {
183 var emails []struct {
184 Email string `json:"email"`
185 Primary bool `json:"primary"`
188 // if we require an Org or Team, check that first
191 if ok, err := p.hasOrgAndTeam(s.AccessToken); err != nil || !ok {
195 if ok, err := p.hasOrg(s.AccessToken); err != nil || !ok {
201 params := url.Values{
202 "access_token": {s.AccessToken},
205 endpoint := &url.URL{
206 Scheme: p.ValidateURL.Scheme,
207 Host: p.ValidateURL.Host,
208 Path: path.Join(p.ValidateURL.Path, "/user/emails"),
209 RawQuery: params.Encode(),
211 resp, err := http.DefaultClient.Get(endpoint.String())
215 body, err := ioutil.ReadAll(resp.Body)
221 if resp.StatusCode != 200 {
222 return "", fmt.Errorf("got %d from %q %s",
223 resp.StatusCode, stripToken(endpoint.String()), body)
225 log.Printf("got %d from %q %s", resp.StatusCode, stripToken(endpoint.String()), body)
228 if err := json.Unmarshal(body, &emails); err != nil {
229 return "", fmt.Errorf("%s unmarshaling %s", err, body)
232 for _, email := range emails {
234 return email.Email, nil
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list