Skip to content

Commit 0da1a6a

Browse files
merge remote ref
Signed-off-by: Kartikay <[email protected]>
2 parents 4af7feb + 5b6d6ac commit 0da1a6a

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed

internal/services/shared/errors.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,30 @@ func NewDeprecationError(err error) DeprecationError {
9696
}
9797
}
9898

99+
// DeprecationError is an error returned when a schema object or relation is deprecated.
100+
type DeprecationError struct {
101+
error
102+
}
103+
104+
func (err DeprecationError) GRPCStatus() *status.Status {
105+
return spiceerrors.WithCodeAndDetails(
106+
err,
107+
codes.Aborted,
108+
spiceerrors.ForReason(
109+
// TODO: replace with a deprecation type error reason
110+
v1.ErrorReason_ERROR_REASON_SCHEMA_TYPE_ERROR,
111+
map[string]string{},
112+
),
113+
)
114+
}
115+
116+
// NewDeprecationError wraps an error to indicate an attempted write to a deprecated object type, subject or allowed relation type.
117+
func NewDeprecationError(err error) DeprecationError {
118+
return DeprecationError{
119+
error: err,
120+
}
121+
}
122+
99123
// SchemaWriteDataValidationError occurs when a schema cannot be applied due to leaving data unreferenced.
100124
type SchemaWriteDataValidationError struct {
101125
error

pkg/schema/definition_test.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,152 @@ func TestTypeSystemAccessors(t *testing.T) {
11201120
require.True(t, traits.AllowsCaveats)
11211121
require.True(t, traits.AllowsExpiration)
11221122
require.False(t, traits.AllowsDeprecation)
1123+
require.False(t, traits.AllowsDeprecation)
1124+
1125+
_, err = vts.PossibleTraitsForSubject("unknown", "user")
1126+
require.Error(t, err)
1127+
1128+
_, err = vts.PossibleTraitsForSubject("editor", "unknown")
1129+
require.Error(t, err)
1130+
})
1131+
},
1132+
},
1133+
},
1134+
{
1135+
"schema with deprecation and expiration",
1136+
`use expiration
1137+
use deprecation
1138+
1139+
definition user {}
1140+
definition testuser {}
1141+
1142+
caveat somecaveat(somecondition int) {
1143+
somecondition == 42
1144+
}
1145+
1146+
@deprecated(warn, "some comments here")
1147+
definition resource {
1148+
relation editor: user with expiration
1149+
relation viewer: user | user with somecaveat | @deprecated(error) user with expiration | user with somecaveat and expiration
1150+
relation auditor: @deprecated(warn, "migrate tester") testuser with somecaveat and expiration | @deprecated(error, "can't be expired") testuser with expiration
1151+
relation user_pool: @deprecated(warn) user:*
1152+
}`,
1153+
map[string]tsTester{
1154+
"resource": func(t *testing.T, vts *ValidatedDefinition) {
1155+
t.Run("IsPermission", func(t *testing.T) {
1156+
require.False(t, vts.IsPermission("editor"))
1157+
require.False(t, vts.IsPermission("viewer"))
1158+
require.False(t, vts.IsPermission("auditor"))
1159+
require.False(t, vts.IsPermission("user_pool"))
1160+
})
1161+
1162+
t.Run("RelationDoesNotAllowCaveatsOrTraitsForSubject", func(t *testing.T) {
1163+
ok, err := vts.RelationDoesNotAllowCaveatsOrTraitsForSubject("editor", "user")
1164+
require.NoError(t, err)
1165+
require.False(t, ok)
1166+
1167+
ok, err = vts.RelationDoesNotAllowCaveatsOrTraitsForSubject("viewer", "user")
1168+
require.NoError(t, err)
1169+
require.False(t, ok)
1170+
1171+
ok, err = vts.RelationDoesNotAllowCaveatsOrTraitsForSubject("auditor", "testuser")
1172+
require.NoError(t, err)
1173+
require.False(t, ok)
1174+
1175+
ok, err = vts.RelationDoesNotAllowCaveatsOrTraitsForSubject("user_pool", "user")
1176+
require.NoError(t, err)
1177+
require.False(t, ok)
1178+
})
1179+
1180+
t.Run("IsAllowedPublicNamespace", func(t *testing.T) {
1181+
require.Equal(t, PublicSubjectNotAllowed, noError(vts.IsAllowedPublicNamespace("editor", "user")))
1182+
require.Equal(t, PublicSubjectNotAllowed, noError(vts.IsAllowedPublicNamespace("viewer", "user")))
1183+
require.Equal(t, PublicSubjectNotAllowed, noError(vts.IsAllowedPublicNamespace("auditor", "testuser")))
1184+
require.Equal(t, PublicSubjectAllowed, noError(vts.IsAllowedPublicNamespace("user_pool", "user")))
1185+
})
1186+
1187+
t.Run("IsAllowedDirectNamespace", func(t *testing.T) {
1188+
require.Equal(t, AllowedDefinitionValid, noError(vts.IsAllowedDirectNamespace("editor", "user")))
1189+
require.Equal(t, AllowedDefinitionValid, noError(vts.IsAllowedDirectNamespace("viewer", "user")))
1190+
require.Equal(t, AllowedDefinitionValid, noError(vts.IsAllowedDirectNamespace("auditor", "testuser")))
1191+
require.Equal(t, AllowedDefinitionNotValid, noError(vts.IsAllowedDirectNamespace("user_pool", "user")))
1192+
})
1193+
1194+
t.Run("IsAllowedDirectRelation", func(t *testing.T) {
1195+
require.Equal(t, DirectRelationValid, noError(vts.IsAllowedDirectRelation("editor", "user", "...")))
1196+
require.Equal(t, DirectRelationValid, noError(vts.IsAllowedDirectRelation("viewer", "user", "...")))
1197+
require.Equal(t, DirectRelationValid, noError(vts.IsAllowedDirectRelation("auditor", "testuser", "...")))
1198+
require.Equal(t, DirectRelationNotValid, noError(vts.IsAllowedDirectRelation("user_pool", "user", "...")))
1199+
})
1200+
1201+
t.Run("HasAllowedRelation", func(t *testing.T) {
1202+
require.Equal(t, AllowedRelationValid, noError(vts.HasAllowedRelation("editor", ns.AllowedRelationWithExpiration("user", "..."))))
1203+
require.Equal(t, AllowedRelationNotValid, noError(vts.HasAllowedRelation("editor", ns.AllowedRelation("user", "..."))))
1204+
require.Equal(t, AllowedRelationNotValid, noError(vts.HasAllowedRelation("editor", ns.AllowedRelationWithCaveat("user", "...", ns.AllowedCaveat("somecaveat")))))
1205+
1206+
require.Equal(t, AllowedRelationValid, noError(vts.HasAllowedRelation("viewer", ns.AllowedRelation("user", "..."))))
1207+
require.Equal(t, AllowedRelationValid, noError(vts.HasAllowedRelation("viewer", ns.AllowedRelationWithCaveat("user", "...", ns.AllowedCaveat("somecaveat")))))
1208+
require.Equal(t, AllowedRelationValid, noError(vts.HasAllowedRelation("viewer", ns.AllowedRelationWithDeprecation(ns.AllowedRelationWithExpiration("user", "..."), ns.Deprecation(core.DeprecationType_DEPRECATED_TYPE_ERROR, "")))))
1209+
require.Equal(t, AllowedRelationValid, noError(vts.HasAllowedRelation("viewer", ns.AllowedRelationWithCaveatAndExpiration("user", "...", ns.AllowedCaveat("somecaveat")))))
1210+
1211+
require.Equal(t, AllowedRelationValid, noError(vts.HasAllowedRelation("auditor", ns.AllowedRelationWithDeprecation(ns.AllowedRelationWithExpiration("testuser", "..."), ns.Deprecation(core.DeprecationType_DEPRECATED_TYPE_ERROR, "can't be expired")))))
1212+
require.Equal(t, AllowedRelationValid, noError(vts.HasAllowedRelation("auditor", ns.AllowedRelationWithDeprecation(ns.AllowedRelationWithCaveatAndExpiration("testuser", "...", ns.AllowedCaveat("somecaveat")), ns.Deprecation(core.DeprecationType_DEPRECATED_TYPE_WARNING, "migrate tester")))))
1213+
1214+
require.Equal(t, AllowedRelationValid, noError(vts.HasAllowedRelation("user_pool", ns.AllowedPublicNamespaceWithDeprecation("user", ns.Deprecation(core.DeprecationType_DEPRECATED_TYPE_WARNING, "")))))
1215+
})
1216+
1217+
t.Run("AllowedDirectRelationsAndWildcards", func(t *testing.T) {
1218+
userDirect := ns.AllowedRelation("user", "...")
1219+
caveatedUser := ns.AllowedRelationWithCaveat("user", "...", ns.AllowedCaveat("somecaveat"))
1220+
expiringUser := ns.AllowedRelationWithExpiration("user", "...")
1221+
expiringCaveatedUser := ns.AllowedRelationWithCaveatAndExpiration("user", "...", ns.AllowedCaveat("somecaveat"))
1222+
deprecatedUser := ns.AllowedRelationWithDeprecation(ns.AllowedRelationWithExpiration("user", "..."), ns.Deprecation(core.DeprecationType_DEPRECATED_TYPE_ERROR, ""))
1223+
1224+
deprecatedPublicUser := ns.AllowedPublicNamespaceWithDeprecation("user", ns.Deprecation(core.DeprecationType_DEPRECATED_TYPE_WARNING, ""))
1225+
1226+
deprecatedCaveatedUser := ns.AllowedRelationWithDeprecation(ns.AllowedRelationWithCaveatAndExpiration("testuser", "...", ns.AllowedCaveat("somecaveat")), ns.Deprecation(core.DeprecationType_DEPRECATED_TYPE_WARNING, "migrate tester"))
1227+
deprecatedExpiredUser := ns.AllowedRelationWithDeprecation(ns.AllowedRelationWithExpiration("testuser", "..."), ns.Deprecation(core.DeprecationType_DEPRECATED_TYPE_ERROR, "can't be expired"))
1228+
1229+
allowed := noError(vts.AllowedDirectRelationsAndWildcards("editor"))
1230+
requireSameAllowedRelations(t, allowed, expiringUser)
1231+
1232+
allowed = noError(vts.AllowedDirectRelationsAndWildcards("viewer"))
1233+
requireSameAllowedRelations(t, allowed, userDirect, caveatedUser, deprecatedUser, expiringCaveatedUser)
1234+
1235+
allowed = noError(vts.AllowedDirectRelationsAndWildcards("auditor"))
1236+
requireSameAllowedRelations(t, allowed, deprecatedCaveatedUser, deprecatedExpiredUser)
1237+
1238+
allowed = noError(vts.AllowedDirectRelationsAndWildcards("user_pool"))
1239+
requireSameAllowedRelations(t, allowed, deprecatedPublicUser)
1240+
})
1241+
1242+
t.Run("AllowedSubjectRelations", func(t *testing.T) {
1243+
userDirect := ns.RelationReference("user", "...")
1244+
1245+
allowed := noError(vts.AllowedSubjectRelations("editor"))
1246+
requireSameSubjectRelations(t, allowed, userDirect)
1247+
1248+
allowed = noError(vts.AllowedSubjectRelations("viewer"))
1249+
requireSameSubjectRelations(t, allowed, userDirect)
1250+
})
1251+
1252+
t.Run("PossibleTraitsForSubject", func(t *testing.T) {
1253+
traits, err := vts.PossibleTraitsForSubject("editor", "user")
1254+
require.NoError(t, err)
1255+
require.False(t, traits.AllowsCaveats)
1256+
require.True(t, traits.AllowsExpiration)
1257+
1258+
traits, err = vts.PossibleTraitsForSubject("viewer", "user")
1259+
require.NoError(t, err)
1260+
require.True(t, traits.AllowsCaveats)
1261+
require.True(t, traits.AllowsExpiration)
1262+
require.True(t, traits.AllowsDeprecation)
1263+
1264+
traits, err = vts.PossibleTraitsForSubject("auditor", "testuser")
1265+
require.NoError(t, err)
1266+
require.True(t, traits.AllowsCaveats)
1267+
require.True(t, traits.AllowsExpiration)
1268+
require.True(t, traits.AllowsDeprecation)
11231269

11241270
_, err = vts.PossibleTraitsForSubject("unknown", "user")
11251271
require.Error(t, err)

pkg/schemadsl/compiler/translator.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,15 @@ func translateSpecificTypeReference(tctx *translationContext, typeRefNode *dslNo
805805
ref.Deprecation = dep
806806
}
807807

808+
// Add the deprecation, if any.
809+
if depChild, err := typeRefNode.Lookup(dslshape.NodeTypeReferenceDeprecatedType); err == nil && depChild.GetType() == dslshape.NodeTypeDeprecation {
810+
dep, err := translateDeprecation(tctx, depChild)
811+
if err != nil {
812+
return nil, err
813+
}
814+
ref.Deprecation = dep
815+
}
816+
808817
if !tctx.skipValidate {
809818
if err := ref.Validate(); err != nil {
810819
return nil, typeRefNode.Errorf("invalid type relation: %w", err)

0 commit comments

Comments
 (0)