Skip to content

Commit 2856485

Browse files
fix(authorization): Hierarchy working in GetDecisions (#519)
Needed to provide additional scope to GetEntitlements for hierarchy attributes as the entity may not possess the specific resource attribute but an attribute higher/lower All rules working -- allof, anyof, hierarchy
1 parent a0e2747 commit 2856485

File tree

1 file changed

+53
-2
lines changed

1 file changed

+53
-2
lines changed

service/authorization/authorization.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func NewRegistration() serviceregistry.Registration {
4747
var retrieveAttributeDefinitions = func(ctx context.Context, ra *authorization.ResourceAttribute, sdk *otdf.SDK) (map[string]*attr.GetAttributeValuesByFqnsResponse_AttributeAndValue, error) {
4848
resp, err := sdk.Attributes.GetAttributeValuesByFqns(ctx, &attr.GetAttributeValuesByFqnsRequest{
4949
WithValue: &policy.AttributeValueSelector{
50-
WithSubjectMaps: true,
50+
WithSubjectMaps: false,
5151
},
5252
Fqns: ra.GetAttributeValueFqns(),
5353
})
@@ -86,14 +86,31 @@ func (as AuthorizationService) GetDecisions(ctx context.Context, req *authorizat
8686
attrVals = append(attrVals, v.GetValue())
8787
}
8888

89+
attrDefs, err = populateAttrDefValueFqns(attrDefs)
90+
if err != nil {
91+
return nil, err
92+
}
93+
94+
// get the relevent resource attribute fqns
95+
allPertinentFqnsRA := authorization.ResourceAttribute{
96+
AttributeValueFqns: ra.GetAttributeValueFqns(),
97+
}
98+
for _, attrDef := range attrDefs {
99+
if attrDef.GetRule() == policy.AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_HIERARCHY {
100+
for _, value := range attrDef.GetValues() {
101+
allPertinentFqnsRA.AttributeValueFqns = append(allPertinentFqnsRA.AttributeValueFqns, value.GetFqn())
102+
}
103+
}
104+
}
105+
89106
for _, ec := range dr.GetEntityChains() {
90107
//
91108
// TODO: we should already have the subject mappings here and be able to just use OPA to trim down the known data attr values to the ones matched up with the entities
92109
//
93110
entities := ec.GetEntities()
94111
req := authorization.GetEntitlementsRequest{
95112
Entities: entities,
96-
Scope: ra,
113+
Scope: &allPertinentFqnsRA,
97114
}
98115
ecEntitlements, err := retrieveEntitlements(ctx, &req, as)
99116
if err != nil {
@@ -225,3 +242,37 @@ func (as AuthorizationService) GetEntitlements(ctx context.Context, req *authori
225242
slog.DebugContext(ctx, "opa", "rsp", fmt.Sprintf("%+v", rsp))
226243
return rsp, nil
227244
}
245+
246+
// Build an fqn from a namespace, attribute name, and value
247+
func fqnBuilder(n string, a string, v string) (string, error) {
248+
fqn := "https://"
249+
switch {
250+
case n != "" && a != "" && v != "":
251+
return fqn + n + "/attr/" + a + "/value/" + v, nil
252+
case n != "" && a != "" && v == "":
253+
return fqn + n + "/attr/" + a, nil
254+
case n != "" && a == "":
255+
return fqn + n, nil
256+
default:
257+
return "", errors.New("invalid FQN, unable to build fqn")
258+
}
259+
}
260+
261+
// If there are missing fqns in the attribute definition fill them in using
262+
// information from the attr definition
263+
func populateAttrDefValueFqns(attrDefs []*policy.Attribute) ([]*policy.Attribute, error) {
264+
for i, attrDef := range attrDefs {
265+
ns := attrDef.GetNamespace().GetName()
266+
attr := attrDef.GetName()
267+
for j, value := range attrDef.GetValues() {
268+
if value.GetFqn() == "" {
269+
fqn, err := fqnBuilder(ns, attr, value.GetValue())
270+
if err != nil {
271+
return nil, err
272+
}
273+
attrDefs[i].Values[j].Fqn = fqn
274+
}
275+
}
276+
}
277+
return attrDefs, nil
278+
}

0 commit comments

Comments
 (0)