Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/grpc/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docs/openapi/policy/actions/actions.openapi.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

314 changes: 158 additions & 156 deletions protocol/go/policy/actions/actions.pb.go

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions service/integration/actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,41 @@ func (s *ActionsSuite) Test_ListActions_FiltersCustomActionsByNamespace_Succeeds
s.False(foundSecond)
}

func (s *ActionsSuite) Test_ListActions_WithoutNamespace_ReturnsAcrossNamespaces_Succeeds() {
name := fmt.Sprintf("global-list-action-%d", time.Now().UnixNano())

inDefault, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
Name: name,
NamespaceId: s.defaultNamespaceID(),
})
s.Require().NoError(err)

inOther, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
Name: name,
NamespaceId: s.otherNamespaceID(),
})
s.Require().NoError(err)

list, err := s.db.PolicyClient.ListActions(s.ctx, &actions.ListActionsRequest{})
s.Require().NoError(err)

foundDefault := false
foundOther := false
for _, action := range list.GetActionsCustom() {
if action.GetId() == inDefault.GetId() {
foundDefault = true
s.Equal(s.defaultNamespaceID(), action.GetNamespace().GetId())
}
if action.GetId() == inOther.GetId() {
foundOther = true
s.Equal(s.otherNamespaceID(), action.GetNamespace().GetId())
}
}

s.True(foundDefault)
s.True(foundOther)
}
Comment thread
elizabethhealy marked this conversation as resolved.
Resolved

func (s *ActionsSuite) Test_ListActions_LegacyCustomAction_NamespaceProjection_Succeeds() {
legacy := s.f.GetCustomActionKey("custom_action_1")
assertLegacyProjected := func(list *actions.ListActionsResponse) {
Expand Down
13 changes: 8 additions & 5 deletions service/policy/actions/actions.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import "policy/selectors.proto";
*/
Comment thread
elizabethhealy marked this conversation as resolved.
Resolved

message GetActionRequest {
option (buf.validate.message).oneof = { fields: ["namespace_id", "namespace_fqn"], required: false };
option (buf.validate.message).cel = {
id: "namespace_required_for_name"
message: "Either namespace_id or namespace_fqn must be provided when getting an action by name"
Expand Down Expand Up @@ -54,12 +55,14 @@ message GetActionResponse {
}

message ListActionsRequest {
// Required
option (buf.validate.message).oneof = { fields: ["namespace_id", "namespace_fqn"], required: true };
// Optional
option (buf.validate.message).oneof = { fields: ["namespace_id", "namespace_fqn"], required: false };

// ID of the namespace. Required if namespace_fqn is not provided.
string namespace_id = 1 [(buf.validate.field).string.uuid = true];
// FQN of the namespace. Required if namespace_id is not provided.
// ID of the namespace to scope results. If omitted, returns actions across namespaces.
string namespace_id = 1 [
(buf.validate.field).string.uuid = true
];
// FQN of the namespace to scope results. If omitted, returns actions across namespaces.
string namespace_fqn = 2 [
(buf.validate.field).string = {
min_len : 1
Expand Down
16 changes: 7 additions & 9 deletions service/policy/actions/actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,17 @@ func (s *ActionSuite) Test_GetAction_Fails() {
}

func (s *ActionSuite) Test_ListActions_Succeeds() {
reqNoNamespace := &actions.ListActionsRequest{}
err := s.v.Validate(reqNoNamespace)
s.Require().NoError(err)

reqPaginated := &actions.ListActionsRequest{
NamespaceId: validUUID,
Pagination: &policy.PageRequest{
Limit: 1,
},
}
err := s.v.Validate(reqPaginated)
err = s.v.Validate(reqPaginated)
s.Require().NoError(err)

reqPaginated.Pagination.Offset = 100
Expand All @@ -259,15 +263,9 @@ func (s *ActionSuite) Test_ListActions_Succeeds() {
}

func (s *ActionSuite) Test_ListActions_Fails() {
// missing namespace
req := &actions.ListActionsRequest{}
err := s.v.Validate(req)
s.Require().Error(err)
s.Require().Contains(err.Error(), errMessageOneof)

// invalid namespace id
req = &actions.ListActionsRequest{NamespaceId: "invalid-uuid"}
err = s.v.Validate(req)
req := &actions.ListActionsRequest{NamespaceId: "invalid-uuid"}
err := s.v.Validate(req)
s.Require().Error(err)
s.Require().Contains(err.Error(), errMessageUUID)

Expand Down
68 changes: 46 additions & 22 deletions service/policy/db/actions.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 17 additions & 5 deletions service/policy/db/queries/actions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ WITH resolved_namespace AS (
counted AS (
SELECT COUNT(a.id) AS total
FROM actions a
JOIN resolved_namespace rn ON TRUE
WHERE a.is_standard = TRUE OR a.namespace_id = rn.id OR a.namespace_id IS NULL
LEFT JOIN resolved_namespace rn ON TRUE
WHERE
rn.id IS NULL
OR a.is_standard = TRUE
OR a.namespace_id = rn.id
OR a.namespace_id IS NULL
)
Comment thread
elizabethhealy marked this conversation as resolved.
Resolved
SELECT
a.id,
Expand All @@ -32,11 +36,12 @@ SELECT
)) as metadata,
a.is_standard,
CASE
WHEN a.namespace_id IS NULL THEN JSON_BUILD_OBJECT(
WHEN a.namespace_id IS NULL AND rn.id IS NOT NULL THEN JSON_BUILD_OBJECT(
Comment thread
elizabethhealy marked this conversation as resolved.
Resolved
'id', rn.id,
'name', rn.name,
'fqn', rn.fqn
)
WHEN a.namespace_id IS NULL THEN NULL
ELSE JSON_BUILD_OBJECT(
'id', n.id,
'name', n.name,
Expand All @@ -45,11 +50,18 @@ SELECT
END AS namespace,
counted.total
FROM actions a
JOIN resolved_namespace rn ON TRUE
LEFT JOIN resolved_namespace rn ON TRUE
LEFT JOIN attribute_namespaces n ON a.namespace_id = n.id
LEFT JOIN attribute_fqns ns_fqns ON ns_fqns.namespace_id = n.id AND ns_fqns.attribute_id IS NULL AND ns_fqns.value_id IS NULL
CROSS JOIN counted
WHERE a.is_standard = TRUE OR a.namespace_id = rn.id OR a.namespace_id IS NULL
WHERE
(
sqlc.narg('namespace_id')::uuid IS NULL
AND sqlc.narg('namespace_fqn')::text IS NULL
)
OR a.is_standard = TRUE
OR a.namespace_id = rn.id
OR a.namespace_id IS NULL
ORDER BY a.created_at DESC
LIMIT @limit_
OFFSET @offset_;
Expand Down
Loading