Permalink
Browse files

pass the user model through, unify tests

  • Loading branch information...
rybit committed Oct 18, 2017
1 parent 6cd5ef3 commit 10c8fe8711e2a2ad18ce9176125b64bcf5a434a2
Showing with 71 additions and 71 deletions.
  1. +10 −45 api/hook_test.go
  2. +10 −5 api/hooks.go
  3. +5 −4 api/signup.go
  4. +44 −15 api/signup_test.go
  5. +2 −2 models/user.go
View
@@ -8,71 +8,36 @@ import (
"testing"
"time"
jwt "github.com/dgrijalva/jwt-go"
"github.com/netlify/gotrue/conf"
"github.com/netlify/gotrue/models"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSignupHook(t *testing.T) {
func TestSignupHookSendInstanceID(t *testing.T) {
user, err := models.NewUser("myinstance", "test@truth.com", "thisisapassword", "", nil)
require.NoError(t, err)
var callCount int
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
callCount++
assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
assert.Equal(t, "", r.Header.Get("x-gotrue-signature"))
defer squash(r.Body.Close)
raw, err := ioutil.ReadAll(r.Body)
require.NoError(t, err)
data := map[string]string{}
data := map[string]interface{}{}
require.NoError(t, json.Unmarshal(raw, &data))
assert.Equal(t, "myinstance", data["instance_id"])
assert.Equal(t, "test@truth.com", data["email"])
assert.Equal(t, "someone", data["provider"])
assert.Len(t, data, 3)
assert.Equal(t, "myinstance", data["instance_id"])
w.WriteHeader(http.StatusOK)
}))
defer svr.Close()
params := &SignupParams{
Email: "test@truth.com",
Provider: "someone",
}
config := &conf.WebhookConfig{
URL: svr.URL,
}
require.NoError(t, triggerSignupHook(params, "myinstance", "", config))
assert.Equal(t, 1, callCount)
}
func TestSignupHookJWTSignature(t *testing.T) {
var callCount int
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
callCount++
signature := r.Header.Get("x-gotrue-signature")
p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}}
claims := new(jwt.StandardClaims)
token, err := p.ParseWithClaims(signature, claims, func(token *jwt.Token) (interface{}, error) {
return []byte("somesecret"), nil
})
require.NoError(t, err)
assert.True(t, token.Valid)
assert.Equal(t, "myinstance", claims.Subject)
assert.WithinDuration(t, time.Now(), time.Unix(claims.IssuedAt, 0), 5*time.Second)
w.WriteHeader(http.StatusOK)
}))
defer svr.Close()
params := &SignupParams{
Email: "test@truth.com",
Provider: "someone",
}
config := &conf.WebhookConfig{
URL: svr.URL,
}
require.NoError(t, triggerSignupHook(params, "myinstance", "somesecret", config))
require.NoError(t, triggerSignupHook(user, "myinstance", "", config))
assert.Equal(t, 1, callCount)
}
View
@@ -12,6 +12,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/netlify/gotrue/conf"
"github.com/netlify/gotrue/models"
)
const (
@@ -115,16 +116,20 @@ func (w *Webhook) generateSignature() (string, error) {
return tokenString, nil
}
func triggerSignupHook(params *SignupParams, instanceID, jwtSecret string, hconfig *conf.WebhookConfig) error {
func triggerSignupHook(user *models.User, instanceID, jwtSecret string, hconfig *conf.WebhookConfig) error {
if hconfig.URL == "" {
return nil
}
payload := struct {
Email string `json:"email"`
InstanceID string `json:"instance_id"`
Provider string `json:"provider"`
}{Email: params.Email, InstanceID: instanceID, Provider: params.Provider}
Event string `json:"event"`
InstanceID string `json:"instance_id,omitempty"`
User *models.User `json:"user"`
}{
Event: "signup",
InstanceID: instanceID,
User: user,
}
data, err := json.Marshal(&payload)
if err != nil {
return internalServerError("Failed to serialize the data for signup webhook").WithInternalError(err)
View
@@ -84,10 +84,6 @@ func (a *API) signupNewUser(ctx context.Context, params *SignupParams, aud strin
instanceID := getInstanceID(ctx)
config := a.getConfig(ctx)
if err := triggerSignupHook(params, instanceID, config.JWT.Secret, &config.SignupHook); err != nil {
return nil, err
}
user, err := models.NewUser(instanceID, params.Email, params.Password, aud, params.Data)
if err != nil {
return nil, internalServerError("Database error creating user").WithInternalError(err)
@@ -102,6 +98,11 @@ func (a *API) signupNewUser(ctx context.Context, params *SignupParams, aud strin
}
user.SetRole(config.JWT.DefaultGroupName)
if err := triggerSignupHook(user, instanceID, config.JWT.Secret, &config.SignupHook); err != nil {
return nil, err
}
if err := a.db.CreateUser(user); err != nil {
return nil, internalServerError("Database error saving new user").WithInternalError(err)
}
View
@@ -79,9 +79,12 @@ func (ts *SignupTestSuite) TestSignup() {
func (ts *SignupTestSuite) TestWebhookTriggered() {
var callCount int
require := ts.Require()
assert := ts.Assert()
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
callCount++
assert.Equal(ts.T(), "application/json", r.Header.Get("Content-Type"))
assert.Equal("application/json", r.Header.Get("Content-Type"))
// verify the signature
signature := r.Header.Get("x-gotrue-signature")
@@ -90,21 +93,47 @@ func (ts *SignupTestSuite) TestWebhookTriggered() {
token, err := p.ParseWithClaims(signature, claims, func(token *jwt.Token) (interface{}, error) {
return []byte(ts.Config.JWT.Secret), nil
})
assert.True(ts.T(), token.Valid)
assert.Equal(ts.T(), "", claims.Subject) // not configured for multitenancy
assert.Equal(ts.T(), "gotrue", claims.Issuer)
assert.WithinDuration(ts.T(), time.Now(), time.Unix(claims.IssuedAt, 0), 5*time.Second)
assert.True(token.Valid)
assert.Equal("", claims.Subject) // not configured for multitenancy
assert.Equal("gotrue", claims.Issuer)
assert.WithinDuration(time.Now(), time.Unix(claims.IssuedAt, 0), 5*time.Second)
// verify the contents
defer squash(r.Body.Close)
raw, err := ioutil.ReadAll(r.Body)
require.NoError(ts.T(), err)
data := map[string]string{}
require.NoError(ts.T(), json.Unmarshal(raw, &data))
assert.Equal(ts.T(), "", data["instance_id"]) // not configured for multitenancy
assert.Equal(ts.T(), "test@example.com", data["email"])
assert.Equal(ts.T(), "email", data["provider"])
require.NoError(err)
data := map[string]interface{}{}
require.NoError(json.Unmarshal(raw, &data))
assert.Equal(2, len(data))
assert.Equal("signup", data["event"])
u, ok := data["user"].(map[string]interface{})
require.True(ok)
assert.Len(u, 8)
// assert.Equal(t, user.ID, u["id"]) TODO
assert.Equal("api.netlify.com", u["aud"])
assert.Equal("", u["role"])
assert.Equal("test@example.com", u["email"])
appmeta, ok := u["app_metadata"].(map[string]interface{})
require.True(ok)
assert.Len(appmeta, 1)
assert.EqualValues("email", appmeta["provider"])
usermeta, ok := u["user_metadata"].(map[string]interface{})
require.True(ok)
assert.Len(usermeta, 1)
assert.EqualValues(1, usermeta["a"])
created, err := time.Parse(time.RFC3339Nano, u["created_at"].(string))
assert.NoError(err)
assert.True(created.IsZero())
updated, err := time.Parse(time.RFC3339Nano, u["created_at"].(string))
assert.NoError(err)
assert.True(updated.IsZero())
w.WriteHeader(http.StatusOK)
}))
defer svr.Close()
@@ -114,7 +143,7 @@ func (ts *SignupTestSuite) TestWebhookTriggered() {
TimeoutSec: 1,
}
var buffer bytes.Buffer
require.NoError(ts.T(), json.NewEncoder(&buffer).Encode(map[string]interface{}{
require.NoError(json.NewEncoder(&buffer).Encode(map[string]interface{}{
"email": "test@example.com",
"password": "test",
"data": map[string]interface{}{
@@ -126,8 +155,8 @@ func (ts *SignupTestSuite) TestWebhookTriggered() {
w := httptest.NewRecorder()
ts.API.handler.ServeHTTP(w, req)
assert.Equal(ts.T(), http.StatusOK, w.Code)
assert.Equal(ts.T(), 1, callCount)
assert.Equal(http.StatusOK, w.Code)
assert.Equal(1, callCount)
}
func (ts *SignupTestSuite) TestFailingWebhook() {
View
@@ -23,8 +23,8 @@ type User struct {
Role string `json:"role"`
Email string `json:"email"`
EncryptedPassword string `json:"-"`
ConfirmedAt *time.Time `json:"confirmed_at"`
InvitedAt *time.Time `json:"invited_at"`
ConfirmedAt *time.Time `json:"confirmed_at,omitempty"`
InvitedAt *time.Time `json:"invited_at,omitempty"`
ConfirmationToken string `json:"-"`
ConfirmationSentAt *time.Time `json:"confirmation_sent_at,omitempty"`

0 comments on commit 10c8fe8

Please sign in to comment.