Skip to content

Commit

Permalink
Check service Check() to use wookie read
Browse files Browse the repository at this point in the history
  • Loading branch information
akajla09 committed Jun 21, 2023
1 parent db4e813 commit 7ad0c8c
Showing 1 changed file with 65 additions and 53 deletions.
118 changes: 65 additions & 53 deletions pkg/authz/check/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (svc CheckService) checkRule(ctx context.Context, authInfo *service.AuthInf
return true, decisionPath, nil
default:
if rule.OfType == "" && rule.WithRelation == "" {
return svc.Check(ctx, authInfo, CheckSpec{
match, decisionPath, _, err := svc.Check(ctx, authInfo, CheckSpec{
CheckWarrantSpec: CheckWarrantSpec{
ObjectType: warrantSpec.ObjectType,
ObjectId: warrantSpec.ObjectId,
Expand All @@ -202,6 +202,7 @@ func (svc CheckService) checkRule(ctx context.Context, authInfo *service.AuthInf
},
Debug: warrantCheck.Debug,
})
return match, decisionPath, err
}

matchingWarrants, err := svc.getMatchingSubjectsBySubjectType(ctx, warrantSpec.ObjectType, warrantSpec.ObjectId, rule.WithRelation, rule.OfType, warrantSpec.Context)
Expand All @@ -210,7 +211,7 @@ func (svc CheckService) checkRule(ctx context.Context, authInfo *service.AuthInf
}

for _, matchingWarrant := range matchingWarrants {
match, decisionPath, err := svc.Check(ctx, authInfo, CheckSpec{
match, decisionPath, _, err := svc.Check(ctx, authInfo, CheckSpec{
CheckWarrantSpec: CheckWarrantSpec{
ObjectType: matchingWarrant.Subject.ObjectType,
ObjectId: matchingWarrant.Subject.ObjectId,
Expand Down Expand Up @@ -247,7 +248,7 @@ func (svc CheckService) CheckMany(ctx context.Context, authInfo *service.AuthInf
if warrantCheck.Op == objecttype.InheritIfAllOf {
var processingTime int64
for _, warrantSpec := range warrantCheck.Warrants {
match, decisionPath, err := svc.Check(wkCtx, authInfo, CheckSpec{
match, decisionPath, _, err := svc.Check(wkCtx, authInfo, CheckSpec{
CheckWarrantSpec: warrantSpec,
Debug: warrantCheck.Debug,
})
Expand Down Expand Up @@ -293,7 +294,7 @@ func (svc CheckService) CheckMany(ctx context.Context, authInfo *service.AuthInf
if warrantCheck.Op == objecttype.InheritIfAnyOf {
var processingTime int64
for _, warrantSpec := range warrantCheck.Warrants {
match, decisionPath, err := svc.Check(wkCtx, authInfo, CheckSpec{
match, decisionPath, _, err := svc.Check(wkCtx, authInfo, CheckSpec{
CheckWarrantSpec: warrantSpec,
Debug: warrantCheck.Debug,
})
Expand Down Expand Up @@ -343,7 +344,7 @@ func (svc CheckService) CheckMany(ctx context.Context, authInfo *service.AuthInf
}

warrantSpec := warrantCheck.Warrants[0]
match, decisionPath, err := svc.Check(wkCtx, authInfo, CheckSpec{
match, decisionPath, _, err := svc.Check(wkCtx, authInfo, CheckSpec{
CheckWarrantSpec: warrantSpec,
Debug: warrantCheck.Debug,
})
Expand Down Expand Up @@ -390,74 +391,85 @@ func (svc CheckService) CheckMany(ctx context.Context, authInfo *service.AuthInf
return &checkResult, newWookie, nil
}

// TODO: wrap in WookieSafeRead
// Check returns true if the subject has a warrant (explicitly or implicitly) for given objectType:objectId#relation and context
func (svc CheckService) Check(ctx context.Context, authInfo *service.AuthInfo, warrantCheck CheckSpec) (match bool, decisionPath []warrant.WarrantSpec, err error) {
func (svc CheckService) Check(ctx context.Context, authInfo *service.AuthInfo, warrantCheck CheckSpec) (bool, []warrant.WarrantSpec, *wookie.Token, error) {
log.Ctx(ctx).Debug().Msgf("Checking for warrant %s", warrantCheck.String())

// Used to automatically append tenant context for session token w/ tenantId checks
if authInfo != nil && authInfo.TenantId != "" {
svc.appendTenantContext(&warrantCheck, authInfo.TenantId)
}

// Check for direct warrant match -> doc:readme#viewer@[10]
matchedWarrant, err := svc.getWithPolicyMatch(ctx, warrantCheck.CheckWarrantSpec)
if err != nil {
return false, decisionPath, err
}
var match bool
decisionPath := make([]warrant.WarrantSpec, 0)
var newWookie *wookie.Token
newWookie, e := svc.WookieSvc.WookieSafeRead(ctx, func(wkCtx context.Context) error {
// Check for direct warrant match -> doc:readme#viewer@[10]
matchedWarrant, err := svc.getWithPolicyMatch(ctx, warrantCheck.CheckWarrantSpec)
if err != nil {
return err
}

if matchedWarrant != nil {
return true, []warrant.WarrantSpec{*matchedWarrant}, nil
}
if matchedWarrant != nil {
match = true
decisionPath = []warrant.WarrantSpec{*matchedWarrant}
return nil
}

// Check against indirectly related warrants
matchingWarrants, err := svc.getMatchingSubjects(ctx, warrantCheck.ObjectType, warrantCheck.ObjectId, warrantCheck.Relation, warrantCheck.Context)
if err != nil {
return false, decisionPath, err
}
// Check against indirectly related warrants
matchingWarrants, err := svc.getMatchingSubjects(ctx, warrantCheck.ObjectType, warrantCheck.ObjectId, warrantCheck.Relation, warrantCheck.Context)
if err != nil {
return err
}

for _, matchingWarrant := range matchingWarrants {
if matchingWarrant.Subject.Relation == "" {
continue
}

match, decisionPath, _, err = svc.Check(ctx, authInfo, CheckSpec{
CheckWarrantSpec: CheckWarrantSpec{
ObjectType: matchingWarrant.Subject.ObjectType,
ObjectId: matchingWarrant.Subject.ObjectId,
Relation: matchingWarrant.Subject.Relation,
Subject: warrantCheck.Subject,
Context: warrantCheck.Context,
},
Debug: warrantCheck.Debug,
})
if err != nil {
return err
}

for _, matchingWarrant := range matchingWarrants {
if matchingWarrant.Subject.Relation == "" {
continue
if match {
decisionPath = append(decisionPath, matchingWarrant)
return nil
}
}

match, decisionPath, err := svc.Check(ctx, authInfo, CheckSpec{
CheckWarrantSpec: CheckWarrantSpec{
ObjectType: matchingWarrant.Subject.ObjectType,
ObjectId: matchingWarrant.Subject.ObjectId,
Relation: matchingWarrant.Subject.Relation,
Subject: warrantCheck.Subject,
Context: warrantCheck.Context,
},
Debug: warrantCheck.Debug,
})
// Attempt to match against defined rules for target relation
objectTypeSpec, _, err := svc.ObjectTypeSvc.GetByTypeId(ctx, warrantCheck.ObjectType)
if err != nil {
return false, decisionPath, err
return err
}

if match {
decisionPath = append(decisionPath, matchingWarrant)
return true, decisionPath, nil
relationRule := objectTypeSpec.Relations[warrantCheck.Relation]
match, decisionPath, err = svc.checkRule(ctx, authInfo, warrantCheck, &relationRule)
if err != nil {
return err
}
}

// Attempt to match against defined rules for target relation
objectTypeSpec, _, err := svc.ObjectTypeSvc.GetByTypeId(ctx, warrantCheck.ObjectType)
if err != nil {
return false, decisionPath, err
}

relationRule := objectTypeSpec.Relations[warrantCheck.Relation]
match, decisionPath, err = svc.checkRule(ctx, authInfo, warrantCheck, &relationRule)
if err != nil {
return false, decisionPath, err
}
if match {
return nil
}

if match {
return true, decisionPath, nil
match = false
return nil
})
if e != nil {
return false, decisionPath, nil, e
}

return false, decisionPath, nil
return match, decisionPath, newWookie, nil
}

func (svc CheckService) appendTenantContext(warrantCheck *CheckSpec, tenantId string) {
Expand Down

0 comments on commit 7ad0c8c

Please sign in to comment.