Skip to content

Commit 4a30426

Browse files
authored
feat(policy): attribute values unsafe actions db connectivity (#1030)
PR Number 4 related to #115
1 parent a7c660e commit 4a30426

File tree

6 files changed

+611
-84
lines changed

6 files changed

+611
-84
lines changed

service/integration/attribute_fqns_test.go

Lines changed: 251 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,113 @@ func (s *AttributeFqnSuite) TestGetAttributesByValueFqns() {
262262
}
263263
}
264264

265+
func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_AllValuesHaveProperFqns() {
266+
namespace := "testing_multiple_fqns.properfqns"
267+
attr := "test_attr"
268+
value1 := "test_value"
269+
value2 := "test_value_2"
270+
value3 := "testing_values_3"
271+
fqn1 := fqnBuilder(namespace, attr, value1)
272+
fqn2 := fqnBuilder(namespace, attr, value2)
273+
fqn3 := fqnBuilder(namespace, attr, value3)
274+
275+
// Create namespace
276+
n, err := s.db.PolicyClient.CreateNamespace(s.ctx, &namespaces.CreateNamespaceRequest{
277+
Name: namespace,
278+
})
279+
s.Require().NoError(err)
280+
281+
// Create attribute
282+
a, err := s.db.PolicyClient.CreateAttribute(s.ctx, &attributes.CreateAttributeRequest{
283+
NamespaceId: n.GetId(),
284+
Name: attr,
285+
Rule: policy.AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_ANY_OF,
286+
})
287+
s.Require().NoError(err)
288+
289+
// Create attribute value1
290+
v1, err := s.db.PolicyClient.CreateAttributeValue(s.ctx, a.GetId(), &attributes.CreateAttributeValueRequest{
291+
Value: value1,
292+
})
293+
s.Require().NoError(err)
294+
295+
// Get attributes by fqns with a solo value
296+
fqns := []string{fqn1}
297+
attributeAndValues, err := s.db.PolicyClient.GetAttributesByValueFqns(s.ctx, &attributes.GetAttributeValuesByFqnsRequest{
298+
Fqns: fqns,
299+
WithValue: &policy.AttributeValueSelector{
300+
WithSubjectMaps: true,
301+
},
302+
})
303+
s.Require().NoError(err)
304+
305+
// Verify attribute1 is sole attribute
306+
s.Len(attributeAndValues, 1)
307+
val, ok := attributeAndValues[fqn1]
308+
s.True(ok)
309+
s.Equal(a.GetId(), val.GetAttribute().GetId())
310+
311+
s.Equal(v1.GetId(), val.GetAttribute().GetValues()[0].GetId())
312+
s.Equal(v1.GetValue(), val.GetValue().GetValue())
313+
314+
s.Equal(v1.GetValue(), val.GetAttribute().GetValues()[0].GetValue())
315+
s.Equal(v1.GetId(), val.GetValue().GetId())
316+
317+
// Create attribute value2
318+
v2, err := s.db.PolicyClient.CreateAttributeValue(s.ctx, a.GetId(), &attributes.CreateAttributeValueRequest{
319+
Value: value2,
320+
})
321+
s.Require().NoError(err)
322+
323+
// Create attribute value3
324+
v3, err := s.db.PolicyClient.CreateAttributeValue(s.ctx, a.GetId(), &attributes.CreateAttributeValueRequest{
325+
Value: value3,
326+
})
327+
s.Require().NoError(err)
328+
s.NotNil(v3)
329+
330+
// Get attributes by fqns with all three values
331+
fqns = []string{fqn1, fqn2, fqn3}
332+
attributeAndValues, err = s.db.PolicyClient.GetAttributesByValueFqns(s.ctx, &attributes.GetAttributeValuesByFqnsRequest{
333+
Fqns: fqns,
334+
WithValue: &policy.AttributeValueSelector{
335+
WithSubjectMaps: true,
336+
},
337+
})
338+
s.Require().NoError(err)
339+
s.Len(attributeAndValues, 3)
340+
341+
val, ok = attributeAndValues[fqn2]
342+
s.True(ok)
343+
s.Equal(a.GetId(), val.GetAttribute().GetId())
344+
345+
val, ok = attributeAndValues[fqn3]
346+
s.True(ok)
347+
s.Equal(a.GetId(), val.GetAttribute().GetId())
348+
349+
// ensure fqns are properly found in response for each value
350+
for fqn, attrAndVal := range attributeAndValues {
351+
values := attrAndVal.GetAttribute().GetValues()
352+
s.Equal(fqn, attrAndVal.GetValue().GetFqn())
353+
for i, v := range values {
354+
s.Equal(fqns[i], v.GetFqn())
355+
switch {
356+
case v.GetId() == v1.GetId():
357+
s.Equal(v1.GetId(), v.GetId())
358+
s.Equal(v1.GetValue(), v.GetValue())
359+
case v.GetId() == v2.GetId():
360+
s.Equal(v2.GetId(), v.GetId())
361+
s.Equal(v2.GetValue(), v.GetValue())
362+
case v.GetId() == v3.GetId():
363+
s.Equal(v3.GetId(), v.GetId())
364+
s.Equal(v3.GetValue(), v.GetValue())
365+
default:
366+
s.Fail("unexpected value", v)
367+
}
368+
}
369+
}
370+
}
371+
265372
func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_WithDeactivatedNamespace() {
266373
// create a new namespace
267374
ns, err := s.db.PolicyClient.CreateNamespace(s.ctx, &namespaces.CreateNamespaceRequest{
@@ -369,7 +476,7 @@ func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_WithDeactivatedAt
369476
func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_WithDeactivatedAttributeValue() {
370477
// create a new namespace
371478
ns, err := s.db.PolicyClient.CreateNamespace(s.ctx, &namespaces.CreateNamespaceRequest{
372-
Name: "test_fqn_namespace.goodbye",
479+
Name: "test_fqn_namespace.example",
373480
})
374481
s.Require().NoError(err)
375482

@@ -378,20 +485,17 @@ func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_WithDeactivatedAt
378485
NamespaceId: ns.GetId(),
379486
Name: "deactivating_attr",
380487
Rule: policy.AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_ANY_OF,
488+
Values: []string{"value1", "value2"},
381489
})
382490
s.Require().NoError(err)
383-
384-
v1, err := s.db.PolicyClient.CreateAttributeValue(s.ctx, attr.GetId(), &attributes.CreateAttributeValueRequest{
385-
Value: "value1",
386-
})
491+
got, _ := s.db.PolicyClient.GetAttribute(s.ctx, attr.GetId())
387492
s.Require().NoError(err)
493+
values := got.GetValues()
494+
s.Len(values, 2)
495+
v1 := values[0]
496+
v2 := values[1]
388497

389-
v2, err := s.db.PolicyClient.CreateAttributeValue(s.ctx, attr.GetId(), &attributes.CreateAttributeValueRequest{
390-
Value: "value2",
391-
})
392-
s.Require().NoError(err)
393-
394-
// deactivate the first attribute value only
498+
// deactivate an attribute value
395499
_, err = s.db.PolicyClient.DeactivateAttributeValue(s.ctx, v1.GetId())
396500
s.Require().NoError(err)
397501

@@ -414,7 +518,142 @@ func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_WithDeactivatedAt
414518
},
415519
})
416520
s.Require().NoError(err)
417-
s.Len(v, 1)
521+
s.NotNil(v)
522+
}
523+
524+
// UnsafeReactivateAttributevalue: active namespace, inactive definition, unsafely active value (fails)
525+
func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_InactiveDef_ActiveNsAndValue() {
526+
// create a new namespace
527+
ns, err := s.db.PolicyClient.CreateNamespace(s.ctx, &namespaces.CreateNamespaceRequest{
528+
Name: "test_namespace.uk",
529+
})
530+
s.Require().NoError(err)
531+
532+
// give it an attribute with two values
533+
attr, err := s.db.PolicyClient.CreateAttribute(s.ctx, &attributes.CreateAttributeRequest{
534+
NamespaceId: ns.GetId(),
535+
Name: "deactivating_attr",
536+
Rule: policy.AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_ANY_OF,
537+
Values: []string{"value1", "value2"},
538+
})
539+
s.Require().NoError(err)
540+
got, _ := s.db.PolicyClient.GetAttribute(s.ctx, attr.GetId())
541+
s.Require().NoError(err)
542+
values := got.GetValues()
543+
s.Len(values, 2)
544+
v1 := values[0]
545+
546+
// deactivate the attribute definition
547+
_, err = s.db.PolicyClient.DeactivateAttribute(s.ctx, attr.GetId())
548+
s.Require().NoError(err)
549+
550+
// unsafely reactivate the first attribute value
551+
v, err := s.db.PolicyClient.UnsafeReactivateAttributeValue(s.ctx, v1.GetId())
552+
s.Require().NoError(err)
553+
s.NotNil(v)
554+
555+
// get the attribute by the value fqn for v1
556+
retrieved, err := s.db.PolicyClient.GetAttributesByValueFqns(s.ctx, &attributes.GetAttributeValuesByFqnsRequest{
557+
Fqns: []string{fqnBuilder(ns.GetName(), attr.GetName(), v1.GetValue())},
558+
WithValue: &policy.AttributeValueSelector{
559+
WithSubjectMaps: true,
560+
},
561+
})
562+
s.Require().Error(err)
563+
s.Nil(retrieved)
564+
s.Require().ErrorIs(err, db.ErrNotFound)
565+
}
566+
567+
// UnsafeReactivateAttributevalue: inactive namespace, inactive definition, unsafely active value (fails)
568+
func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_InactiveNsAndDef_ActiveValue() {
569+
// create a new namespace
570+
ns, err := s.db.PolicyClient.CreateNamespace(s.ctx, &namespaces.CreateNamespaceRequest{
571+
Name: "test_inactive_namespace.co",
572+
})
573+
s.Require().NoError(err)
574+
575+
// give it an attribute with two values
576+
attr, err := s.db.PolicyClient.CreateAttribute(s.ctx, &attributes.CreateAttributeRequest{
577+
NamespaceId: ns.GetId(),
578+
Name: "deactivating_attr",
579+
Rule: policy.AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_ANY_OF,
580+
Values: []string{"value1", "value2"},
581+
})
582+
s.Require().NoError(err)
583+
got, _ := s.db.PolicyClient.GetAttribute(s.ctx, attr.GetId())
584+
s.Require().NoError(err)
585+
values := got.GetValues()
586+
s.Len(values, 2)
587+
v1 := values[0]
588+
589+
// deactivate the namespace
590+
_, err = s.db.PolicyClient.DeactivateNamespace(s.ctx, ns.GetId())
591+
s.Require().NoError(err)
592+
593+
// unsafely reactivate the first attribute value
594+
v, err := s.db.PolicyClient.UnsafeReactivateAttributeValue(s.ctx, v1.GetId())
595+
s.Require().NoError(err)
596+
s.NotNil(v)
597+
598+
// get the attribute by the value fqn for v1
599+
retrieved, err := s.db.PolicyClient.GetAttributesByValueFqns(s.ctx, &attributes.GetAttributeValuesByFqnsRequest{
600+
Fqns: []string{fqnBuilder(ns.GetName(), attr.GetName(), v1.GetValue())},
601+
WithValue: &policy.AttributeValueSelector{
602+
WithSubjectMaps: true,
603+
},
604+
})
605+
s.Require().Error(err)
606+
s.Nil(retrieved)
607+
s.Require().ErrorIs(err, db.ErrNotFound)
608+
}
609+
610+
// UnsafeReactivateNamespace: active namespace, inactive definition, inactive value (fails)
611+
func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_ActiveDef_InactiveNsAndValue() {
612+
// create a new namespace
613+
ns, err := s.db.PolicyClient.CreateNamespace(s.ctx, &namespaces.CreateNamespaceRequest{
614+
Name: "test_ns_active.uk",
615+
})
616+
s.Require().NoError(err)
617+
618+
// give it an attribute with two values
619+
attr, err := s.db.PolicyClient.CreateAttribute(s.ctx, &attributes.CreateAttributeRequest{
620+
NamespaceId: ns.GetId(),
621+
Name: "active_attr",
622+
Rule: policy.AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_ANY_OF,
623+
Values: []string{"value1", "value2"},
624+
})
625+
s.Require().NoError(err)
626+
got, _ := s.db.PolicyClient.GetAttribute(s.ctx, attr.GetId())
627+
s.Require().NoError(err)
628+
values := got.GetValues()
629+
s.Len(values, 2)
630+
v1 := values[0]
631+
632+
// deactivate the namespace
633+
ns, err = s.db.PolicyClient.DeactivateNamespace(s.ctx, ns.GetId())
634+
s.Require().NoError(err)
635+
s.NotNil(ns)
636+
637+
// reactivate the namespace (unsafely)
638+
ns, err = s.db.PolicyClient.UnsafeReactivateNamespace(s.ctx, ns.GetId())
639+
s.Require().NoError(err)
640+
s.NotNil(ns)
641+
642+
gotNs, err := s.db.PolicyClient.GetNamespace(s.ctx, ns.GetId())
643+
s.Require().NoError(err)
644+
s.NotNil(gotNs)
645+
s.True(gotNs.GetActive().GetValue())
646+
647+
// get the attribute by the value fqn for v1
648+
retrieved, err := s.db.PolicyClient.GetAttributesByValueFqns(s.ctx, &attributes.GetAttributeValuesByFqnsRequest{
649+
Fqns: []string{fqnBuilder(ns.GetName(), attr.GetName(), v1.GetValue())},
650+
WithValue: &policy.AttributeValueSelector{
651+
WithSubjectMaps: true,
652+
},
653+
})
654+
s.Require().Error(err)
655+
s.Nil(retrieved)
656+
s.Require().ErrorIs(err, db.ErrNotFound)
418657
}
419658

420659
func (s *AttributeFqnSuite) TestGetAttributesByValueFqns_Fails_WithNonValueFqns() {

0 commit comments

Comments
 (0)