Skip to content

Commit

Permalink
refactor: return error if invalid
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Nov 14, 2023
1 parent 5636de5 commit 72ccfb7
Showing 1 changed file with 42 additions and 22 deletions.
64 changes: 42 additions & 22 deletions core/corehttp/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,11 @@ func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool)
cmdHandler := cmdsHttp.NewHandler(&cctx, command, cfg)

if len(rcfg.API.Authorizations) > 0 {
cmdHandler = withAuthSecrets(rcfg.API.Authorizations, cmdHandler)
authorizations, err := convertAuthorizationsMap(rcfg.API.Authorizations)
if err != nil {
return nil, err
}
cmdHandler = withAuthSecrets(authorizations, cmdHandler)

Check warning on line 153 in core/corehttp/commands.go

View check run for this annotation

Codecov / codecov/patch

core/corehttp/commands.go#L147-L153

Added lines #L147 - L153 were not covered by tests
}

cmdHandler = otelhttp.NewHandler(cmdHandler, "corehttp.cmdsHandler")
Expand All @@ -155,40 +159,56 @@ func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool)
}
}

// convertHTTPAuthSecret converts the given secret "type:value" into an HTTP Header
// value. It returns empty string if unknown type. Returns error if invalid.
func convertHTTPAuthSecret(secret string) (string, error) {
split := strings.SplitN(secret, ":", 2)
if len(split) < 2 {
// invalid
return "", errors.New("HTTPAuthSecret has invalid value: it must be encoded as 'type:value'")
}

Check warning on line 169 in core/corehttp/commands.go

View check run for this annotation

Codecov / codecov/patch

core/corehttp/commands.go#L164-L169

Added lines #L164 - L169 were not covered by tests

if strings.HasPrefix(secret, "basic:") {
if strings.Contains(split[1], ":") {
// Assume basic:user:password
return "Basic " + base64.StdEncoding.EncodeToString([]byte(split[1])), nil
} else {
// Assume already base64 encoded.
return "Basic " + split[1], nil
}
} else if strings.HasPrefix(secret, "bearer:") {
return "Bearer " + split[1], nil
}

Check warning on line 181 in core/corehttp/commands.go

View check run for this annotation

Codecov / codecov/patch

core/corehttp/commands.go#L171-L181

Added lines #L171 - L181 were not covered by tests

// unknown
return "", nil

Check warning on line 184 in core/corehttp/commands.go

View check run for this annotation

Codecov / codecov/patch

core/corehttp/commands.go#L184

Added line #L184 was not covered by tests
}

type rpcAuthScopeWithUser struct {
config.RPCAuthScope
User string
}

func withAuthSecrets(authScopes map[string]*config.RPCAuthScope, next http.Handler) http.Handler {
func convertAuthorizationsMap(authScopes map[string]*config.RPCAuthScope) (map[string]rpcAuthScopeWithUser, error) {
// authorizations is a map where we can just check for the header value to match.
authorizations := map[string]rpcAuthScopeWithUser{}

for user, authScope := range authScopes {
split := strings.SplitN(authScope.HTTPAuthSecret, ":", 2)
if len(split) < 2 {
continue
expectedHeader, err := convertHTTPAuthSecret(authScope.HTTPAuthSecret)
if err != nil {
return nil, err
}

expectedHeader := ""
if strings.HasPrefix(authScope.HTTPAuthSecret, "basic:") {
if strings.Contains(split[1], ":") {
// Assume basic:user:password
expectedHeader = "Basic " + base64.StdEncoding.EncodeToString([]byte(split[1]))
} else {
// Assume already base64 encoded.
expectedHeader = "Basic " + split[1]
if expectedHeader != "" {
authorizations[expectedHeader] = rpcAuthScopeWithUser{
RPCAuthScope: *authScopes[user],
User: user,
}
} else if strings.HasPrefix(authScope.HTTPAuthSecret, "bearer:") {
expectedHeader = "Bearer " + split[1]
}

authorizations[expectedHeader] = rpcAuthScopeWithUser{
RPCAuthScope: *authScopes[user],
User: user,
}

Check warning on line 205 in core/corehttp/commands.go

View check run for this annotation

Codecov / codecov/patch

core/corehttp/commands.go#L192-L205

Added lines #L192 - L205 were not covered by tests
}

return authorizations, nil

Check warning on line 208 in core/corehttp/commands.go

View check run for this annotation

Codecov / codecov/patch

core/corehttp/commands.go#L208

Added line #L208 was not covered by tests
}

func withAuthSecrets(authorizations map[string]rpcAuthScopeWithUser, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authorizationHeader := r.Header.Get("Authorization")
auth, ok := authorizations[authorizationHeader]
Expand Down

0 comments on commit 72ccfb7

Please sign in to comment.