|
@ -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} |
|
|