Browse Source

Add redirect handler for AuthRealms

Add state param generation for githubRealm.
kegan/github-auth
Kegan Dougal 9 years ago
parent
commit
036cd7e7b4
  1. 17
      src/github.com/matrix-org/go-neb/api.go
  2. 2
      src/github.com/matrix-org/go-neb/goneb.go
  3. 32
      src/github.com/matrix-org/go-neb/realms/github/github.go
  4. 1
      src/github.com/matrix-org/go-neb/types/types.go

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

@ -51,6 +51,23 @@ func (h *requestAuthSessionHandler) OnIncomingRequest(req *http.Request) (interf
return response, nil return response, nil
} }
type realmRedirectHandler struct {
db *database.ServiceDB
}
func (rh *realmRedirectHandler) handle(w http.ResponseWriter, req *http.Request) {
segments := strings.Split(req.URL.Path, "/")
// last path segment is the realm ID which we will pass the incoming request to
realmID := segments[len(segments)-1]
realm, err := rh.db.LoadAuthRealm(realmID)
if err != nil {
log.WithError(err).WithField("realm_id", realmID).Print("Failed to load realm")
w.WriteHeader(404)
return
}
realm.OnReceiveRedirect(w, req)
}
type configureAuthRealmHandler struct { type configureAuthRealmHandler struct {
db *database.ServiceDB db *database.ServiceDB
} }

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

@ -37,6 +37,8 @@ func main() {
http.Handle("/admin/requestAuthSession", server.MakeJSONAPI(&requestAuthSessionHandler{db: db})) http.Handle("/admin/requestAuthSession", server.MakeJSONAPI(&requestAuthSessionHandler{db: db}))
wh := &webhookHandler{db: db, clients: clients} wh := &webhookHandler{db: db, clients: clients}
http.HandleFunc("/services/hooks/", wh.handle) http.HandleFunc("/services/hooks/", wh.handle)
rh := &realmRedirectHandler{db: db}
http.HandleFunc("/realms/redirects/", rh.handle)
http.ListenAndServe(bindAddress, nil) http.ListenAndServe(bindAddress, nil)
} }

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

@ -1,10 +1,13 @@
package realms package realms
import ( import (
"crypto/rand"
"encoding/hex"
"encoding/json" "encoding/json"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/matrix-org/go-neb/database" "github.com/matrix-org/go-neb/database"
"github.com/matrix-org/go-neb/types" "github.com/matrix-org/go-neb/types"
"net/http"
"net/url" "net/url"
) )
@ -12,7 +15,7 @@ type githubRealm struct {
id string id string
ClientSecret string ClientSecret string
ClientID string ClientID string
WebhookEndpoint string
RedirectBaseURI string
} }
type githubSession struct { type githubSession struct {
@ -38,18 +41,25 @@ func (r *githubRealm) Type() string {
} }
func (r *githubRealm) RequestAuthSession(userID string, req json.RawMessage) interface{} { func (r *githubRealm) RequestAuthSession(userID string, req json.RawMessage) interface{} {
state, err := randomString(10)
if err != nil {
log.WithError(err).Print("Failed to generate state param")
return nil
}
u, _ := url.Parse("https://github.com/login/oauth/authorize") u, _ := url.Parse("https://github.com/login/oauth/authorize")
q := u.Query() q := u.Query()
q.Set("client_id", r.ClientID) q.Set("client_id", r.ClientID)
q.Set("client_secret", r.ClientSecret) q.Set("client_secret", r.ClientSecret)
// TODO: state, scope
q.Set("state", state)
// 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() u.RawQuery = q.Encode()
session := &githubSession{ session := &githubSession{
State: "TODO",
State: state,
userID: userID, userID: userID,
realmID: r.ID(), realmID: r.ID(),
} }
_, err := database.GetServiceDB().StoreAuthSession(session)
_, err = database.GetServiceDB().StoreAuthSession(session)
if err != nil { if err != nil {
log.WithError(err).Print("Failed to store new auth session") log.WithError(err).Print("Failed to store new auth session")
return nil return nil
@ -60,6 +70,9 @@ func (r *githubRealm) RequestAuthSession(userID string, req json.RawMessage) int
}{u.String()} }{u.String()}
} }
func (r *githubRealm) OnReceiveRedirect(w http.ResponseWriter, req *http.Request) {
}
func (r *githubRealm) AuthSession(userID, realmID string) types.AuthSession { func (r *githubRealm) AuthSession(userID, realmID string) types.AuthSession {
return &githubSession{ return &githubSession{
userID: userID, userID: userID,
@ -67,6 +80,17 @@ func (r *githubRealm) AuthSession(userID, realmID string) types.AuthSession {
} }
} }
// Generate a cryptographically secure pseudorandom string with the given number of bytes (length).
// Returns a hex string of the bytes.
func randomString(length int) (string, error) {
b := make([]byte, length)
_, err := rand.Read(b)
if err != nil {
return "", err
}
return hex.EncodeToString(b), nil
}
func init() { func init() {
types.RegisterAuthRealm(func(realmID string) types.AuthRealm { types.RegisterAuthRealm(func(realmID string) types.AuthRealm {
return &githubRealm{id: realmID} return &githubRealm{id: realmID}

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

@ -59,6 +59,7 @@ func CreateService(serviceID, serviceType string) Service {
type AuthRealm interface { type AuthRealm interface {
ID() string ID() string
Type() string Type() string
OnReceiveRedirect(w http.ResponseWriter, req *http.Request)
AuthSession(userID, realmID string) AuthSession AuthSession(userID, realmID string) AuthSession
RequestAuthSession(userID string, config json.RawMessage) interface{} RequestAuthSession(userID string, config json.RawMessage) interface{}
} }

Loading…
Cancel
Save