github.com/openfga/openfga@v1.5.4-rc1/pkg/storage/test/authz_models.go (about) 1 package test 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/google/go-cmp/cmp" 8 "github.com/oklog/ulid/v2" 9 openfgav1 "github.com/openfga/api/proto/openfga/v1" 10 "github.com/stretchr/testify/require" 11 12 "github.com/openfga/openfga/pkg/storage" 13 "github.com/openfga/openfga/pkg/testutils" 14 "github.com/openfga/openfga/pkg/typesystem" 15 ) 16 17 func WriteAndReadAuthorizationModelTest(t *testing.T, datastore storage.OpenFGADatastore) { 18 ctx := context.Background() 19 storeID := ulid.Make().String() 20 21 t.Run("write, then read, succeeds", func(t *testing.T) { 22 model := &openfgav1.AuthorizationModel{ 23 Id: ulid.Make().String(), 24 SchemaVersion: typesystem.SchemaVersion1_0, 25 TypeDefinitions: []*openfgav1.TypeDefinition{{Type: "folder"}}, 26 } 27 28 err := datastore.WriteAuthorizationModel(ctx, storeID, model) 29 require.NoError(t, err) 30 31 got, err := datastore.ReadAuthorizationModel(ctx, storeID, model.GetId()) 32 require.NoError(t, err) 33 34 if diff := cmp.Diff(model, got, cmpOpts...); diff != "" { 35 t.Errorf("mismatch (-want +got):\n%s", diff) 36 } 37 }) 38 39 t.Run("trying_to_get_a_model_which_does_not_exist_returns_not_found", func(t *testing.T) { 40 _, err := datastore.ReadAuthorizationModel(ctx, storeID, ulid.Make().String()) 41 require.ErrorIs(t, err, storage.ErrNotFound) 42 }) 43 } 44 45 func ReadAuthorizationModelsTest(t *testing.T, datastore storage.OpenFGADatastore) { 46 ctx := context.Background() 47 store := ulid.Make().String() 48 49 model1 := &openfgav1.AuthorizationModel{ 50 Id: ulid.Make().String(), 51 SchemaVersion: typesystem.SchemaVersion1_0, 52 TypeDefinitions: []*openfgav1.TypeDefinition{ 53 { 54 Type: "folder", 55 Relations: map[string]*openfgav1.Userset{ 56 "viewer": { 57 Userset: &openfgav1.Userset_This{ 58 This: &openfgav1.DirectUserset{}, 59 }, 60 }, 61 }, 62 }, 63 }, 64 } 65 66 err := datastore.WriteAuthorizationModel(ctx, store, model1) 67 require.NoError(t, err) 68 69 model2 := &openfgav1.AuthorizationModel{ 70 Id: ulid.Make().String(), 71 SchemaVersion: typesystem.SchemaVersion1_0, 72 TypeDefinitions: []*openfgav1.TypeDefinition{ 73 { 74 Type: "folder", 75 Relations: map[string]*openfgav1.Userset{ 76 "reader": { 77 Userset: &openfgav1.Userset_This{ 78 This: &openfgav1.DirectUserset{}, 79 }, 80 }, 81 }, 82 }, 83 }, 84 } 85 86 err = datastore.WriteAuthorizationModel(ctx, store, model2) 87 require.NoError(t, err) 88 89 models, continuationToken, err := datastore.ReadAuthorizationModels(ctx, store, storage.PaginationOptions{ 90 PageSize: 1, 91 }) 92 require.NoError(t, err) 93 require.Len(t, models, 1) 94 require.NotEmpty(t, continuationToken) 95 96 if diff := cmp.Diff(model2, models[0], cmpOpts...); diff != "" { 97 t.Fatalf("mismatch (-want +got):\n%s", diff) 98 } 99 100 models, continuationToken, err = datastore.ReadAuthorizationModels(ctx, store, storage.PaginationOptions{ 101 PageSize: 2, 102 From: string(continuationToken), 103 }) 104 require.NoError(t, err) 105 require.Len(t, models, 1) 106 require.Empty(t, continuationToken) 107 108 if diff := cmp.Diff(model1, models[0], cmpOpts...); diff != "" { 109 t.Fatalf("mismatch (-want +got):\n%s", diff) 110 } 111 } 112 113 func FindLatestAuthorizationModelTest(t *testing.T, datastore storage.OpenFGADatastore) { 114 ctx := context.Background() 115 116 t.Run("find_latest_authorization_model_should_return_not_found_when_no_models", func(t *testing.T) { 117 store := testutils.CreateRandomString(10) 118 _, err := datastore.FindLatestAuthorizationModel(ctx, store) 119 require.ErrorIs(t, err, storage.ErrNotFound) 120 }) 121 122 t.Run("find_latest_authorization_model_should_succeed", func(t *testing.T) { 123 store := ulid.Make().String() 124 125 oldModel := &openfgav1.AuthorizationModel{ 126 Id: ulid.Make().String(), 127 SchemaVersion: typesystem.SchemaVersion1_1, 128 TypeDefinitions: []*openfgav1.TypeDefinition{ 129 { 130 Type: "user", 131 }, 132 { 133 Type: "folder", 134 Relations: map[string]*openfgav1.Userset{ 135 "viewer": { 136 Userset: &openfgav1.Userset_This{}, 137 }, 138 }, 139 Metadata: &openfgav1.Metadata{ 140 Relations: map[string]*openfgav1.RelationMetadata{ 141 "viewer": { 142 DirectlyRelatedUserTypes: []*openfgav1.RelationReference{ 143 { 144 Type: "user", 145 }, 146 }, 147 }, 148 }, 149 }, 150 }, 151 }, 152 } 153 err := datastore.WriteAuthorizationModel(ctx, store, oldModel) 154 require.NoError(t, err) 155 156 updatedModel := &openfgav1.AuthorizationModel{ 157 Id: ulid.Make().String(), 158 SchemaVersion: typesystem.SchemaVersion1_1, 159 TypeDefinitions: []*openfgav1.TypeDefinition{ 160 { 161 Type: "user", 162 }, 163 { 164 Type: "folder", 165 Relations: map[string]*openfgav1.Userset{ 166 "owner": { 167 Userset: &openfgav1.Userset_This{}, 168 }, 169 }, 170 Metadata: &openfgav1.Metadata{ 171 Relations: map[string]*openfgav1.RelationMetadata{ 172 "owner": { 173 DirectlyRelatedUserTypes: []*openfgav1.RelationReference{ 174 { 175 Type: "user", 176 }, 177 }, 178 }, 179 }, 180 }, 181 }, 182 }, 183 } 184 err = datastore.WriteAuthorizationModel(ctx, store, updatedModel) 185 require.NoError(t, err) 186 187 latestModel, err := datastore.FindLatestAuthorizationModel(ctx, store) 188 require.NoError(t, err) 189 if diff := cmp.Diff(updatedModel, latestModel, cmpOpts...); diff != "" { 190 t.Errorf("mismatch (-want +got):\n%s", diff) 191 } 192 193 newModel := &openfgav1.AuthorizationModel{ 194 Id: ulid.Make().String(), 195 SchemaVersion: typesystem.SchemaVersion1_1, 196 TypeDefinitions: []*openfgav1.TypeDefinition{ 197 { 198 Type: "user", 199 }, 200 { 201 Type: "folder", 202 Relations: map[string]*openfgav1.Userset{ 203 "reader": { 204 Userset: &openfgav1.Userset_This{}, 205 }, 206 }, 207 Metadata: &openfgav1.Metadata{ 208 Relations: map[string]*openfgav1.RelationMetadata{ 209 "reader": { 210 DirectlyRelatedUserTypes: []*openfgav1.RelationReference{ 211 { 212 Type: "user", 213 }, 214 }, 215 }, 216 }, 217 }, 218 }, 219 }, 220 } 221 err = datastore.WriteAuthorizationModel(ctx, store, newModel) 222 require.NoError(t, err) 223 224 latestModel, err = datastore.FindLatestAuthorizationModel(ctx, store) 225 require.NoError(t, err) 226 if diff := cmp.Diff(newModel, latestModel, cmpOpts...); diff != "" { 227 t.Errorf("mismatch (-want +got):\n%s", diff) 228 } 229 }) 230 }