Skip to content

Commit

Permalink
feat: identify subject by external_id
Browse files Browse the repository at this point in the history
ENG-2125
  • Loading branch information
jakubtomany committed Dec 12, 2023
1 parent 67f7ffc commit 9f1044c
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 15 deletions.
7 changes: 7 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,10 @@ issues:
- govet
text: 'fieldalignment:'
path: .*_test.go$

# We want to allow import gomega and ginkgo (+ all sub-packages) in tests files only
- linters:
- revive
text: '^dot-imports:'
source: . "github.com/onsi/(gomega|ginkgo)(/.*)?"
path: .*_test.go
9 changes: 7 additions & 2 deletions functions/is_authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,18 @@ func init() {
}, nil),
types.NewObject([]*types.StaticProperty{
types.NewStaticProperty("id", types.S),
types.NewStaticProperty("type", types.S),
types.NewStaticProperty("subjectType", types.S),
}, nil),
types.NewObject([]*types.StaticProperty{
types.NewStaticProperty("id", types.S),
types.NewStaticProperty("type", types.S),
types.NewStaticProperty("subjectType", types.S),
types.NewStaticProperty("property", types.S),
}, nil),
types.NewObject([]*types.StaticProperty{
types.NewStaticProperty("id", types.S),
types.NewStaticProperty("subjectType", types.S),
types.NewStaticProperty("type", types.S),
}, nil),
)),
types.Named("resources", types.NewArray(nil, types.NewObject([]*types.StaticProperty{
types.NewStaticProperty("externalId", types.S),
Expand Down
25 changes: 20 additions & 5 deletions functions/is_authorization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ var _ = Describe("indy.is_authorized", func() {
respTTL: durationpb.New(time.Minute * 90),
decisionTimeMatcher: BeEquivalentTo("1645543102"), // All numbers are json.Number ie string
ttlMatcher: BeEquivalentTo("5400"),
regoParam1: `{"id": "` + testAccessToken + `", "type": "token"}`,
regoParam1: `{"id": "` + testAccessToken + `", "subjectType": "token"}`,
}),
Entry("DigitalTwin id", &dtIDCase{
reqSubject: &authorizationpb.Subject{
Expand All @@ -164,7 +164,7 @@ var _ = Describe("indy.is_authorized", func() {
respTTL: durationpb.New(time.Minute * 90),
decisionTimeMatcher: BeEquivalentTo("1645543102"), // All numbers are json.Number ie string
ttlMatcher: BeEquivalentTo("5400"),
regoParam1: `{"id": "gid:AAAAFezuHiJHiUeRjrIJV8k3oKo", "type": "id"}`,
regoParam1: `{"id": "gid:AAAAFezuHiJHiUeRjrIJV8k3oKo", "subjectType": "id"}`,
}),
Entry("DigitalTwin property", &dtIDCase{
reqSubject: &authorizationpb.Subject{
Expand All @@ -179,7 +179,22 @@ var _ = Describe("indy.is_authorized", func() {
respTTL: durationpb.New(time.Minute * 90),
decisionTimeMatcher: BeEquivalentTo("1645543102"), // All numbers are json.Number ie string
ttlMatcher: BeEquivalentTo("5400"),
regoParam1: `{"id": "[email protected]", "type": "property", "property": "email"}`,
regoParam1: `{"id": "[email protected]", "subjectType": "property", "property": "email"}`,
}),
Entry("DigitalTwin externalID", &dtIDCase{
reqSubject: &authorizationpb.Subject{
Subject: &authorizationpb.Subject_ExternalId{
ExternalId: &authorizationpb.ExternalID{
Type: "Person",
ExternalId: "some-external-id",
},
},
},
respDecisionTime: timestamppb.New(time.Date(2022, 02, 22, 15, 18, 22, 0, time.UTC)),
respTTL: durationpb.New(time.Minute * 90),
decisionTimeMatcher: BeEquivalentTo("1645543102"), // All numbers are json.Number ie string
ttlMatcher: BeEquivalentTo("5400"),
regoParam1: `{"id": "some-external-id", "subjectType": "external_id", "type": "Person"}`,
}),
)

Expand Down Expand Up @@ -218,10 +233,10 @@ var _ = Describe("indy.is_authorized", func() {
Entry("Empty resource_references", `{"id": "`+testAccessToken+`"}, [], {}`,
"unable to call IsAuthorized client endpoint",
"invalid IsAuthorizedRequest.Resources: value must contain between 1 and 32 items, inclusive"),
Entry("Invalid digital twin", `{"id": "abc", "type": "id"}, [{"externalId": "res1", "type": "Type", "actions": ["READ"]}, {"externalId": "res2", "type": "Type", "actions": ["READ"]}], {}`,
Entry("Invalid digital twin", `{"id": "abc", "subjectType": "id"}, [{"externalId": "res1", "type": "Type", "actions": ["READ"]}, {"externalId": "res2", "type": "Type", "actions": ["READ"]}], {}`,
"unable to call IsAuthorized client endpoint",
"invalid DigitalTwin.Id: value length must be between 27 and 100 runes"),
Entry("Invalid propertyType", `{"id": "", "type": "property", "property": ""}, [{"externalId": "res1", "type": "Type", "actions": ["READ"]}, {"externalId": "res2", "type": "Type", "actions": ["READ"]}], {}`,
Entry("Invalid propertyType", `{"id": "", "subjectType": "property", "property": ""}, [{"externalId": "res1", "type": "Type", "actions": ["READ"]}, {"externalId": "res2", "type": "Type", "actions": ["READ"]}], {}`,
"unable to call IsAuthorized client endpoint",
"invalid Property.Type: value length must be between 2 and 20 runes"),
)
Expand Down
17 changes: 16 additions & 1 deletion functions/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const policyTagsKey = "policyTags"
const subjectTypeToken = "token"
const subjectTypeID = "id"
const subjectTypeProperty = "property"
const subjectTypeExternalID = "external_id"

var allowedKeyNames = [...]string{
inputParamsKey,
Expand Down Expand Up @@ -174,14 +175,28 @@ func extractSubject(subjectValue ast.Value, pos int) (*authorizationpb.Subject,
},
},
}, nil
case subjectTypeExternalID:
nodeTypeObject := subject.Get(ast.StringTerm("type"))
if nodeTypeObject == nil {
return nil, builtins.NewOperandTypeErr(pos, subjectValue, "type")
}
nodeType := nodeTypeObject.Value.(ast.String)
return &authorizationpb.Subject{
Subject: &authorizationpb.Subject_ExternalId{
ExternalId: &authorizationpb.ExternalID{
Type: string(nodeType),
ExternalId: string(idValue),
},
},
}, nil
}

// Next line is unreachable. OPA will complain based on declaration of function, when types do not match.
return nil, builtins.NewOperandTypeErr(pos, subjectValue, "object")
}

func getSubjectType(subject ast.Object) string {
typeObject := subject.Get(ast.StringTerm("type"))
typeObject := subject.Get(ast.StringTerm("subjectType"))
if typeObject == nil {
return subjectTypeToken
}
Expand Down
9 changes: 7 additions & 2 deletions functions/what_authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,18 @@ func init() {
}, nil),
types.NewObject([]*types.StaticProperty{
types.NewStaticProperty("id", types.S),
types.NewStaticProperty("type", types.S),
types.NewStaticProperty("subjectType", types.S),
}, nil),
types.NewObject([]*types.StaticProperty{
types.NewStaticProperty("id", types.S),
types.NewStaticProperty("type", types.S),
types.NewStaticProperty("subjectType", types.S),
types.NewStaticProperty("property", types.S),
}, nil),
types.NewObject([]*types.StaticProperty{
types.NewStaticProperty("id", types.S),
types.NewStaticProperty("subjectType", types.S),
types.NewStaticProperty("type", types.S),
}, nil),
)),
types.Named("resourcesTypes", types.NewArray(nil, types.NewAny(
types.NewObject([]*types.StaticProperty{
Expand Down
26 changes: 21 additions & 5 deletions functions/what_authorization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ var _ = Describe("indy.what_authorized", func() {
respTTL: durationpb.New(time.Minute * 90),
decisionTimeMatcher: BeEquivalentTo("1645543102"), // All numbers are json.Number ie string
ttlMatcher: BeEquivalentTo("5400"),
regoParam1: `{"id": "` + testAccessToken + `", "type": "token"}`,
regoParam1: `{"id": "` + testAccessToken + `", "subjectType": "token"}`,
}),
Entry("DigitalTwin", &dtIDCase{
reqSubject: &authorizationpb.Subject{
Expand All @@ -187,7 +187,7 @@ var _ = Describe("indy.what_authorized", func() {
respTTL: nil,
decisionTimeMatcher: BeEquivalentTo("0"),
ttlMatcher: BeEquivalentTo("0"),
regoParam1: `{"id": "gid:AAAAFezuHiJHiUeRjrIJV8k3oKo", "type": "id"}`,
regoParam1: `{"id": "gid:AAAAFezuHiJHiUeRjrIJV8k3oKo", "subjectType": "id"}`,
}),
Entry("DigitalTwin property", &dtIDCase{
reqSubject: &authorizationpb.Subject{
Expand All @@ -203,7 +203,23 @@ var _ = Describe("indy.what_authorized", func() {
respTTL: nil,
decisionTimeMatcher: BeEquivalentTo("0"),
ttlMatcher: BeEquivalentTo("0"),
regoParam1: `{"id": "[email protected]", "type": "property", "property": "email"}`,
regoParam1: `{"id": "[email protected]", "subjectType": "property", "property": "email"}`,
}),
Entry("DigitalTwin externalID", &dtIDCase{
reqSubject: &authorizationpb.Subject{
Subject: &authorizationpb.Subject_ExternalId{
ExternalId: &authorizationpb.ExternalID{
Type: "Person",
ExternalId: "some-external-id",
},
},
},
// Test also nil values
respDecisionTime: nil,
respTTL: nil,
decisionTimeMatcher: BeEquivalentTo("0"),
ttlMatcher: BeEquivalentTo("0"),
regoParam1: `{"id": "some-external-id", "subjectType": "external_id", "type": "Person"}`,
}),
)

Expand Down Expand Up @@ -239,10 +255,10 @@ var _ = Describe("indy.what_authorized", func() {
Entry("Empty resource_references", `{"id": "`+testAccessToken+`"}, [], {}`,
"unable to call WhatAuthorized client endpoint",
"invalid WhatAuthorizedRequest.ResourceTypes: value must contain between 1 and 10 items, inclusive"),
Entry("Invalid digital twin", `{"id": "abc", "type": "id"}, [{"type": "Type", "actions": ["READ"]}], {}`,
Entry("Invalid digital twin", `{"id": "abc", "subjectType": "id"}, [{"type": "Type", "actions": ["READ"]}], {}`,
"unable to call WhatAuthorized client endpoint",
"invalid DigitalTwin.Id: value length must be between 27 and 100 runes"),
Entry("Invalid propertyType", `{"id": "", "type": "property", "property": ""}, [{"type": "Type", "actions": ["READ"]}, {"type": "Type", "actions": ["READ"]}], {}`,
Entry("Invalid propertyType", `{"id": "", "subjectType": "property", "property": ""}, [{"type": "Type", "actions": ["READ"]}, {"type": "Type", "actions": ["READ"]}], {}`,
"unable to call WhatAuthorized client endpoint",
"invalid Property.Type: value length must be between 2 and 20 runes"),
)
Expand Down

0 comments on commit 9f1044c

Please sign in to comment.