Permalink
Browse files

Replace gorm with pop for db access

Change model IDs to UUIDs
Remove `deleted_at` from instances model
  • Loading branch information...
brycekahle committed Jan 8, 2018
1 parent 1031987 commit 47cc9ce137a24c96985ee3e742b0f0adfb6f146c
View
@@ -1,5 +1,4 @@
.env
gorm.db
vendor/
gotrue
View
@@ -27,7 +27,7 @@ migrate_test: ## Run database migrations for test.
hack/migrate.sh test
test: ## Run tests.
go test -v $(CHECK_FILES)
go test -p 1 -v $(CHECK_FILES)
vet: # Vet the code
go vet $(CHECK_FILES)
View
@@ -58,20 +58,16 @@ DATABASE_URL=root@localhost/gotrue
`DB_DRIVER` - `string` **required**
Chooses what dialect of database you want. Choose from `mysql` or `postgres`.
Chooses what dialect of database you want. Must be `mysql`.
`DATABASE_URL` (no prefix) / `DB_DATABASE_URL` - `string` **required**
Connection string for the database. See the [gorm examples](https://github.com/jinzhu/gorm/blob/gh-pages/documents/database.md) for more details.
Connection string for the database.
`DB_NAMESPACE` - `string`
Adds a prefix to all table names.
`DB_AUTOMIGRATE` - `bool`
If enabled, creates missing tables and columns upon startup.
### Logging
```
View
@@ -7,6 +7,7 @@ import (
"github.com/go-chi/chi"
"github.com/netlify/gotrue/models"
uuid "github.com/satori/go.uuid"
)
type adminUserParams struct {
@@ -20,7 +21,11 @@ type adminUserParams struct {
}
func (a *API) loadUser(w http.ResponseWriter, r *http.Request) (context.Context, error) {
userID := chi.URLParam(r, "user_id")
userID, err := uuid.FromString(chi.URLParam(r, "user_id"))
if err != nil {
return nil, badRequestError("user_id must be an UUID")
}
logEntrySetField(r, "user_id", userID)
instanceID := getInstanceID(r.Context())
View
@@ -12,7 +12,7 @@ import (
jwt "github.com/dgrijalva/jwt-go"
"github.com/netlify/gotrue/conf"
"github.com/netlify/gotrue/models"
"github.com/netlify/gotrue/storage/test"
uuid "github.com/satori/go.uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
@@ -25,7 +25,7 @@ type AdminTestSuite struct {
Config *conf.Configuration
token string
instanceID string
instanceID uuid.UUID
}
func TestAdmin(t *testing.T) {
@@ -37,12 +37,14 @@ func TestAdmin(t *testing.T) {
Config: config,
instanceID: instanceID,
}
defer api.db.Close()
//defer api.db.DropDB()
suite.Run(t, ts)
}
func (ts *AdminTestSuite) SetupTest() {
test.CleanupTables()
ts.API.db.TruncateAll()
ts.token = ts.makeSuperAdmin("test@example.com")
}
@@ -70,7 +72,7 @@ func (ts *AdminTestSuite) makeSuperAdmin(email string) string {
}
func (ts *AdminTestSuite) makeSystemUser() string {
u := models.NewSystemUser("", ts.Config.JWT.Aud)
u := models.NewSystemUser(uuid.Nil, ts.Config.JWT.Aud)
token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret)
require.NoError(ts.T(), err, "Error generating access token")
@@ -107,6 +109,7 @@ func (ts *AdminTestSuite) TestAdminUsers() {
assert.Equal(ts.T(), "</admin/users?page=1>; rel=\"last\"", w.HeaderMap.Get("Link"))
assert.Equal(ts.T(), "1", w.HeaderMap.Get("X-Total-Count"))
fmt.Println(w.Body)
data := struct {
Users []*models.User `json:"users"`
Aud string `json:"aud"`
@@ -153,6 +156,8 @@ func (ts *AdminTestSuite) TestAdminUsers_SortAsc() {
u, err := models.NewUser(ts.instanceID, "test1@example.com", "test", ts.Config.JWT.Aud, nil)
require.NoError(ts.T(), err, "Error making new user")
// if the created_at times are the same, then the sort order is not guaranteed
time.Sleep(1 * time.Second)
require.NoError(ts.T(), ts.API.db.CreateUser(u), "Error creating user")
// Setup request
@@ -182,6 +187,8 @@ func (ts *AdminTestSuite) TestAdminUsers_SortAsc() {
func (ts *AdminTestSuite) TestAdminUsers_SortDesc() {
u, err := models.NewUser(ts.instanceID, "test1@example.com", "test", ts.Config.JWT.Aud, nil)
require.NoError(ts.T(), err, "Error making new user")
// if the created_at times are the same, then the sort order is not guaranteed
time.Sleep(1 * time.Second)
require.NoError(ts.T(), ts.API.db.CreateUser(u), "Error creating user")
// Setup request
@@ -279,7 +286,7 @@ func (ts *AdminTestSuite) TestAdminUserCreate() {
// TestAdminUserGet tests API /admin/user route (GET)
func (ts *AdminTestSuite) TestAdminUserGet() {
u, err := models.NewUser(ts.instanceID, "test1@example.com", "test", ts.Config.JWT.Aud, nil)
u, err := models.NewUser(ts.instanceID, "test1@example.com", "test", ts.Config.JWT.Aud, map[string]interface{}{"full_name": "Test Get User"})
require.NoError(ts.T(), err, "Error making new user")
require.NoError(ts.T(), ts.API.db.CreateUser(u), "Error creating user")
@@ -298,6 +305,8 @@ func (ts *AdminTestSuite) TestAdminUserGet() {
assert.Equal(ts.T(), data["email"], "test1@example.com")
assert.NotNil(ts.T(), data["app_metadata"])
assert.NotNil(ts.T(), data["user_metadata"])
md := data["user_metadata"].(map[string]interface{})
assert.Equal(ts.T(), "Test Get User", md["full_name"])
}
// TestAdminUserUpdate tests API /admin/user route (UPDATE)
View
@@ -13,6 +13,7 @@ import (
"github.com/netlify/gotrue/storage/dial"
"github.com/netlify/netlify-commons/graceful"
"github.com/rs/cors"
uuid "github.com/satori/go.uuid"
"github.com/sebest/xff"
"github.com/sirupsen/logrus"
)
@@ -155,7 +156,7 @@ func NewAPIFromConfigFile(filename string, version string) (*API, *conf.Configur
return nil, nil, err
}
ctx, err := WithInstanceConfig(context.Background(), globalConfig.SMTP, config, "")
ctx, err := WithInstanceConfig(context.Background(), globalConfig.SMTP, config, uuid.Nil)
if err != nil {
logrus.Fatalf("Error loading instance config: %+v", err)
}
@@ -176,7 +177,7 @@ func (a *API) HealthCheck(w http.ResponseWriter, r *http.Request) error {
})
}
func WithInstanceConfig(ctx context.Context, smtp conf.SMTPConfiguration, config *conf.Configuration, instanceID string) (context.Context, error) {
func WithInstanceConfig(ctx context.Context, smtp conf.SMTPConfiguration, config *conf.Configuration, instanceID uuid.UUID) (context.Context, error) {
ctx = withConfig(ctx, config)
mailer := mailer.NewMailer(smtp, config)
View
@@ -2,19 +2,25 @@ package api
import (
"context"
"math/rand"
"time"
"github.com/netlify/gotrue/conf"
"github.com/netlify/gotrue/models"
"github.com/netlify/gotrue/storage"
"github.com/netlify/gotrue/storage/test"
"github.com/pborman/uuid"
"github.com/satori/go.uuid"
)
const (
apiTestVersion = "1"
apiTestConfig = "../hack/test.env"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
// setupAPIForTest creates a new API to run tests with.
// Using this function allows us to keep track of the database connection
// and cleaning up data between tests.
@@ -23,17 +29,17 @@ func setupAPIForTest() (*API, *conf.Configuration, error) {
}
func setupAPIForMultiinstanceTest() (*API, *conf.Configuration, error) {
cb := func(gc *conf.GlobalConfiguration, c *conf.Configuration, conn storage.Connection) (string, error) {
cb := func(gc *conf.GlobalConfiguration, c *conf.Configuration, conn storage.Connection) (uuid.UUID, error) {
gc.MultiInstanceMode = true
return "", nil
return uuid.Nil, nil
}
return setupAPIForTestWithCallback(cb)
}
func setupAPIForTestForInstance() (*API, *conf.Configuration, string, error) {
instanceID := uuid.NewRandom().String()
cb := func(gc *conf.GlobalConfiguration, c *conf.Configuration, conn storage.Connection) (string, error) {
func setupAPIForTestForInstance() (*API, *conf.Configuration, uuid.UUID, error) {
instanceID := uuid.Must(uuid.NewV4())
cb := func(gc *conf.GlobalConfiguration, c *conf.Configuration, conn storage.Connection) (uuid.UUID, error) {
err := conn.CreateInstance(&models.Instance{
ID: instanceID,
UUID: testUUID,
@@ -44,34 +50,65 @@ func setupAPIForTestForInstance() (*API, *conf.Configuration, string, error) {
api, conf, err := setupAPIForTestWithCallback(cb)
if err != nil {
return nil, nil, "", err
return nil, nil, uuid.Nil, err
}
return api, conf, instanceID, nil
}
func setupAPIForTestWithCallback(cb func(*conf.GlobalConfiguration, *conf.Configuration, storage.Connection) (string, error)) (*API, *conf.Configuration, error) {
globalConfig, conn, err := test.SetupDBConnection()
func setupAPIForTestWithCallback(cb func(*conf.GlobalConfiguration, *conf.Configuration, storage.Connection) (uuid.UUID, error)) (*API, *conf.Configuration, error) {
globalConfig, err := conf.LoadGlobal(apiTestConfig)
if err != nil {
return nil, nil, err
}
// TODO disable serial tests and re-enable automigrate and uncomment
// this code once `pop` migrations are fixed
//
// dbname := fmt.Sprintf("gotrue_test_%s", randStringBytes(10))
// globalConfig.DB.URL, err = test.CreateTestDB(dbname, globalConfig)
// if err != nil {
// return nil, nil, err
// }
conn, err := test.SetupDBConnection(globalConfig)
if err != nil {
//test.DeleteTestDB(globalConfig)
return nil, nil, err
}
config, err := conf.LoadConfig(apiTestConfig)
if err != nil {
conn.Close()
//test.DeleteTestDB(globalConfig)
return nil, nil, err
}
instanceID := ""
instanceID := uuid.Nil
if cb != nil {
instanceID, err = cb(globalConfig, config, conn)
if err != nil {
conn.Close()
//test.DeleteTestDB(globalConfig)
return nil, nil, err
}
}
ctx, err := WithInstanceConfig(context.Background(), globalConfig.SMTP, config, instanceID)
if err != nil {
conn.Close()
//test.DeleteTestDB(globalConfig)
return nil, nil, err
}
return NewAPIWithVersion(ctx, globalConfig, conn, apiTestVersion), config, nil
}
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func randStringBytes(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))]
}
return string(b)
}
View
@@ -27,7 +27,7 @@ func (a *API) requireAdmin(ctx context.Context, w http.ResponseWriter, r *http.R
// Find the administrative user
adminUser, err := getUserFromClaims(ctx, a.db)
if err != nil {
return nil, unauthorizedError("Invalid admin user")
return nil, unauthorizedError("Invalid admin user").WithInternalError(err)
}
aud := a.requestAud(ctx, r)
View
@@ -7,6 +7,7 @@ import (
"github.com/netlify/gotrue/conf"
"github.com/netlify/gotrue/mailer"
"github.com/netlify/gotrue/models"
uuid "github.com/satori/go.uuid"
)
type contextKey string
@@ -96,17 +97,17 @@ func getMailer(ctx context.Context) mailer.Mailer {
}
// withInstanceID adds the instance id to the context.
func withInstanceID(ctx context.Context, id string) context.Context {
func withInstanceID(ctx context.Context, id uuid.UUID) context.Context {
return context.WithValue(ctx, instanceIDKey, id)
}
// getInstanceID reads the instance id from the context.
func getInstanceID(ctx context.Context) string {
func getInstanceID(ctx context.Context) uuid.UUID {
obj := ctx.Value(instanceIDKey)
if obj == nil {
return ""
return uuid.Nil
}
return obj.(string)
return obj.(uuid.UUID)
}
// withInstance adds the instance id to the context.
View
@@ -68,7 +68,7 @@ func (a *API) ExternalProviderRedirect(w http.ResponseWriter, r *http.Request) e
ExpiresAt: time.Now().Add(5 * time.Minute).Unix(),
},
SiteURL: config.SiteURL,
InstanceID: getInstanceID(ctx),
InstanceID: getInstanceID(ctx).String(),
NetlifyID: getNetlifyID(ctx),
},
Provider: providerType,
View
@@ -9,7 +9,7 @@ import (
jwt "github.com/dgrijalva/jwt-go"
"github.com/netlify/gotrue/conf"
"github.com/netlify/gotrue/storage/test"
uuid "github.com/satori/go.uuid"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
@@ -18,7 +18,7 @@ type ExternalTestSuite struct {
suite.Suite
API *API
Config *conf.Configuration
instanceID string
instanceID uuid.UUID
}
func TestExternal(t *testing.T) {
@@ -30,12 +30,14 @@ func TestExternal(t *testing.T) {
Config: config,
instanceID: instanceID,
}
defer api.db.Close()
//defer api.db.DropDB()
suite.Run(t, ts)
}
func (ts *ExternalTestSuite) SetupTest() {
test.CleanupTables()
ts.API.db.TruncateAll()
}
// TestSignupExternalUnsupported tests API /authorize for an unsupported external provider
Oops, something went wrong.

0 comments on commit 47cc9ce

Please sign in to comment.