Skip to content

Commit 06c761b

Browse files
JoibelAnton Gilgur
and
Anton Gilgur
authored
Merge commit from fork
* fix(api): properly authorize GET workflow fallback to archive - the authorization was accidentally removed in f1ab5aa - also if no archived workflow is found, properly return the original error as per ac9e2de Signed-off-by: Anton Gilgur <[email protected]> * test: add permission assertions for GET WF archived fallback - the permission suite seemed to not have previously tested this - add good, bad, and fake token checks - where "bad" is valid, but unauthorized, while "fake" is valid in format, but not corresponding to a real token Signed-off-by: Anton Gilgur <[email protected]> * fix(test): assign `goodToken` initially - these tests were relying on ordering of assignments before, i.e. 1. good 2. bad 3. bad - should just assign before each test instead for simplicity / less complexity / less mistakes Signed-off-by: Anton Gilgur <[email protected]> --------- Signed-off-by: Anton Gilgur <[email protected]> Co-authored-by: Anton Gilgur <[email protected]>
1 parent ac40195 commit 06c761b

File tree

2 files changed

+51
-10
lines changed

2 files changed

+51
-10
lines changed

server/workflow/workflow_server.go

+20-8
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ func (s *workflowServer) ListWorkflows(ctx context.Context, req *workflowpkg.Wor
176176
if err != nil {
177177
return nil, err
178178
}
179+
179180
// verify if we have permission to list Workflows
180181
allowed, err := auth.CanI(ctx, "list", workflow.WorkflowPlural, options.Namespace, "")
181182
if err != nil {
@@ -664,7 +665,6 @@ func (s *workflowServer) PodLogs(req *workflowpkg.WorkflowLogRequest, ws workflo
664665
req.Name = wf.Name
665666

666667
err = ws.SendHeader(metadata.MD{})
667-
668668
if err != nil {
669669
return sutils.ToStatusError(err, codes.Internal)
670670
}
@@ -686,22 +686,34 @@ func (s *workflowServer) getWorkflow(ctx context.Context, wfClient versioned.Int
686686
log.Debugf("Resolved alias %s to workflow %s.\n", latestAlias, latest.Name)
687687
return latest, nil
688688
}
689-
var err error
689+
690690
wf, origErr := wfClient.ArgoprojV1alpha1().Workflows(namespace).Get(ctx, name, options)
691+
// fallback to retrieve from archived workflows
691692
if wf == nil || origErr != nil {
692-
wf, err = s.wfArchive.GetWorkflow("", namespace, name)
693+
allowed, err := auth.CanI(ctx, "get", workflow.WorkflowPlural, namespace, name)
693694
if err != nil {
694-
log.Errorf("failed to get live workflow: %v; failed to get archived workflow: %v", origErr, err)
695-
// We only return the original error to preserve the original status code.
696-
return nil, sutils.ToStatusError(origErr, codes.Internal)
695+
return nil, getWorkflowOrigErr(origErr, err)
697696
}
698-
if wf == nil {
699-
return nil, status.Error(codes.NotFound, "not found")
697+
if !allowed {
698+
err = status.Error(codes.PermissionDenied, "permission denied")
699+
return nil, getWorkflowOrigErr(origErr, err)
700+
}
701+
702+
wf, err = s.wfArchive.GetWorkflow("", namespace, name)
703+
if wf == nil || err != nil {
704+
return nil, getWorkflowOrigErr(origErr, err)
700705
}
701706
}
702707
return wf, nil
703708
}
704709

710+
// getWorkflowOrigErr only returns the original error to preserve the original status code
711+
// it logs out the new error
712+
func getWorkflowOrigErr(origErr error, err error) error {
713+
log.Errorf("failed to get live workflow: %v; failed to get archived workflow: %v", origErr, err)
714+
return sutils.ToStatusError(origErr, codes.Internal)
715+
}
716+
705717
func (s *workflowServer) validateWorkflow(wf *wfv1.Workflow) error {
706718
return sutils.ToStatusError(s.instanceIDService.Validate(wf), codes.InvalidArgument)
707719
}

test/e2e/argo_server_test.go

+31-2
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,9 @@ func (s *ArgoServerSuite) TestPermission() {
458458
badToken = string(secret.Data["token"])
459459
})
460460

461+
// fake / spoofed token
462+
fakeToken := "faketoken"
463+
461464
token := s.bearerToken
462465
defer func() { s.bearerToken = token }()
463466

@@ -561,8 +564,8 @@ func (s *ArgoServerSuite) TestPermission() {
561564
Status(200)
562565
})
563566

564-
// we've now deleted the workflow, but it is still in the archive, testing the archive
565-
// after deleting the workflow makes sure that we are no dependant of the workflow for authorization
567+
// we've now deleted the workflow, but it is still in the archive
568+
// testing the archive after deleting it makes sure that we are not dependent on a live workflow resource for authorization
566569

567570
// Test list archived WFs with good token
568571
s.Run("ListArchivedWFsGoodToken", func() {
@@ -602,7 +605,33 @@ func (s *ArgoServerSuite) TestPermission() {
602605
Status(403)
603606
})
604607

608+
// Test get wf w/ archive fallback with good token
609+
s.bearerToken = goodToken
610+
s.Run("GetWFsFallbackArchivedGoodToken", func() {
611+
s.e().GET("/api/v1/workflows/"+uid).
612+
WithQuery("listOptions.labelSelector", "workflows.argoproj.io/test").
613+
Expect().
614+
Status(200)
615+
})
616+
617+
// Test get wf w/ archive fallback with bad token
618+
s.bearerToken = badToken
619+
s.Run("GetWFsFallbackArchivedBadToken", func() {
620+
s.e().GET("/api/v1/workflows/" + uid).
621+
Expect().
622+
Status(403)
623+
})
624+
625+
// Test get wf w/ archive fallback with fake token
626+
s.bearerToken = fakeToken
627+
s.Run("GetWFsFallbackArchivedFakeToken", func() {
628+
s.e().GET("/api/v1/workflows/" + uid).
629+
Expect().
630+
Status(403)
631+
})
632+
605633
// Test deleting archived wf with bad token
634+
s.bearerToken = badToken
606635
s.Run("DeleteArchivedWFsBadToken", func() {
607636
s.e().DELETE("/api/v1/archived-workflows/" + uid).
608637
Expect().

0 commit comments

Comments
 (0)