From 34eca3984f24d122f819d7e62f2caad29d67f604 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Mon, 15 Aug 2016 15:24:40 +0100 Subject: [PATCH 1/2] List possible GH repos on /getSession Add an Info() method to pull out info about an auth session. --- src/github.com/matrix-org/go-neb/api.go | 4 +- .../matrix-org/go-neb/realms/github/github.go | 29 +++++++++++ .../matrix-org/go-neb/realms/jira/jira.go | 5 ++ .../go-neb/services/github/client/client.go | 51 +++++++++++++++++++ .../go-neb/services/github/github.go | 20 ++------ .../matrix-org/go-neb/types/types.go | 1 + 6 files changed, 91 insertions(+), 19 deletions(-) create mode 100644 src/github.com/matrix-org/go-neb/services/github/client/client.go diff --git a/src/github.com/matrix-org/go-neb/api.go b/src/github.com/matrix-org/go-neb/api.go index f2235c1..a6fc0c8 100644 --- a/src/github.com/matrix-org/go-neb/api.go +++ b/src/github.com/matrix-org/go-neb/api.go @@ -295,6 +295,6 @@ func (h *getSessionHandler) OnIncomingRequest(req *http.Request) (interface{}, * return &struct { ID string Authenticated bool - Session types.AuthSession - }{session.ID(), session.Authenticated(), session}, nil + Session interface{} + }{session.ID(), session.Authenticated(), session.Info()}, nil } diff --git a/src/github.com/matrix-org/go-neb/realms/github/github.go b/src/github.com/matrix-org/go-neb/realms/github/github.go index 5ce18b1..677df7b 100644 --- a/src/github.com/matrix-org/go-neb/realms/github/github.go +++ b/src/github.com/matrix-org/go-neb/realms/github/github.go @@ -5,7 +5,9 @@ import ( "encoding/hex" "encoding/json" log "github.com/Sirupsen/logrus" + "github.com/google/go-github/github" "github.com/matrix-org/go-neb/database" + "github.com/matrix-org/go-neb/services/github/client" "github.com/matrix-org/go-neb/types" "io/ioutil" "net/http" @@ -37,6 +39,33 @@ func (s *GithubSession) Authenticated() bool { return s.AccessToken != "" } +// Info returns a list of possible repositories that this session can integrate with. +func (s *GithubSession) Info() interface{} { + logger := log.WithFields(log.Fields{ + "user_id": s.userID, + "realm_id": s.realmID, + }) + cli := client.New(s.AccessToken) + // query for a list of possible projects + rs, _, err := cli.Repositories.List("", &github.RepositoryListOptions{ + Type: "all", + }) + if err != nil { + logger.WithError(err).Print("Failed to query github projects on github.com") + return nil + } + + var repos []client.TrimmedRepository + + for _, r := range rs { + repos = append(repos, client.TrimRepository(r)) + } + + return struct { + Repos []client.TrimmedRepository + }{repos} +} + // UserID returns the user_id who authorised with Github func (s *GithubSession) UserID() string { return s.userID diff --git a/src/github.com/matrix-org/go-neb/realms/jira/jira.go b/src/github.com/matrix-org/go-neb/realms/jira/jira.go index 765f2a8..76005cf 100644 --- a/src/github.com/matrix-org/go-neb/realms/jira/jira.go +++ b/src/github.com/matrix-org/go-neb/realms/jira/jira.go @@ -52,6 +52,11 @@ func (s *JIRASession) Authenticated() bool { return s.AccessToken != "" && s.AccessSecret != "" } +// Info returns nothing +func (s *JIRASession) Info() interface{} { + return nil +} + // UserID returns the ID of the user performing the authentication. func (s *JIRASession) UserID() string { return s.userID diff --git a/src/github.com/matrix-org/go-neb/services/github/client/client.go b/src/github.com/matrix-org/go-neb/services/github/client/client.go new file mode 100644 index 0000000..2dcfb55 --- /dev/null +++ b/src/github.com/matrix-org/go-neb/services/github/client/client.go @@ -0,0 +1,51 @@ +package client + +import ( + "github.com/google/go-github/github" + "golang.org/x/oauth2" +) + +// TrimmedRepository represents a cut-down version of github.Repository with only the keys the end-user is +// likely to want. +type TrimmedRepository struct { + Name *string `json:"name"` + Description *string `json:"description"` + Private *bool `json:"private"` + HTMLURL *string `json:"html_url"` + CreatedAt *github.Timestamp `json:"created_at"` + UpdatedAt *github.Timestamp `json:"updated_at"` + PushedAt *github.Timestamp `json:"pushed_at"` + Fork *bool `json:"fork"` + FullName *string `json:"full_name"` + Permissions *map[string]bool `json:"permissions"` +} + +// TrimRepository trims a github repo into important fields only. +func TrimRepository(repo *github.Repository) TrimmedRepository { + return TrimmedRepository{ + Name: repo.Name, + Description: repo.Description, + Private: repo.Private, + HTMLURL: repo.HTMLURL, + CreatedAt: repo.CreatedAt, + UpdatedAt: repo.UpdatedAt, + PushedAt: repo.PushedAt, + Permissions: repo.Permissions, + Fork: repo.Fork, + FullName: repo.FullName, + } +} + +// New returns a github Client which can perform Github API operations. +// If `token` is empty, a non-authenticated client will be created. This should be +// used sparingly where possible as you only get 60 requests/hour like that (IP locked). +func New(token string) *github.Client { + var tokenSource oauth2.TokenSource + if token != "" { + tokenSource = oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: token}, + ) + } + httpCli := oauth2.NewClient(oauth2.NoContext, tokenSource) + return github.NewClient(httpCli) +} diff --git a/src/github.com/matrix-org/go-neb/services/github/github.go b/src/github.com/matrix-org/go-neb/services/github/github.go index e363c79..5b566ff 100644 --- a/src/github.com/matrix-org/go-neb/services/github/github.go +++ b/src/github.com/matrix-org/go-neb/services/github/github.go @@ -8,9 +8,9 @@ import ( "github.com/matrix-org/go-neb/matrix" "github.com/matrix-org/go-neb/plugin" "github.com/matrix-org/go-neb/realms/github" + "github.com/matrix-org/go-neb/services/github/client" "github.com/matrix-org/go-neb/services/github/webhook" "github.com/matrix-org/go-neb/types" - "golang.org/x/oauth2" "net/http" "regexp" "strconv" @@ -290,9 +290,9 @@ func (s *githubService) githubClientFor(userID string, allowUnauth bool) *github }).Print("Failed to get token for user") } if token != "" { - return githubClient(token) + return client.New(token) } else if allowUnauth { - return githubClient("") + return client.New("") } else { return nil } @@ -322,20 +322,6 @@ func getTokenForUser(realmID, userID string) (string, error) { return ghSession.AccessToken, nil } -// githubClient returns a github Client which can perform Github API operations. -// If `token` is empty, a non-authenticated client will be created. This should be -// used sparingly where possible as you only get 60 requests/hour like that (IP locked). -func githubClient(token string) *github.Client { - var tokenSource oauth2.TokenSource - if token != "" { - tokenSource = oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: token}, - ) - } - httpCli := oauth2.NewClient(oauth2.NoContext, tokenSource) - return github.NewClient(httpCli) -} - // ownerRepoNumberFromText parses a GH issue string that looks like 'owner/repo#11' // into its constituient parts. Returns: owner, repo, issue#. func ownerRepoNumberFromText(ownerRepoNumberText string) (string, string, int, error) { diff --git a/src/github.com/matrix-org/go-neb/types/types.go b/src/github.com/matrix-org/go-neb/types/types.go index 5e68cfe..9b7ef28 100644 --- a/src/github.com/matrix-org/go-neb/types/types.go +++ b/src/github.com/matrix-org/go-neb/types/types.go @@ -124,4 +124,5 @@ type AuthSession interface { UserID() string RealmID() string Authenticated() bool + Info() interface{} } From 0e9411e5593cadd5be3b2887c6f56c3a946b7f44 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Mon, 15 Aug 2016 15:39:15 +0100 Subject: [PATCH 2/2] s/Session/Info/ given it isn't an AuthSession object --- src/github.com/matrix-org/go-neb/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/github.com/matrix-org/go-neb/api.go b/src/github.com/matrix-org/go-neb/api.go index a6fc0c8..55a9599 100644 --- a/src/github.com/matrix-org/go-neb/api.go +++ b/src/github.com/matrix-org/go-neb/api.go @@ -295,6 +295,6 @@ func (h *getSessionHandler) OnIncomingRequest(req *http.Request) (interface{}, * return &struct { ID string Authenticated bool - Session interface{} + Info interface{} }{session.ID(), session.Authenticated(), session.Info()}, nil }