Skip to content

Commit

Permalink
feat: Auth refactoring to support single version token (argoproj#1998)
Browse files Browse the repository at this point in the history
  • Loading branch information
sarabala1979 authored Jan 21, 2020
1 parent eb360d6 commit f8569ae
Show file tree
Hide file tree
Showing 19 changed files with 149 additions and 269 deletions.
2 changes: 1 addition & 1 deletion cmd/argo/commands/archive/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func NewDeleteCommand() *cobra.Command {
Run: func(cmd *cobra.Command, args []string) {
for _, uid := range args {
conn := client.GetClientConn()
ctx := client.ContextWithAuthorization()
ctx := client.GetContext()
client := workflowarchive.NewArchivedWorkflowServiceClient(conn)
_, err := client.DeleteArchivedWorkflow(ctx, &workflowarchive.DeleteArchivedWorkflowRequest{
Uid: uid,
Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/archive/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func NewGetCommand() *cobra.Command {
}
uid := args[0]
conn := client.GetClientConn()
ctx := client.ContextWithAuthorization()
ctx := client.GetContext()
client := workflowarchive.NewArchivedWorkflowServiceClient(conn)
wf, err := client.GetArchivedWorkflow(ctx, &workflowarchive.GetArchivedWorkflowRequest{
Uid: uid,
Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/archive/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func NewListCommand() *cobra.Command {
Use: "list",
Run: func(cmd *cobra.Command, args []string) {
conn := client.GetClientConn()
ctx := client.ContextWithAuthorization()
ctx := client.GetContext()
client := workflowarchive.NewArchivedWorkflowServiceClient(conn)
resp, err := client.ListArchivedWorkflows(ctx, &workflowarchive.ListArchivedWorkflowsRequest{
ListOptions: &metav1.ListOptions{FieldSelector: "metadata.namespace=" + namespace},
Expand Down
6 changes: 5 additions & 1 deletion cmd/argo/commands/client/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ func GetClientConn() *grpc.ClientConn {
return conn
}

func ContextWithAuthorization() context.Context {
func GetContext() context.Context {
token := GetBearerToken()
if token == "" {
return context.Background()
}
return metadata.NewOutgoingContext(context.Background(), metadata.Pairs("grpcgateway-authorization", "Bearer "+GetBearerToken()))
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,5 @@ func (c LazyWorkflowTemplateGetter) Get(name string) (*wfv1.WorkflowTemplate, er
var _ templateresolution.WorkflowTemplateNamespacedGetter = &LazyWorkflowTemplateGetter{}

func GetWFApiServerGRPCClient(conn *grpc.ClientConn) (wfApiServer.WorkflowServiceClient, context.Context) {
return wfApiServer.NewWorkflowServiceClient(conn), client.ContextWithAuthorization()
return wfApiServer.NewWorkflowServiceClient(conn), client.GetContext()
}
2 changes: 1 addition & 1 deletion cmd/argo/commands/template/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,5 @@ func (c LazyWorkflowTemplateGetter) Get(name string) (*wfv1.WorkflowTemplate, er
var _ templateresolution.WorkflowTemplateNamespacedGetter = &LazyWorkflowTemplateGetter{}

func GetWFtmplApiServerGRPCClient(conn *grpc.ClientConn) (wftmplApiServer.WorkflowTemplateServiceClient, context.Context) {
return wftmplApiServer.NewWorkflowTemplateServiceClient(conn), client.ContextWithAuthorization()
return wftmplApiServer.NewWorkflowTemplateServiceClient(conn), client.GetContext()
}
22 changes: 11 additions & 11 deletions cmd/server/auth/gatekeeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ func (s Gatekeeper) useHybridAuth() bool {
return s.authType == Hybrid
}

func (s Gatekeeper) useClientAuth(md metadata.MD) (bool, error) {
if s.authType == Client && len(md.Get("grpcgateway-authorization")) == 0 {
return false, status.Error(codes.Unauthenticated, "Auth Token is not found")
func (s Gatekeeper) useClientAuth(md metadata.MD) bool {
if s.authType == Client {
return true
}
if s.useHybridAuth() && len(md.Get("grpcgateway-authorization")) > 0 {
return true, nil
return true
}
return true, nil
return false
}
func (s Gatekeeper) getClients(ctx context.Context) (versioned.Interface, kubernetes.Interface, error) {

Expand All @@ -106,16 +106,16 @@ func (s Gatekeeper) getClients(ctx context.Context) (versioned.Interface, kubern
}
return nil, nil, status.Error(codes.Unauthenticated, "unable to get metadata from incoming context")
}
useClientAuth, err := s.useClientAuth(md)
if err != nil {
return nil, nil, status.Errorf(codes.Unauthenticated, "auth token is not present in the request: %v", err)
}
if !useClientAuth {

if !s.useClientAuth(md) {
return s.wfClient, s.kubeClient, nil
}

token := ""
authorization := md.Get("grpcgateway-authorization")
token := strings.TrimPrefix(authorization[0], "Bearer ")
if len(authorization) > 0 {
token = strings.TrimPrefix(authorization[0], "Bearer ")
}

restConfig, err := kubeconfig.GetRestConfig(token)
if err != nil {
Expand Down
20 changes: 12 additions & 8 deletions test/e2e/argo_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"testing"
"time"

wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
"github.com/argoproj/argo/test/e2e/fixtures"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
Expand All @@ -17,10 +19,6 @@ import (
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"

wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
"github.com/argoproj/argo/test/e2e/fixtures"
"github.com/argoproj/argo/util/kubeconfig"
)

const baseUrl = "http://localhost:2746"
Expand All @@ -35,10 +33,11 @@ type ArgoServerSuite struct {
func (s *ArgoServerSuite) BeforeTest(suiteName, testName string) {
s.E2ESuite.BeforeTest(suiteName, testName)
var err error
s.bearerToken, err = kubeconfig.GetBearerToken(s.RestConfig)
s.bearerToken, err = s.GetServiceAccountToken()
if err != nil {
panic(err)
}

}

func (s *ArgoServerSuite) AfterTest(suiteName, testName string) {
Expand Down Expand Up @@ -75,7 +74,7 @@ func (s *ArgoServerSuite) TestInfo() {
func (s *ArgoServerSuite) TestUnauthorized() {
token := s.bearerToken
defer func() { s.bearerToken = token }()
s.bearerToken = ""
s.bearerToken = "test-token"
s.e(s.T()).GET("/api/v1/workflows/argo").
Expect().
Status(401)
Expand Down Expand Up @@ -578,7 +577,7 @@ func (s *ArgoServerSuite) TestWorkflowStream() {
When().
SubmitWorkflow()

time.Sleep(1 * time.Second)
time.Sleep(2 * time.Second)

// use the watch to make sure that the workflow has succeeded
s.Run("Watch", func(t *testing.T) {
Expand All @@ -589,7 +588,12 @@ func (s *ArgoServerSuite) TestWorkflowStream() {
req.Close = true
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
defer func() { _ = resp.Body.Close() }()
assert.NotNil(t, resp)
defer func() {
if resp != nil {
_ = resp.Body.Close()
}
}()
if assert.Equal(t, 200, resp.StatusCode) {
assert.Equal(t, resp.Header.Get("Content-Type"), "text/event-stream")
s := bufio.NewScanner(resp.Body)
Expand Down
5 changes: 4 additions & 1 deletion test/e2e/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type CLISuite struct {

func (s *CLISuite) BeforeTest(suiteName, testName string) {
s.E2ESuite.BeforeTest(suiteName, testName)

}

func (s *CLISuite) AfterTest(suiteName, testName string) {
Expand All @@ -35,7 +36,9 @@ func (s *CLISuite) TestCompletion() {
func (s *CLISuite) TestToken() {
s.Given().RunCli([]string{"token"}, func(t *testing.T, output string, err error) {
assert.NoError(t, err)
assert.Equal(t, "v2:password", output)
token, err := s.GetServiceAccountToken()
assert.NoError(t, err)
assert.Equal(t, token, output)
})
}

Expand Down
26 changes: 25 additions & 1 deletion test/e2e/fixtures/e2e_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -60,13 +61,18 @@ func (s *E2ESuite) SetupSuite() {
}

func (s *E2ESuite) BeforeTest(_, _ string) {
s.SetEnv()

s.Diagnostics = &Diagnostics{}
var err error
s.RestConfig, err = kubeconfig.DefaultRestConfig()
if err != nil {
panic(err)
}
token, err := s.GetServiceAccountToken()
if err != nil {
panic(err)
}
s.SetEnv(token)
s.KubeClient, err = kubernetes.NewForConfig(s.RestConfig)
if err != nil {
panic(err)
Expand Down Expand Up @@ -176,6 +182,24 @@ func (s *E2ESuite) BeforeTest(_, _ string) {
_ = db.Close()
}

func (s *E2ESuite) GetServiceAccountToken() (string, error) {
// create the clientset
clientset, err := kubernetes.NewForConfig(s.RestConfig)
if err != nil {
return "", err
}
secretList, err := clientset.CoreV1().Secrets("argo").List(metav1.ListOptions{})
if err != nil {
return "", err
}
for _, sec := range secretList.Items {
if strings.HasPrefix(sec.Name, "argo-server-token") {
return string(sec.Data["token"]), nil
}
}
return "", nil
}

func (s *E2ESuite) Run(name string, f func(t *testing.T)) {
t := s.T()
if t.Failed() {
Expand Down
8 changes: 3 additions & 5 deletions test/e2e/fixtures/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ import "os"
type Env struct {
}

func (s *Env) SetEnv() {
func (s *Env) SetEnv(token string) {
_ = os.Setenv("ARGO_SERVER", "localhost:2746")
_ = os.Setenv("ARGO_TOKEN_VERSION", "v2")
_ = os.Setenv("ARGO_V2_TOKEN", "password")
_ = os.Setenv("ARGO_TOKEN", token)
}
func (s *Env) UnsetEnv() {
_ = os.Unsetenv("ARGO_SERVER")
_ = os.Unsetenv("ARGO_TOKEN_VERSION")
_ = os.Unsetenv("ARGO_V2_TOKEN")
_ = os.Unsetenv("ARGO_TOKEN")
}
3 changes: 3 additions & 0 deletions test/e2e/fixtures/util.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package fixtures

import (
"os"
"os/exec"

log "github.com/sirupsen/logrus"
)

func runCli(diagnostics *Diagnostics, args []string) (string, error) {
runArgs := append([]string{"-n", Namespace}, args...)
cmd := exec.Command("../../dist/argo", runArgs...)
cmd.Env = os.Environ()
output, err := exec.Command("../../dist/argo", runArgs...).CombinedOutput()
stringOutput := string(output)
diagnostics.Log(log.Fields{"args": args, "output": stringOutput, "err": err}, "Run CLI")
Expand Down
3 changes: 0 additions & 3 deletions test/e2e/manifests/postgres.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,6 @@ spec:
- client
- --loglevel
- debug
env:
- name: ARGO_V2_TOKEN
value: password
image: argoproj/argocli:latest
imagePullPolicy: Never
name: argo-server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,4 @@
- op: add
path: /spec/template/spec/containers/0/args/-
value: debug
- op: add
path: /spec/template/spec/containers/0/env
value:
- name: ARGO_V2_TOKEN
value: password

3 changes: 2 additions & 1 deletion ui/src/app/shared/services/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ const getToken = () => localStorage.getItem('token');

const auth = (req: SuperAgentRequest) => {
const token = getToken();
return (token !== null ? req.auth(token, {type: 'bearer'}) : req).on('error', handle);

return (token !== null && token !== '' ? req.auth(token, {type: 'bearer'}) : req).on('error', handle);
};

const handle = (err: any) => {
Expand Down
Loading

0 comments on commit f8569ae

Please sign in to comment.