Skip to content

Commit

Permalink
Merge pull request #800 from Permify/next
Browse files Browse the repository at this point in the history
Next
  • Loading branch information
tolgaOzen authored Nov 1, 2023
2 parents f55f74a + 64cba8e commit 466ae10
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/apidocs.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"info": {
"title": "Permify API",
"description": "Permify is an open-source authorization service for creating and maintaining fine-grained authorizations across your individual applications and services. Permify converts authorization data as relational tuples into a database you point at. We called that database a Write Database (WriteDB) and it behaves as a centralized data source for your authorization system. You can model of your authorization with Permify's DSL - Permify Schema - and perform access checks with a single API call anywhere on your stack. Access decisions made according to stored relational tuples.",
"version": "v0.5.5",
"version": "v0.5.6",
"contact": {
"name": "API Support",
"url": "https://github.com/Permify/permify/issues",
Expand Down
2 changes: 1 addition & 1 deletion internal/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var Identifier = xid.New().String()
*/
const (
// Version is the last release of the Permify (e.g. v0.1.0)
Version = "v0.5.5"
Version = "v0.5.6"

// Banner is the view for terminal.
Banner = `
Expand Down
4 changes: 2 additions & 2 deletions internal/storage/postgres/dataWriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func (w *DataWriter) Delete(ctx context.Context, tenantID string, tupleFilter *b
}

if !validation.IsTupleFilterEmpty(tupleFilter) {
tbuilder := w.database.Builder.Update(RelationTuplesTable).Set("expired_tx_id", xid).Where(squirrel.Eq{"expired_tx_id": "0"})
tbuilder := w.database.Builder.Update(RelationTuplesTable).Set("expired_tx_id", xid).Where(squirrel.Eq{"expired_tx_id": "0", "tenant_id": tenantID})
tbuilder = utils.TuplesFilterQueryForUpdateBuilder(tbuilder, tupleFilter)

var tquery string
Expand All @@ -316,7 +316,7 @@ func (w *DataWriter) Delete(ctx context.Context, tenantID string, tupleFilter *b
}

if !validation.IsAttributeFilterEmpty(attributeFilter) {
abuilder := w.database.Builder.Update(AttributesTable).Set("expired_tx_id", xid).Where(squirrel.Eq{"expired_tx_id": "0"})
abuilder := w.database.Builder.Update(AttributesTable).Set("expired_tx_id", xid).Where(squirrel.Eq{"expired_tx_id": "0", "tenant_id": tenantID})
abuilder = utils.AttributesFilterQueryForUpdateBuilder(abuilder, attributeFilter)

var aquery string
Expand Down
143 changes: 143 additions & 0 deletions internal/storage/postgres/dataWriter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,5 +272,148 @@ var _ = Describe("DataWriter", func() {
Expect(ct5.String()).Should(Equal(""))
Expect(len(col4.GetAttributes())).Should(Equal(1))
})

It("tenants should be isolated", func() {
ctx := context.Background()

attr1, err := attribute.Attribute("organization:organization-1$public|boolean:true")
Expect(err).ShouldNot(HaveOccurred())

attr2, err := attribute.Attribute("organization:organization-1$ip_addresses|string[]:127.0.0.1,127.0.0.2")
Expect(err).ShouldNot(HaveOccurred())

attr3, err := attribute.Attribute("organization:organization-3$balance|double:234.344")
Expect(err).ShouldNot(HaveOccurred())

tup1, err := tuple.Tuple("organization:organization-1#admin@user:user-1")
Expect(err).ShouldNot(HaveOccurred())

tup2, err := tuple.Tuple("organization:organization-1#admin@user:user-4")
Expect(err).ShouldNot(HaveOccurred())

tup3, err := tuple.Tuple("organization:organization-1#admin@user:user-2")
Expect(err).ShouldNot(HaveOccurred())

attributes1 := database.NewAttributeCollection([]*base.Attribute{
attr1,
attr2,
attr3,
}...)

tuples1 := database.NewTupleCollection([]*base.Tuple{
tup1,
tup2,
tup3,
}...)

token1, err := dataWriter.Write(ctx, "t1", tuples1, attributes1)
Expect(err).ShouldNot(HaveOccurred())
Expect(token1.String()).ShouldNot(Equal(""))

tokenT21, err := dataWriter.Write(ctx, "t2", tuples1, attributes1)
Expect(err).ShouldNot(HaveOccurred())
Expect(tokenT21.String()).ShouldNot(Equal(""))

col1, ct1, err := dataReader.ReadRelationships(ctx, "t1", &base.TupleFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
}, token1.String(), database.NewPagination(database.Size(10), database.Token("")))
Expect(err).ShouldNot(HaveOccurred())
Expect(ct1.String()).Should(Equal(""))
Expect(len(col1.GetTuples())).Should(Equal(3))

col2, ct2, err := dataReader.ReadAttributes(ctx, "t1", &base.AttributeFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
}, token1.String(), database.NewPagination(database.Size(10), database.Token("")))
Expect(err).ShouldNot(HaveOccurred())
Expect(ct2.String()).Should(Equal(""))
Expect(len(col2.GetAttributes())).Should(Equal(2))

colT21, ctT21, err := dataReader.ReadRelationships(ctx, "t2", &base.TupleFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
}, tokenT21.String(), database.NewPagination(database.Size(10), database.Token("")))
Expect(err).ShouldNot(HaveOccurred())
Expect(ctT21.String()).Should(Equal(""))
Expect(len(colT21.GetTuples())).Should(Equal(3))

colT22, ctT22, err := dataReader.ReadAttributes(ctx, "t2", &base.AttributeFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
}, tokenT21.String(), database.NewPagination(database.Size(10), database.Token("")))
Expect(err).ShouldNot(HaveOccurred())
Expect(ctT22.String()).Should(Equal(""))
Expect(len(colT22.GetAttributes())).Should(Equal(2))

token2, err := dataWriter.Delete(ctx, "t1",
&base.TupleFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
Relation: "admin",
Subject: &base.SubjectFilter{
Type: "user",
Ids: []string{"user-1"},
},
},
&base.AttributeFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
Attributes: []string{"public"},
})
Expect(err).ShouldNot(HaveOccurred())

col3, ct3, err := dataReader.ReadRelationships(ctx, "t1", &base.TupleFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
}, token2.String(), database.NewPagination(database.Size(10), database.Token("")))
Expect(err).ShouldNot(HaveOccurred())
Expect(ct3.String()).Should(Equal(""))
Expect(len(col3.GetTuples())).Should(Equal(2))

col4, ct5, err := dataReader.ReadAttributes(ctx, "t1", &base.AttributeFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
}, token2.String(), database.NewPagination(database.Size(10), database.Token("")))
Expect(err).ShouldNot(HaveOccurred())
Expect(ct5.String()).Should(Equal(""))
Expect(len(col4.GetAttributes())).Should(Equal(1))

colT23, ctT23, err := dataReader.ReadRelationships(ctx, "t2", &base.TupleFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
}, token2.String(), database.NewPagination(database.Size(10), database.Token("")))
Expect(err).ShouldNot(HaveOccurred())
Expect(ctT23.String()).Should(Equal(""))
Expect(len(colT23.GetTuples())).Should(Equal(3))

colT24, ctT25, err := dataReader.ReadAttributes(ctx, "t2", &base.AttributeFilter{
Entity: &base.EntityFilter{
Type: "organization",
Ids: []string{"organization-1"},
},
}, token2.String(), database.NewPagination(database.Size(10), database.Token("")))
Expect(err).ShouldNot(HaveOccurred())
Expect(ctT25.String()).Should(Equal(""))
Expect(len(colT24.GetAttributes())).Should(Equal(2))
})
})
})
2 changes: 1 addition & 1 deletion pkg/pb/base/v1/openapi.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion proto/base/v1/openapi.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
title: "Permify API";
description: "Permify is an open-source authorization service for creating and maintaining fine-grained authorizations across your individual applications and services. Permify converts authorization data as relational tuples into a database you point at. We called that database a Write Database (WriteDB) and it behaves as a centralized data source for your authorization system. You can model of your authorization with Permify's DSL - Permify Schema - and perform access checks with a single API call anywhere on your stack. Access decisions made according to stored relational tuples.";
version: "v0.5.5";
version: "v0.5.6";
contact: {
name: "API Support";
url: "https://github.com/Permify/permify/issues";
Expand Down

0 comments on commit 466ae10

Please sign in to comment.