diff --git a/.docker/Dockerfile-build b/.docker/Dockerfile-build index f425790d3..179adff0f 100644 --- a/.docker/Dockerfile-build +++ b/.docker/Dockerfile-build @@ -10,6 +10,9 @@ ADD go.sum go.sum ADD proto/go.mod proto/go.mod ADD proto/go.sum proto/go.sum +ADD internal/httpclient-next/go.mod internal/httpclient-next/go.mod +ADD internal/httpclient-next/go.sum internal/httpclient-next/go.sum + ENV CGO_ENABLED 1 RUN go mod download diff --git a/go.mod b/go.mod index 214d40c19..e45cf7ad5 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ replace ( github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.14.10 github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1 + github.com/ory/keto/internal/httpclient-next => ./internal/httpclient-next github.com/ory/keto/proto => ./proto github.com/soheilhy/cmux => github.com/soheilhy/cmux v0.1.5-0.20210114230657-cdd3331e3e7c ) @@ -27,6 +28,7 @@ require ( github.com/ory/graceful v0.1.3 github.com/ory/herodot v0.9.13 github.com/ory/jsonschema/v3 v3.0.7 + github.com/ory/keto/internal/httpclient-next v0.0.0-00010101000000-000000000000 github.com/ory/keto/proto v0.0.0-00010101000000-000000000000 github.com/ory/x v0.0.463 github.com/pelletier/go-toml v1.9.5 diff --git a/internal/e2e/cases_test.go b/internal/e2e/cases_test.go index 1f46a7267..ff23a0c3b 100644 --- a/internal/e2e/cases_test.go +++ b/internal/e2e/cases_test.go @@ -49,6 +49,36 @@ func runCases(c client, m *namespaceTestManager) func(*testing.T) { assert.True(t, c.check(t, tuple)) }) + t.Run("case=creates tuple with empty IDs", func(t *testing.T) { + n := &namespace.Namespace{Name: t.Name()} + m.add(t, n) + + tuples := []*ketoapi.RelationTuple{{ + Namespace: n.Name, + Object: "", + Relation: "access", + SubjectID: x.Ptr(""), + }, { + Namespace: n.Name, + Object: "", + Relation: "access", + SubjectSet: &ketoapi.SubjectSet{ + Namespace: n.Name, + Object: "", + Relation: "access", + }, + }} + + for _, tp := range tuples { + c.createTuple(t, tp) + // try the check API to see whether the tuple is interpreted correctly + assert.True(t, c.check(t, tp)) + } + + resp := c.queryTuple(t, &ketoapi.RelationQuery{Namespace: &n.Name}) + assert.ElementsMatch(t, tuples, resp.RelationTuples) + }) + t.Run("case=check subjectSet relations", func(t *testing.T) { n := &namespace.Namespace{Name: t.Name()} m.add(t, n) @@ -216,7 +246,7 @@ func runCases(c client, m *namespaceTestManager) func(*testing.T) { c.deleteAllTuples(t, q) resp = c.queryTuple(t, q) - assert.Equal(t, len(resp.RelationTuples), 0) + assert.Equal(t, 0, len(resp.RelationTuples)) }) t.Run("case=returns error with status code on unknown namespace", func(t *testing.T) { diff --git a/internal/e2e/full_suit_test.go b/internal/e2e/full_suit_test.go index be4731c07..1f0c1b150 100644 --- a/internal/e2e/full_suit_test.go +++ b/internal/e2e/full_suit_test.go @@ -7,8 +7,6 @@ import ( "testing" "time" - "github.com/ory/keto/ketoapi" - "github.com/ory/herodot" "github.com/ory/x/cmdx" prometheus "github.com/ory/x/prometheusx" @@ -21,6 +19,7 @@ import ( "github.com/ory/keto/internal/relationtuple" "github.com/ory/keto/internal/x" "github.com/ory/keto/internal/x/dbx" + "github.com/ory/keto/ketoapi" ) type ( diff --git a/internal/e2e/sdk_client_test.go b/internal/e2e/sdk_client_test.go index 8424d4d6c..3807e3ff7 100644 --- a/internal/e2e/sdk_client_test.go +++ b/internal/e2e/sdk_client_test.go @@ -1,29 +1,23 @@ package e2e import ( + "context" "net/http" "time" - "github.com/ory/keto/ketoapi" - "github.com/ory/herodot" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/ory/keto/internal/httpclient/client/health" - - "github.com/ory/keto/internal/httpclient/client/write" - - "github.com/ory/keto/internal/httpclient/models" - - httpclient "github.com/ory/keto/internal/httpclient/client" - "github.com/ory/keto/internal/httpclient/client/read" - + httpclient "github.com/ory/keto/internal/httpclient-next" "github.com/ory/keto/internal/x" + "github.com/ory/keto/ketoapi" ) type sdkClient struct { - rc, wc *httpclient.OryKeto + rc httpclient.ReadApi + wc httpclient.WriteApi + mc httpclient.MetadataApi readRemote, writeRemote string } @@ -32,143 +26,166 @@ var _ client = (*sdkClient)(nil) var requestTimeout = 5 * time.Second -func (c *sdkClient) getReadClient() *httpclient.OryKeto { +func (c *sdkClient) requestCtx() context.Context { + ctx, _ := context.WithTimeout(context.Background(), requestTimeout) + return ctx +} + +func (c *sdkClient) getReadClient() httpclient.ReadApi { if c.rc == nil { - c.rc = httpclient.NewHTTPClientWithConfig(nil, &httpclient.TransportConfig{ - Host: c.readRemote, - Schemes: []string{"http"}, - }) + cfg := httpclient.NewConfiguration() + cfg.Host = c.readRemote + cfg.Scheme = "http" + c.rc = httpclient.NewAPIClient(cfg).ReadApi } return c.rc } -func (c *sdkClient) getWriteClient() *httpclient.OryKeto { +func (c *sdkClient) getMetadataClient() httpclient.MetadataApi { + if c.mc == nil { + cfg := httpclient.NewConfiguration() + cfg.Host = c.writeRemote + cfg.Scheme = "http" + c.mc = httpclient.NewAPIClient(cfg).MetadataApi + } + return c.mc +} + +func (c *sdkClient) getWriteClient() httpclient.WriteApi { if c.wc == nil { - c.wc = httpclient.NewHTTPClientWithConfig(nil, &httpclient.TransportConfig{ - Host: c.writeRemote, - Schemes: []string{"http"}, - }) + cfg := httpclient.NewConfiguration() + cfg.Host = c.writeRemote + cfg.Scheme = "http" + c.wc = httpclient.NewAPIClient(cfg).WriteApi } return c.wc } func (c *sdkClient) createTuple(t require.TestingT, r *ketoapi.RelationTuple) { - payload := &models.RelationQuery{ - Namespace: r.Namespace, - Object: r.Object, - Relation: r.Relation, + payload := httpclient.RelationQuery{ + Namespace: x.Ptr(r.Namespace), + Object: x.Ptr(r.Object), + Relation: x.Ptr(r.Relation), + SubjectId: r.SubjectID, } - if r.SubjectID != nil { - payload.SubjectID = *r.SubjectID - } else { - payload.SubjectSet = &models.SubjectSet{ - Namespace: &r.SubjectSet.Namespace, - Object: &r.SubjectSet.Object, - Relation: &r.SubjectSet.Relation, + if r.SubjectID == nil { + payload.SubjectSet = &httpclient.SubjectSet{ + Namespace: r.SubjectSet.Namespace, + Object: r.SubjectSet.Object, + Relation: r.SubjectSet.Relation, } } - _, err := c.getWriteClient().Write.CreateRelationTuple( - write.NewCreateRelationTupleParamsWithTimeout(requestTimeout). - WithPayload(payload), - ) + _, _, err := c.getWriteClient(). + CreateRelationTuple(c.requestCtx()). + RelationQuery(payload). + Execute() require.NoError(t, err) } func withSubject[P interface { - WithSubjectID(*string) P - WithSubjectSetNamespace(*string) P - WithSubjectSetObject(*string) P - WithSubjectSetRelation(*string) P - WithObject(*string) P - WithRelation(*string) P + SubjectId(string) P + SubjectSetNamespace(string) P + SubjectSetObject(string) P + SubjectSetRelation(string) P }](params P, subID *string, subSet *ketoapi.SubjectSet) P { if subID != nil { - return params.WithSubjectID(subID) + return params.SubjectId(*subID) } if subSet != nil { return params. - WithSubjectSetNamespace(&subSet.Namespace). - WithSubjectSetObject(&subSet.Object). - WithSubjectSetRelation(&subSet.Relation) + SubjectSetNamespace(subSet.Namespace). + SubjectSetObject(subSet.Object). + SubjectSetRelation(subSet.Relation) } return params } func (c *sdkClient) deleteTuple(t require.TestingT, r *ketoapi.RelationTuple) { - params := write.NewDeleteRelationTuplesParamsWithTimeout(time.Second). - WithNamespace(&r.Namespace). - WithObject(&r.Object). - WithRelation(&r.Relation) - params = withSubject(params, r.SubjectID, r.SubjectSet) - - _, err := c.getWriteClient().Write.DeleteRelationTuples(params) + request := c.getWriteClient(). + DeleteRelationTuples(c.requestCtx()). + Namespace(r.Namespace). + Object(r.Object). + Relation(r.Relation) + request = withSubject(request, r.SubjectID, r.SubjectSet) + + _, err := request.Execute() require.NoError(t, err) } func (c *sdkClient) deleteAllTuples(t require.TestingT, q *ketoapi.RelationQuery) { - params := write.NewDeleteRelationTuplesParamsWithTimeout(time.Second). - WithNamespace(q.Namespace). - WithObject(q.Object). - WithRelation(q.Relation) - withSubject(params, q.SubjectID, q.SubjectSet) - - _, err := c.getWriteClient().Write.DeleteRelationTuples(params) + request := c.getWriteClient().DeleteRelationTuples(c.requestCtx()) + if q.Namespace != nil { + request = request.Namespace(*q.Namespace) + } + if q.Object != nil { + request = request.Object(*q.Object) + } + if q.Relation != nil { + request = request.Relation(*q.Relation) + } + request = withSubject(request, q.SubjectID, q.SubjectSet) + _, err := request.Execute() require.NoError(t, err) } -func compileParams(q *ketoapi.RelationQuery, opts []x.PaginationOptionSetter) *read.GetRelationTuplesParams { - params := read.NewGetRelationTuplesParams().WithNamespace(q.Namespace) +func compileParams(req httpclient.ReadApiApiGetRelationTuplesRequest, q *ketoapi.RelationQuery, opts []x.PaginationOptionSetter) httpclient.ReadApiApiGetRelationTuplesRequest { + if q.Namespace != nil { + req = req.Namespace(*q.Namespace) + } if q.Relation != nil { - params = params.WithRelation(q.Relation) + req = req.Relation(*q.Relation) } if q.Object != nil { - params = params.WithObject(q.Object) + req = req.Object(*q.Object) } if q.SubjectID != nil { - params = params.WithSubjectID(q.SubjectID) + req = req.SubjectId(*q.SubjectID) } if q.SubjectSet != nil { - params = params. - WithSubjectSetNamespace(&q.SubjectSet.Namespace). - WithSubjectSetObject(&q.SubjectSet.Object). - WithSubjectSetRelation(&q.SubjectSet.Relation) + req = req. + SubjectSetNamespace(q.SubjectSet.Namespace). + SubjectSetObject(q.SubjectSet.Object). + SubjectSetRelation(q.SubjectSet.Relation) } pagination := x.GetPaginationOptions(opts...) if pagination.Size != 0 { - params = params.WithPageSize(x.Ptr(int64(pagination.Size))) + req = req.PageSize(int64(pagination.Size)) } if pagination.Token != "" { - params = params.WithPageToken(&pagination.Token) + req = req.PageToken(pagination.Token) } - return params + return req } func (c *sdkClient) queryTuple(t require.TestingT, q *ketoapi.RelationQuery, opts ...x.PaginationOptionSetter) *ketoapi.GetResponse { - resp, err := c.getReadClient().Read.GetRelationTuples(compileParams(q, opts).WithTimeout(time.Second)) + request := c.getReadClient().GetRelationTuples(c.requestCtx()) + request = compileParams(request, q, opts) + + resp, _, err := request.Execute() require.NoError(t, err) getResp := &ketoapi.GetResponse{ - RelationTuples: make([]*ketoapi.RelationTuple, len(resp.Payload.RelationTuples)), - NextPageToken: resp.Payload.NextPageToken, + RelationTuples: make([]*ketoapi.RelationTuple, len(resp.RelationTuples)), + NextPageToken: resp.GetNextPageToken(), } - for i, rt := range resp.Payload.RelationTuples { + for i, rt := range resp.RelationTuples { getResp.RelationTuples[i] = &ketoapi.RelationTuple{ - Namespace: *rt.Namespace, - Object: *rt.Object, - Relation: *rt.Relation, + Namespace: rt.Namespace, + Object: rt.Object, + Relation: rt.Relation, } if rt.SubjectSet != nil { getResp.RelationTuples[i].SubjectSet = &ketoapi.SubjectSet{ - Namespace: *rt.SubjectSet.Namespace, - Object: *rt.SubjectSet.Object, - Relation: *rt.SubjectSet.Relation, + Namespace: rt.SubjectSet.Namespace, + Object: rt.SubjectSet.Object, + Relation: rt.SubjectSet.Relation, } } else { - getResp.RelationTuples[i].SubjectID = &rt.SubjectID + getResp.RelationTuples[i].SubjectID = rt.SubjectId } } @@ -176,12 +193,14 @@ func (c *sdkClient) queryTuple(t require.TestingT, q *ketoapi.RelationQuery, opt } func (c *sdkClient) queryTupleErr(t require.TestingT, expected herodot.DefaultError, q *ketoapi.RelationQuery, opts ...x.PaginationOptionSetter) { - _, err := c.getReadClient().Read.GetRelationTuples(compileParams(q, opts).WithTimeout(time.Second)) + request := c.getReadClient().GetRelationTuples(c.requestCtx()) + request = compileParams(request, q, opts) + _, _, err := request.Execute() switch err.(type) { case nil: require.FailNow(t, "expected error but got nil") - case *read.GetRelationTuplesNotFound: + case *httpclient.GenericOpenAPIError: assert.Equal(t, expected.CodeField, http.StatusNotFound) default: require.FailNow(t, "got unknown error %+v\nexpected %+v", err, expected) @@ -189,65 +208,63 @@ func (c *sdkClient) queryTupleErr(t require.TestingT, expected herodot.DefaultEr } func (c *sdkClient) check(t require.TestingT, r *ketoapi.RelationTuple) bool { - params := read.NewGetCheckParamsWithTimeout(time.Second). - WithNamespace(&r.Namespace). - WithObject(&r.Object). - WithRelation(&r.Relation) - params = withSubject(params, r.SubjectID, r.SubjectSet) - resp, err := c.getReadClient().Read.GetCheck(params) + request := c.getReadClient().GetCheck(c.requestCtx()). + Namespace(r.Namespace). + Object(r.Object). + Relation(r.Relation) + request = withSubject(request, r.SubjectID, r.SubjectSet) + + resp, _, err := request.Execute() require.NoError(t, err) - return *resp.Payload.Allowed + + return resp.GetAllowed() } -func buildTree(t require.TestingT, mt *models.ExpandTree) *ketoapi.Tree[*ketoapi.RelationTuple] { +func buildTree(t require.TestingT, mt *httpclient.ExpandTree) *ketoapi.Tree[*ketoapi.RelationTuple] { result := &ketoapi.Tree[*ketoapi.RelationTuple]{ - Type: ketoapi.TreeNodeType(*mt.Type), + Type: ketoapi.TreeNodeType(mt.Type), } if mt.Tuple.SubjectSet != nil { result.Tuple = &ketoapi.RelationTuple{ SubjectSet: &ketoapi.SubjectSet{ - Namespace: *mt.Tuple.SubjectSet.Namespace, - Object: *mt.Tuple.SubjectSet.Object, - Relation: *mt.Tuple.SubjectSet.Relation, + Namespace: mt.Tuple.SubjectSet.Namespace, + Object: mt.Tuple.SubjectSet.Object, + Relation: mt.Tuple.SubjectSet.Relation, }, } } else { result.Tuple = &ketoapi.RelationTuple{ - SubjectID: &mt.Tuple.SubjectID, + SubjectID: mt.Tuple.SubjectId, } } if result.Type != ketoapi.TreeNodeLeaf && len(mt.Children) != 0 { result.Children = make([]*ketoapi.Tree[*ketoapi.RelationTuple], len(mt.Children)) for i, c := range mt.Children { - result.Children[i] = buildTree(t, c) + c := c + result.Children[i] = buildTree(t, &c) } } return result } func (c *sdkClient) expand(t require.TestingT, r *ketoapi.SubjectSet, depth int) *ketoapi.Tree[*ketoapi.RelationTuple] { - resp, err := c.getReadClient().Read.GetExpand( - read.NewGetExpandParamsWithTimeout(requestTimeout). - WithNamespace(r.Namespace). - WithObject(r.Object). - WithRelation(r.Relation). - WithMaxDepth(x.Ptr(int64(depth))), - ) + request := c.getReadClient().GetExpand(c.requestCtx()). + Namespace(r.Namespace). + Object(r.Object). + Relation(r.Relation). + MaxDepth(int64(depth)) + + resp, _, err := request.Execute() require.NoError(t, err) - return buildTree(t, resp.Payload) + + return buildTree(t, resp) } func (c *sdkClient) waitUntilLive(t require.TestingT) { - resp, err := c.getReadClient().Health.IsInstanceAlive(health.NewIsInstanceAliveParams().WithTimeout(requestTimeout)) - for err != nil { - resp, err = c.getReadClient().Health.IsInstanceAlive(health.NewIsInstanceAliveParams().WithTimeout(requestTimeout)) - } - require.Equal(t, "ok", resp.Payload.Status) - - resp, err = c.getWriteClient().Health.IsInstanceAlive(health.NewIsInstanceAliveParams().WithTimeout(requestTimeout)) + resp, _, err := c.getMetadataClient().IsReady(c.requestCtx()).Execute() for err != nil { - resp, err = c.getWriteClient().Health.IsInstanceAlive(health.NewIsInstanceAliveParams().WithTimeout(requestTimeout)) + resp, _, err = c.getMetadataClient().IsReady(c.requestCtx()).Execute() } - require.Equal(t, "ok", resp.Payload.Status) + require.Equal(t, "ok", resp.Status) } diff --git a/internal/persistence/sql/migrations/migratest/migration_test.go b/internal/persistence/sql/migrations/migratest/migration_test.go index e916c7fd4..cf75b90cb 100644 --- a/internal/persistence/sql/migrations/migratest/migration_test.go +++ b/internal/persistence/sql/migrations/migratest/migration_test.go @@ -9,19 +9,14 @@ import ( "testing" "time" + "github.com/gobuffalo/pop/v6" + "github.com/gofrs/uuid" "github.com/ory/x/fsx" "github.com/ory/x/logrusx" "github.com/ory/x/networkx" - "github.com/sirupsen/logrus" - - "github.com/ory/keto/internal/persistence/sql/migrations/uuidmapping" - "github.com/ory/keto/internal/x" - "github.com/ory/keto/ketoapi" - - "github.com/gobuffalo/pop/v6" - "github.com/gofrs/uuid" "github.com/ory/x/popx" "github.com/ory/x/sqlcon" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -29,8 +24,11 @@ import ( "github.com/ory/keto/internal/driver/config" "github.com/ory/keto/internal/namespace" "github.com/ory/keto/internal/persistence/sql" + "github.com/ory/keto/internal/persistence/sql/migrations/uuidmapping" "github.com/ory/keto/internal/relationtuple" + "github.com/ory/keto/internal/x" "github.com/ory/keto/internal/x/dbx" + "github.com/ory/keto/ketoapi" ) func TestMigrations(t *testing.T) { diff --git a/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.cockroach.down.sql b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.cockroach.down.sql new file mode 100644 index 000000000..e2511ea7a --- /dev/null +++ b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.cockroach.down.sql @@ -0,0 +1 @@ +ALTER TABLE keto_uuid_mappings ADD CONSTRAINT check_string_representation CHECK (string_representation <> ''); diff --git a/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.cockroach.up.sql b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.cockroach.up.sql new file mode 100644 index 000000000..8bdb0f4c0 --- /dev/null +++ b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.cockroach.up.sql @@ -0,0 +1 @@ +ALTER TABLE keto_uuid_mappings DROP CONSTRAINT IF EXISTS check_string_representation; diff --git a/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.mysql.down.sql b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.mysql.down.sql new file mode 100644 index 000000000..71f4ed72f --- /dev/null +++ b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.mysql.down.sql @@ -0,0 +1 @@ +ALTER TABLE keto_uuid_mappings ADD CONSTRAINT keto_uuid_mappings_chk_1 CHECK (string_representation <> ''); diff --git a/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.mysql.up.sql b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.mysql.up.sql new file mode 100644 index 000000000..5b784f96e --- /dev/null +++ b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.mysql.up.sql @@ -0,0 +1 @@ +ALTER TABLE keto_uuid_mappings DROP CONSTRAINT keto_uuid_mappings_chk_1; diff --git a/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.postgres.down.sql b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.postgres.down.sql new file mode 100644 index 000000000..27c6133a6 --- /dev/null +++ b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.postgres.down.sql @@ -0,0 +1 @@ +ALTER TABLE keto_uuid_mappings ADD CONSTRAINT keto_uuid_mappings_string_representation_check CHECK (string_representation <> ''); diff --git a/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.postgres.up.sql b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.postgres.up.sql new file mode 100644 index 000000000..eecf2297d --- /dev/null +++ b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.postgres.up.sql @@ -0,0 +1 @@ +ALTER TABLE keto_uuid_mappings DROP CONSTRAINT IF EXISTS keto_uuid_mappings_string_representation_check; diff --git a/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.sqlite.down.sql b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.sqlite.down.sql new file mode 100644 index 000000000..ee0bf3180 --- /dev/null +++ b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.sqlite.down.sql @@ -0,0 +1 @@ +-- do nothing. \ No newline at end of file diff --git a/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.sqlite.up.sql b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.sqlite.up.sql new file mode 100644 index 000000000..0e3fd3f09 --- /dev/null +++ b/internal/persistence/sql/migrations/sql/20220513200400000001_uuid-mapping-remove-check.sqlite.up.sql @@ -0,0 +1,9 @@ +--ALTER TABLE keto_uuid_mappings DROP CONSTRAINT IF EXISTS check_string_representation; +ALTER TABLE keto_uuid_mappings RENAME TO keto_uuid_mapping_with_old_check_constraint; +CREATE TABLE keto_uuid_mappings +( + id UUID NOT NULL PRIMARY KEY, + string_representation TEXT NOT NULL +); +INSERT INTO keto_uuid_mappings SELECT * FROM keto_uuid_mapping_with_old_check_constraint; +DROP TABLE keto_uuid_mapping_with_old_check_constraint; diff --git a/internal/persistence/sql/uuid_mapping_test.go b/internal/persistence/sql/uuid_mapping_test.go index 704ac2767..ce72b5dbf 100644 --- a/internal/persistence/sql/uuid_mapping_test.go +++ b/internal/persistence/sql/uuid_mapping_test.go @@ -48,13 +48,13 @@ func TestUUIDMapping(t *testing.T) { mappings interface{} assertErr assert.ErrorAssertionFunc }{{ - desc: "empty should fail on constraint", + desc: "empty should not fail on constraint", mappings: &sql.UUIDMapping{}, - assertErr: assertCheckErr, + assertErr: assert.NoError, }, { - desc: "empty strings should fail on constraint", + desc: "empty strings should not fail on constraint", mappings: &sql.UUIDMapping{ID: uuid.Nil}, - assertErr: assertCheckErr, + assertErr: assert.NoError, }, { desc: "single with string rep should succeed", mappings: &sql.UUIDMapping{StringRepresentation: "foo"},