Browse Source

Pass in the webhook endpoint URL for each service

Get the base URL from an env var 'BASE_URL' and pass it through to CreateService.
kegan/webhook-endpoint-fn
Kegan Dougal 8 years ago
parent
commit
32ebe92535
  1. 1
      README.md
  2. 7
      src/github.com/matrix-org/go-neb/goneb.go
  3. 2
      src/github.com/matrix-org/go-neb/services/echo/echo.go
  4. 36
      src/github.com/matrix-org/go-neb/services/github/github.go
  5. 28
      src/github.com/matrix-org/go-neb/types/types.go

1
README.md

@ -130,7 +130,6 @@ curl -X POST localhost:4050/admin/configureService --data-binary '{
"RealmID": "mygithubrealm", "RealmID": "mygithubrealm",
"BotUserID": "@goneb:localhost", "BotUserID": "@goneb:localhost",
"ClientUserID": "@example:localhost", "ClientUserID": "@example:localhost",
"WebhookBaseURI": "https://public.path.to.neb",
"Rooms": { "Rooms": {
"!EmwxeXCVubhskuWvaw:localhost": { "!EmwxeXCVubhskuWvaw:localhost": {
"Repos": { "Repos": {

7
src/github.com/matrix-org/go-neb/goneb.go

@ -8,6 +8,7 @@ import (
"github.com/matrix-org/go-neb/server" "github.com/matrix-org/go-neb/server"
_ "github.com/matrix-org/go-neb/services/echo" _ "github.com/matrix-org/go-neb/services/echo"
_ "github.com/matrix-org/go-neb/services/github" _ "github.com/matrix-org/go-neb/services/github"
"github.com/matrix-org/go-neb/types"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
"net/http" "net/http"
_ "net/http/pprof" _ "net/http/pprof"
@ -18,6 +19,12 @@ func main() {
bindAddress := os.Getenv("BIND_ADDRESS") bindAddress := os.Getenv("BIND_ADDRESS")
databaseType := os.Getenv("DATABASE_TYPE") databaseType := os.Getenv("DATABASE_TYPE")
databaseURL := os.Getenv("DATABASE_URL") databaseURL := os.Getenv("DATABASE_URL")
baseURL := os.Getenv("BASE_URL")
err := types.BaseURL(baseURL)
if err != nil {
log.Panic(err)
}
db, err := database.Open(databaseType, databaseURL) db, err := database.Open(databaseType, databaseURL)
if err != nil { if err != nil {

2
src/github.com/matrix-org/go-neb/services/echo/echo.go

@ -37,7 +37,7 @@ func (e *echoService) OnReceiveWebhook(w http.ResponseWriter, req *http.Request,
} }
func init() { func init() {
types.RegisterService(func(serviceID string) types.Service {
types.RegisterService(func(serviceID, webhookEndpointURL string) types.Service {
return &echoService{id: serviceID} return &echoService{id: serviceID}
}) })
} }

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

@ -22,13 +22,13 @@ import (
var ownerRepoIssueRegex = regexp.MustCompile("([A-z0-9-_]+)/([A-z0-9-_]+)#([0-9]+)") var ownerRepoIssueRegex = regexp.MustCompile("([A-z0-9-_]+)/([A-z0-9-_]+)#([0-9]+)")
type githubService struct { type githubService struct {
id string
BotUserID string
ClientUserID string
RealmID string
SecretToken string
WebhookBaseURI string
Rooms map[string]struct { // room_id => {}
id string
webhookEndpointURL string
BotUserID string
ClientUserID string
RealmID string
SecretToken string
Rooms map[string]struct { // room_id => {}
Repos map[string]struct { // owner/repo => { events: ["push","issue","pull_request"] } Repos map[string]struct { // owner/repo => { events: ["push","issue","pull_request"] }
Events []string Events []string
} }
@ -183,7 +183,8 @@ func (s *githubService) Register() error {
// In order to register the GH service, you must have authed with GH. // In order to register the GH service, you must have authed with GH.
cli := s.githubClientFor(s.ClientUserID, false) cli := s.githubClientFor(s.ClientUserID, false)
if cli == nil { if cli == nil {
return fmt.Errorf("User %s does not have a Github auth session.", s.ClientUserID)
return fmt.Errorf(
"User %s does not have a Github auth session with realm %s.", s.ClientUserID, realm.ID())
} }
return nil return nil
@ -215,14 +216,6 @@ func (s *githubService) PostRegister(oldService types.Service) {
} }
func modifyWebhooks(s *githubService, cli *github.Client, removeHooks bool) { func modifyWebhooks(s *githubService, cli *github.Client, removeHooks bool) {
// TODO: This makes assumptions about how Go-NEB maps services to webhook endpoints.
// We should factor this out to a function called GetWebhookEndpoint(Service) or something.
trailingSlash := ""
if !strings.HasSuffix(s.WebhookBaseURI, "/") {
trailingSlash = "/"
}
webhookEndpointURL := s.WebhookBaseURI + trailingSlash + "services/hooks/" + s.id
ownerRepoSet := make(map[string]bool) ownerRepoSet := make(map[string]bool)
for _, roomCfg := range s.Rooms { for _, roomCfg := range s.Rooms {
for ownerRepo := range roomCfg.Repos { for ownerRepo := range roomCfg.Repos {
@ -244,13 +237,13 @@ func modifyWebhooks(s *githubService, cli *github.Client, removeHooks bool) {
"repo": repo, "repo": repo,
}) })
if removeHooks { if removeHooks {
removeHook(logger, cli, owner, repo, webhookEndpointURL)
removeHook(logger, cli, owner, repo, s.webhookEndpointURL)
} else { } else {
// make a hook for all GH events since we'll filter it when we receive webhook requests // make a hook for all GH events since we'll filter it when we receive webhook requests
name := "web" // https://developer.github.com/v3/repos/hooks/#create-a-hook name := "web" // https://developer.github.com/v3/repos/hooks/#create-a-hook
cfg := map[string]interface{}{ cfg := map[string]interface{}{
"content_type": "json", "content_type": "json",
"url": webhookEndpointURL,
"url": s.webhookEndpointURL,
} }
if s.SecretToken != "" { if s.SecretToken != "" {
cfg["secret"] = s.SecretToken cfg["secret"] = s.SecretToken
@ -375,7 +368,10 @@ func removeHook(logger *log.Entry, cli *github.Client, owner, repo, webhookEndpo
} }
func init() { func init() {
types.RegisterService(func(serviceID string) types.Service {
return &githubService{id: serviceID}
types.RegisterService(func(serviceID, webhookEndpointURL string) types.Service {
return &githubService{
id: serviceID,
webhookEndpointURL: webhookEndpointURL,
}
}) })
} }

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

@ -7,6 +7,7 @@ import (
"github.com/matrix-org/go-neb/plugin" "github.com/matrix-org/go-neb/plugin"
"net/http" "net/http"
"net/url" "net/url"
"strings"
) )
// A ClientConfig is the configuration for a matrix client for a bot to use. // A ClientConfig is the configuration for a matrix client for a bot to use.
@ -39,11 +40,29 @@ type Service interface {
PostRegister(oldService Service) PostRegister(oldService Service)
} }
var servicesByType = map[string]func(string) Service{}
var baseURL = ""
// BaseURL sets the base URL of NEB to the url given. This URL must be accessible from the
// public internet.
func BaseURL(u string) error {
if u == "" {
return errors.New("BASE_URL not found")
}
if !strings.HasPrefix(u, "http://") && !strings.HasPrefix(u, "https://") {
return errors.New("BASE_URL must start with http[s]://")
}
if !strings.HasSuffix(u, "/") {
u = u + "/"
}
baseURL = u
return nil
}
var servicesByType = map[string]func(string, string) Service{}
// RegisterService registers a factory for creating Service instances. // RegisterService registers a factory for creating Service instances.
func RegisterService(factory func(string) Service) {
servicesByType[factory("").ServiceType()] = factory
func RegisterService(factory func(string, string) Service) {
servicesByType[factory("", "").ServiceType()] = factory
} }
// CreateService creates a Service of the given type and serviceID. // CreateService creates a Service of the given type and serviceID.
@ -53,7 +72,8 @@ func CreateService(serviceID, serviceType string) Service {
if f == nil { if f == nil {
return nil return nil
} }
return f(serviceID)
webhookEndpointURL := baseURL + "services/hooks/" + serviceID
return f(serviceID, webhookEndpointURL)
} }
// AuthRealm represents a place where a user can authenticate themselves. // AuthRealm represents a place where a user can authenticate themselves.

Loading…
Cancel
Save