Skip to content

Commit

Permalink
feat: allow one-off token handler targeting
Browse files Browse the repository at this point in the history
  • Loading branch information
wernerdweight committed Sep 9, 2024
1 parent 2737ca4 commit 3fc2768
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ Full configuration structure (only client configuration is mandatory, default va
// TTL: cache TTL in seconds - defaults to 3600 (1 hour)
TTL *time.Duration
}

// TargetOneOffTokenHandlers: list of handlers to target for one-off token authentication (optional; if you omit target handlers, all handlers will be targeted)
TargetOneOffTokenHandlers *[]string
// '.*' # all handlers
// '/v1/*' # all handlers starting with '/v1/'
// '/v1/some/path' # only '/v1/some/path' handler
}
```

Expand Down
9 changes: 9 additions & 0 deletions auth/config/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ func (p *Provider) GetExcludeHandlers() *[]string {
return p.config.ExcludeHandlers
}

func (p *Provider) GetTargetOneOffTokenHandlers() *[]string {
return p.config.TargetOneOffTokenHandlers
}

func (p *Provider) GetClientProvider() contract.ApiClientProviderInterface[contract.ApiClientInterface] {
return p.config.Client.Provider
}
Expand Down Expand Up @@ -201,6 +205,10 @@ func (p *Provider) Init(config contract.Config) {
if nil != config.Cache {
p.initCache(config)
}

if nil != config.TargetOneOffTokenHandlers {
p.config.TargetOneOffTokenHandlers = config.TargetOneOffTokenHandlers
}
}

var (
Expand Down Expand Up @@ -250,5 +258,6 @@ var ProviderInstance = &Provider{
Prefix: &defaultCachePrefix,
TTL: &defaultCacheTTL,
},
TargetOneOffTokenHandlers: nil,
},
}
10 changes: 10 additions & 0 deletions auth/config/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func (s *TestSuite) SetupTest() {
Prefix: &defaultCachePrefix,
TTL: &defaultCacheTTL,
},
TargetOneOffTokenHandlers: nil,
},
}
}
Expand Down Expand Up @@ -156,6 +157,15 @@ func (s *TestSuite) TestProvider_GetExcludeHandlers() {
s.Equal(&handlers, s.provider.GetExcludeHandlers())
}

func (s *TestSuite) TestProvider_GetTargetOneOffTokenHandlers() {
s.Nil(s.provider.GetTargetOneOffTokenHandlers())
handlers := []string{".*"}
s.provider.Init(contract.Config{
TargetOneOffTokenHandlers: &handlers,
})
s.Equal(&handlers, s.provider.GetTargetOneOffTokenHandlers())
}

func (s *TestSuite) TestProvider_GetClientProvider() {
s.Nil(s.provider.GetClientProvider())
s.provider.Init(contract.Config{
Expand Down
6 changes: 6 additions & 0 deletions auth/contract/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,10 @@ type Config struct {

// Cache: cache configuration (optional)
Cache *CacheConfig

// TargetOneOffTokenHandlers: list of handlers to target for one-off token authentication (optional; if you omit target handlers, all handlers will be targeted)
TargetOneOffTokenHandlers *[]string
// '.*' # all handlers
// '/v1/*' # all handlers starting with '/v1/'
// '/v1/some/path' # only '/v1/some/path' handler
}
2 changes: 2 additions & 0 deletions auth/contract/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const (
CacheDisabled
InvalidOneOffToken
InvalidFUPCookie
OneOffTokenNotAllowed
)

var AuthErrorCodes = map[AuthErrorCode]string{
Expand Down Expand Up @@ -74,6 +75,7 @@ var AuthErrorCodes = map[AuthErrorCode]string{
CacheDisabled: "cache driver needs to be configured for this functionality to work",
InvalidOneOffToken: "one-off token is invalid, already used or expired",
InvalidFUPCookie: "FUP cookie present, but invalid",
OneOffTokenNotAllowed: "one-off token authentication is not allowed for this endpoint",
}

func NewAuthError(code AuthErrorCode, payload interface{}) *AuthError {
Expand Down
19 changes: 19 additions & 0 deletions auth/security/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ func shouldAuthenticateByApiKey(c *gin.Context) bool {
}

func authenticateApiClientByOneOffToken(c *gin.Context) (contract.ApiClientInterface, *contract.AuthError) {
// check if one-off token is allowed for the current request
targetHandlers := config.ProviderInstance.GetTargetOneOffTokenHandlers()
if nil != targetHandlers && len(*targetHandlers) > 0 {
inScope := false
for _, targetHandler := range *targetHandlers {
matched, err := regexp.MatchString(targetHandler, c.Request.URL.String())
if nil != err {
log.Printf("can't match one-off token target handler pattern '%s': %v", targetHandler, err)
}
if matched {
inScope = true
break
}
}
if !inScope {
return nil, contract.NewAuthError(contract.OneOffTokenNotAllowed, nil)
}
}

token := c.Request.Header.Get(constants.OneOffTokenHeader)
if !config.ProviderInstance.IsCacheEnabled() {
return nil, contract.NewInternalError(contract.CacheDisabled, nil)
Expand Down

0 comments on commit 3fc2768

Please sign in to comment.