Skip to content

Commit bc75edc

Browse files
authored
Handle permission denied error in Nexus HandleScheduleCommand (temporalio#8442)
## What changed? Nexus HandleScheduleCommand handles PermissionDenied by failing the WFT. ## Why? We want to distinguish between Nexus endpoint not found and caller namespace unauthorized errors. ## How did you test it? - [ ] built - [ ] run locally and tested manually - [ ] covered by existing tests - [x] added new unit test(s) - [ ] added new functional test(s) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Handle `PermissionDenied` from endpoint lookup by failing the workflow task and add a targeted unit test. > > - **Workflow command handling** (`components/nexusoperations/workflow/commands.go`): > - On `GetByName` error `PermissionDenied`, return `FailWorkflowTaskError` with cause `WORKFLOW_TASK_FAILED_CAUSE_BAD_SCHEDULE_NEXUS_OPERATION_ATTRIBUTES` and an authorization message, instead of propagating the error. > - **Tests** (`components/nexusoperations/workflow/commands_test.go`): > - Extend fake endpoint registry to simulate `PermissionDenied` for a specific endpoint name. > - Add test "caller namespace unauthorized" asserting WFT failure and no history events. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7585f5a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 13dcce5 commit bc75edc

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

components/nexusoperations/workflow/commands.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ func (ch *commandHandler) HandleScheduleCommand(
6363
}
6464
}
6565
// Ignore, and let the operation fail when the task is executed.
66+
} else if errors.As(err, new(*serviceerror.PermissionDenied)) {
67+
return workflow.FailWorkflowTaskError{
68+
Cause: enumspb.WORKFLOW_TASK_FAILED_CAUSE_BAD_SCHEDULE_NEXUS_OPERATION_ATTRIBUTES,
69+
Message: fmt.Sprintf("caller namespace %q unauthorized for %q", ns.Name(), attrs.Endpoint),
70+
}
6671
} else {
6772
return err
6873
}

components/nexusoperations/workflow/commands_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ var defaultConfig = &nexusoperations.Config{
5959
func newTestContext(t *testing.T, cfg *nexusoperations.Config) testContext {
6060
endpointReg := nexustest.FakeEndpointRegistry{
6161
OnGetByName: func(ctx context.Context, namespaceID namespace.ID, endpointName string) (*persistencespb.NexusEndpointEntry, error) {
62-
if endpointName != "endpoint" {
62+
if endpointName == "endpoint caller namespace unauthorized" {
63+
return nil, serviceerror.NewPermissionDenied("caller namespace unauthorized", "")
64+
} else if endpointName != "endpoint" {
6365
return nil, serviceerror.NewNotFound("endpoint not found")
6466
}
6567
// Only the ID is taken here.
@@ -168,6 +170,24 @@ func TestHandleScheduleCommand(t *testing.T) {
168170
require.Equal(t, 1, len(tcx.history.Events))
169171
})
170172

173+
t.Run("caller namespace unauthorized", func(t *testing.T) {
174+
tcx := newTestContext(t, defaultConfig)
175+
err := tcx.scheduleHandler(context.Background(), tcx.ms, commandValidator{maxPayloadSize: 1}, 1, &commandpb.Command{
176+
Attributes: &commandpb.Command_ScheduleNexusOperationCommandAttributes{
177+
ScheduleNexusOperationCommandAttributes: &commandpb.ScheduleNexusOperationCommandAttributes{
178+
Endpoint: "endpoint caller namespace unauthorized",
179+
Service: "service",
180+
Operation: "op",
181+
},
182+
},
183+
})
184+
var failWFTErr workflow.FailWorkflowTaskError
185+
require.ErrorAs(t, err, &failWFTErr)
186+
require.False(t, failWFTErr.TerminateWorkflow)
187+
require.Equal(t, enumspb.WORKFLOW_TASK_FAILED_CAUSE_BAD_SCHEDULE_NEXUS_OPERATION_ATTRIBUTES, failWFTErr.Cause)
188+
require.Equal(t, 0, len(tcx.history.Events))
189+
})
190+
171191
t.Run("exceeds max service length", func(t *testing.T) {
172192
tcx := newTestContext(t, defaultConfig)
173193
err := tcx.scheduleHandler(context.Background(), tcx.ms, commandValidator{maxPayloadSize: 1}, 1, &commandpb.Command{

0 commit comments

Comments
 (0)