Skip to content

Commit

Permalink
experimental repro for go-openapi#147
Browse files Browse the repository at this point in the history
Signed-off-by: Frédéric BIDON <fredbi@yahoo.com>
  • Loading branch information
fredbi committed Dec 14, 2023
1 parent 442694d commit 5cf4dbe
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 2 deletions.
80 changes: 78 additions & 2 deletions middleware/route_authenticator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ type countAuthenticator struct {
err error
}

type principalType struct {
Name string
}

func (c *countAuthenticator) Authenticate(_ interface{}) (bool, interface{}, error) {
c.count++
return c.applies, c.principal, c.err
Expand All @@ -37,18 +41,28 @@ var (
noApplyAuth = runtime.AuthenticatorFunc(func(_ interface{}) (bool, interface{}, error) {
return false, nil, nil
})
successAuthWithPointer = runtime.AuthenticatorFunc(func(_ interface{}) (bool, interface{}, error) {
return true, &principalType{Name: "the user"}, nil
})
failAuthWithPointer = runtime.AuthenticatorFunc(func(_ interface{}) (bool, interface{}, error) {
var typedPrincipal *principalType
return true, typedPrincipal, errors.New("unauthenticated")
})
failAuthWithNilPointer = runtime.AuthenticatorFunc(func(_ interface{}) (bool, interface{}, error) {
var typedPrincipal *principalType
return true, typedPrincipal, nil
})
)

func TestAuthenticateSingle(t *testing.T) {
ra := RouteAuthenticator{
Authenticator: map[string]runtime.Authenticator{
"auth1": successAuth,
"auth1": successAuthWithPointer,
},
Schemes: []string{"auth1"},
Scopes: map[string][]string{"auth1": nil},
}
ras := RouteAuthenticators([]RouteAuthenticator{ra})

require.False(t, ras.AllowsAnonymous())

req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/", nil)
Expand All @@ -61,6 +75,68 @@ func TestAuthenticateSingle(t *testing.T) {
require.Equal(t, ra, *route.Authenticator)
}

func TestAuthenticateWrong(t *testing.T) {
t.Run("with principal as a pointer to a concrete type", func(t *testing.T) {
t.Run("should authenticate", func(t *testing.T) {
ra := RouteAuthenticator{
Authenticator: map[string]runtime.Authenticator{
"auth1": successAuthWithPointer,
},
Schemes: []string{"auth1"},
Scopes: map[string][]string{"auth1": nil},
}
ras := RouteAuthenticators([]RouteAuthenticator{ra})

require.False(t, ras.AllowsAnonymous())

req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/", nil)
route := &MatchedRoute{}
ok, prin, err := ras.Authenticate(req, route)
require.NoError(t, err)
require.True(t, ok)
require.EqualValues(t, &principalType{Name: "the user"}, prin)
})
t.Run("should not authenticate", func(t *testing.T) {
ra := RouteAuthenticator{
Authenticator: map[string]runtime.Authenticator{
"auth1": failAuthWithPointer,
},
Schemes: []string{"auth1"},
Scopes: map[string][]string{"auth1": nil},
}
ras := RouteAuthenticators([]RouteAuthenticator{ra})

require.False(t, ras.AllowsAnonymous())

req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/", nil)
route := &MatchedRoute{}
ok, prin, err := ras.Authenticate(req, route)
require.Error(t, err)
require.True(t, ok)
require.Nil(t, prin)
})
t.Run("should yield nil principal", func(t *testing.T) {
ra := RouteAuthenticator{
Authenticator: map[string]runtime.Authenticator{
"auth1": failAuthWithNilPointer,
},
Schemes: []string{"auth1"},
Scopes: map[string][]string{"auth1": nil},
}
ras := RouteAuthenticators([]RouteAuthenticator{ra})

require.False(t, ras.AllowsAnonymous())

req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/", nil)
route := &MatchedRoute{}
ok, prin, err := ras.Authenticate(req, route)
require.NoError(t, err)
require.True(t, ok)
require.Nil(t, prin)
})
})
}

func TestAuthenticateLogicalOr(t *testing.T) {
ra1 := RouteAuthenticator{
Authenticator: map[string]runtime.Authenticator{
Expand Down
4 changes: 4 additions & 0 deletions middleware/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ package middleware

import (
"fmt"
"log"
"net/http"
fpath "path"
"regexp"
"strings"

"github.com/davecgh/go-spew/spew"
"github.com/go-openapi/runtime/security"
"github.com/go-openapi/swag"

Expand Down Expand Up @@ -265,12 +267,14 @@ func (ras RouteAuthenticators) Authenticate(req *http.Request, route *MatchedRou
continue
}
applies, usr, err := ra.Authenticate(req, route)
log.Printf("DEBUG: %v, nil? %t, err: %v", spew.Sdump(usr), usr == nil, err)
if !applies || err != nil || usr == nil {
if err != nil {
lastError = err
}
continue
}
log.Printf("DEBUG exit 1: applies: %t, user=%v, usr==nil? %t, err: %v", applies, spew.Sdump(usr), usr == nil, err)
return applies, usr, nil
}

Expand Down

0 comments on commit 5cf4dbe

Please sign in to comment.