Browse Source

Grab access tokens from the GithubService and use them

Currently only an authenticated client is used to lookup expansion issues.
pull/11/head
Kegan Dougal 8 years ago
parent
commit
55fda3c115
  1. 2
      src/github.com/matrix-org/go-neb/api.go
  2. 28
      src/github.com/matrix-org/go-neb/realms/github/github.go
  3. 59
      src/github.com/matrix-org/go-neb/services/github/github.go

2
src/github.com/matrix-org/go-neb/api.go

@ -200,7 +200,7 @@ func (s *configureServiceHandler) OnIncomingRequest(req *http.Request) (interfac
err := service.Register()
if err != nil {
return nil, &errors.HTTPError{err, "Failed to register service", 500}
return nil, &errors.HTTPError{err, "Failed to register service: " + err.Error(), 500}
}
client, err := s.clients.Client(service.ServiceUserID())

28
src/github.com/matrix-org/go-neb/realms/github/github.go

@ -19,23 +19,29 @@ type githubRealm struct {
RedirectBaseURI string
}
type githubSession struct {
// GithubSession represents an authenticated github session
type GithubSession struct {
// AccessToken is the github access token for the user
AccessToken string
Scopes string
id string
userID string
realmID string
// Scopes are the set of *ALLOWED* scopes (which may not be the same as the requested scopes)
Scopes string
id string
userID string
realmID string
}
func (s *githubSession) UserID() string {
// UserID returns the user_id who authorised with Github
func (s *GithubSession) UserID() string {
return s.userID
}
func (s *githubSession) RealmID() string {
// RealmID returns the realm ID of the realm which performed the authentication
func (s *GithubSession) RealmID() string {
return s.realmID
}
func (s *githubSession) ID() string {
// ID returns the session ID
func (s *GithubSession) ID() string {
return s.id
}
@ -61,7 +67,7 @@ func (r *githubRealm) RequestAuthSession(userID string, req json.RawMessage) int
// TODO: Path is from goneb.go - we should probably factor it out.
q.Set("redirect_uri", r.RedirectBaseURI+"/realms/redirects/"+r.ID())
u.RawQuery = q.Encode()
session := &githubSession{
session := &GithubSession{
id: state, // key off the state for redirects
userID: userID,
realmID: r.ID(),
@ -96,7 +102,7 @@ func (r *githubRealm) OnReceiveRedirect(w http.ResponseWriter, req *http.Request
failWith(logger, w, 400, "Provided ?state= param is not recognised.", err)
return
}
ghSession, ok := session.(*githubSession)
ghSession, ok := session.(*GithubSession)
if !ok {
failWith(logger, w, 500, "Unexpected session found.", nil)
return
@ -136,7 +142,7 @@ func (r *githubRealm) OnReceiveRedirect(w http.ResponseWriter, req *http.Request
}
func (r *githubRealm) AuthSession(id, userID, realmID string) types.AuthSession {
return &githubSession{
return &GithubSession{
id: id,
userID: userID,
realmID: realmID,

59
src/github.com/matrix-org/go-neb/services/github/github.go

@ -4,8 +4,10 @@ import (
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/google/go-github/github"
"github.com/matrix-org/go-neb/database"
"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/webhook"
"github.com/matrix-org/go-neb/types"
"golang.org/x/oauth2"
@ -23,6 +25,7 @@ type githubService struct {
id string
BotUserID string
GithubUserID string
RealmID string
WebhookRooms map[string][]string // room_id => ["push","issue","pull_request"]
}
@ -42,7 +45,7 @@ func (s *githubService) Plugin(roomID string) plugin.Plugin {
plugin.Command{
Path: []string{"github", "create"},
Command: func(roomID, userID string, args []string) (interface{}, error) {
cli := githubClientFor(userID, false)
cli := s.githubClientFor(userID, false)
if cli == nil {
// TODO: send starter link
return &matrix.TextMessage{"m.notice",
@ -56,7 +59,7 @@ func (s *githubService) Plugin(roomID string) plugin.Plugin {
plugin.Expansion{
Regexp: ownerRepoIssueRegex,
Expand: func(roomID, userID, matchingText string) interface{} {
cli := githubClientFor(userID, true)
cli := s.githubClientFor(userID, true)
owner, repo, num, err := ownerRepoNumberFromText(matchingText)
if err != nil {
log.WithError(err).WithField("text", matchingText).Print(
@ -115,18 +118,58 @@ func (s *githubService) OnReceiveWebhook(w http.ResponseWriter, req *http.Reques
w.WriteHeader(200)
}
func (s *githubService) Register() error {
if s.RealmID == "" || s.BotUserID == "" {
return fmt.Errorf("RealmID and BotUserID are required")
}
// check realm exists
realm, err := database.GetServiceDB().LoadAuthRealm(s.RealmID)
if err != nil {
return err
}
// make sure the realm is of the type we expect
if realm.Type() != "github" {
return fmt.Errorf("Realm is of type '%s', not 'github'", realm.Type())
}
return nil
}
func githubClientFor(userID string, allowUnauth bool) *github.Client {
var cli *github.Client
func (s *githubService) githubClientFor(userID string, allowUnauth bool) *github.Client {
token, err := getTokenForUser(s.RealmID, userID)
if err != nil {
log.WithFields(log.Fields{
log.ErrorKey: err,
"user_id": userID,
"realm_id": s.RealmID,
}).Print("Failed to get token for user")
}
if token != "" {
return githubClient(token)
} else if allowUnauth {
return githubClient("")
} else {
return nil
}
}
// TODO get the token for this user
func getTokenForUser(realmID, userID string) (string, error) {
realm, err := database.GetServiceDB().LoadAuthRealm(realmID)
if err != nil {
return "", err
}
if realm.Type() != "github" {
return "", fmt.Errorf("Bad realm type: %s", realm.Type())
}
if cli == nil && allowUnauth {
return githubClient("")
// pull out the token (TODO: should the service know how the realm stores this?)
session, err := database.GetServiceDB().LoadAuthSessionByUser(realm.ID(), userID)
if err != nil {
return "", err
}
ghSession, ok := session.(*realms.GithubSession)
if !ok {
return "", fmt.Errorf("Session is not a github session: %s", session.ID())
}
return cli
return ghSession.AccessToken, nil
}
// githubClient returns a github Client which can perform Github API operations.

Loading…
Cancel
Save