Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 51 additions & 51 deletions plugins/wasm-go/extensions/ext-auth/README.md

Large diffs are not rendered by default.

250 changes: 148 additions & 102 deletions plugins/wasm-go/extensions/ext-auth/README_EN.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package config

import (
"errors"
Expand All @@ -24,44 +24,45 @@ const (
)

type ExtAuthConfig struct {
httpService HttpService
failureModeAllow bool
failureModeAllowHeaderAdd bool
statusOnError uint32
HttpService HttpService
SkippedPathPrefixes []string
FailureModeAllow bool
FailureModeAllowHeaderAdd bool
StatusOnError uint32
}

type HttpService struct {
endpointMode string
client wrapper.HttpClient
// pathPrefix is only used when endpoint_mode is envoy
pathPrefix string
// requestMethod is only used when endpoint_mode is forward_auth
requestMethod string
// path is only used when endpoint_mode is forward_auth
path string
timeout uint32
authorizationRequest AuthorizationRequest
authorizationResponse AuthorizationResponse
EndpointMode string
Client wrapper.HttpClient
// PathPrefix is only used when endpoint_mode is envoy
PathPrefix string
// RequestMethod is only used when endpoint_mode is forward_auth
RequestMethod string
// Path is only used when endpoint_mode is forward_auth
Path string
Timeout uint32
AuthorizationRequest AuthorizationRequest
AuthorizationResponse AuthorizationResponse
}

type AuthorizationRequest struct {
// allowedHeaders In addition to the user’s supplied matchers,
// AllowedHeaders In addition to the user’s supplied matchers,
// Authorization are automatically included to the list.
// When the endpoint_mode is set to forward_auth,
// the original request's path is set in the X-Original-Uri header,
// and the original request's HTTP method is set in the X-Original-Method header.
allowedHeaders expr.Matcher
headersToAdd map[string]string
withRequestBody bool
maxRequestBodyBytes uint32
AllowedHeaders expr.Matcher
HeadersToAdd map[string]string
WithRequestBody bool
MaxRequestBodyBytes uint32
}

type AuthorizationResponse struct {
allowedUpstreamHeaders expr.Matcher
allowedClientHeaders expr.Matcher
AllowedUpstreamHeaders expr.Matcher
AllowedClientHeaders expr.Matcher
}

func parseConfig(json gjson.Result, config *ExtAuthConfig, log wrapper.Log) error {
func ParseConfig(json gjson.Result, config *ExtAuthConfig, log wrapper.Log) error {
httpServiceConfig := json.Get("http_service")
if !httpServiceConfig.Exists() {
return errors.New("missing http_service in config")
Expand All @@ -71,21 +72,23 @@ func parseConfig(json gjson.Result, config *ExtAuthConfig, log wrapper.Log) erro
return err
}

config.SkippedPathPrefixes = convertToStringList(json.Get("skipped_path_prefixes").Array())

failureModeAllow := json.Get("failure_mode_allow")
if failureModeAllow.Exists() {
config.failureModeAllow = failureModeAllow.Bool()
config.FailureModeAllow = failureModeAllow.Bool()
}

failureModeAllowHeaderAdd := json.Get("failure_mode_allow_header_add")
if failureModeAllowHeaderAdd.Exists() {
config.failureModeAllowHeaderAdd = failureModeAllowHeaderAdd.Bool()
config.FailureModeAllowHeaderAdd = failureModeAllowHeaderAdd.Bool()
}

statusOnError := uint32(json.Get("status_on_error").Uint())
if statusOnError == 0 {
statusOnError = DefaultStatusOnError
}
config.statusOnError = statusOnError
config.StatusOnError = statusOnError

return nil
}
Expand All @@ -101,7 +104,7 @@ func parseHttpServiceConfig(json gjson.Result, config *ExtAuthConfig, log wrappe
if timeout == 0 {
timeout = DefaultHttpServiceTimeout
}
httpService.timeout = timeout
httpService.Timeout = timeout

if err := parseAuthorizationRequestConfig(json, &httpService); err != nil {
return err
Expand All @@ -111,7 +114,7 @@ func parseHttpServiceConfig(json gjson.Result, config *ExtAuthConfig, log wrappe
return err
}

config.httpService = httpService
config.HttpService = httpService

return nil
}
Expand All @@ -123,7 +126,7 @@ func parseEndpointConfig(json gjson.Result, httpService *HttpService, log wrappe
} else if endpointMode != EndpointModeEnvoy && endpointMode != EndpointModeForwardAuth {
return errors.New(fmt.Sprintf("endpoint_mode %s is not supported", endpointMode))
}
httpService.endpointMode = endpointMode
httpService.EndpointMode = endpointMode

endpointConfig := json.Get("endpoint")
if !endpointConfig.Exists() {
Expand All @@ -140,7 +143,7 @@ func parseEndpointConfig(json gjson.Result, httpService *HttpService, log wrappe
}
serviceHost := endpointConfig.Get("service_host").String()

httpService.client = wrapper.NewClusterClient(wrapper.FQDNCluster{
httpService.Client = wrapper.NewClusterClient(wrapper.FQDNCluster{
FQDN: serviceName,
Port: servicePort,
Host: serviceHost,
Expand All @@ -152,24 +155,24 @@ func parseEndpointConfig(json gjson.Result, httpService *HttpService, log wrappe
if !pathPrefixConfig.Exists() {
return errors.New("when endpoint_mode is envoy, endpoint path_prefix must not be empty")
}
httpService.pathPrefix = pathPrefixConfig.String()
httpService.PathPrefix = pathPrefixConfig.String()

if endpointConfig.Get("request_method").Exists() || endpointConfig.Get("path").Exists() {
log.Warn("when endpoint_mode is envoy, endpoint request_method and path will be ignored")
}
case EndpointModeForwardAuth:
requestMethodConfig := endpointConfig.Get("request_method")
if !requestMethodConfig.Exists() {
httpService.requestMethod = http.MethodGet
httpService.RequestMethod = http.MethodGet
} else {
httpService.requestMethod = strings.ToUpper(requestMethodConfig.String())
httpService.RequestMethod = strings.ToUpper(requestMethodConfig.String())
}

pathConfig := endpointConfig.Get("path")
if !pathConfig.Exists() {
return errors.New("when endpoint_mode is forward_auth, endpoint path must not be empty")
}
httpService.path = pathConfig.String()
httpService.Path = pathConfig.String()

if endpointConfig.Get("path_prefix").Exists() {
log.Warn("when endpoint_mode is forward_auth, endpoint path_prefix will be ignored")
Expand All @@ -189,35 +192,28 @@ func parseAuthorizationRequestConfig(json gjson.Result, httpService *HttpService
if err != nil {
return err
}
authorizationRequest.allowedHeaders = result
authorizationRequest.AllowedHeaders = result
}

headersToAdd := map[string]string{}
headersToAddConfig := authorizationRequestConfig.Get("headers_to_add")
if headersToAddConfig.Exists() {
for key, value := range headersToAddConfig.Map() {
headersToAdd[key] = value.Str
}
}
authorizationRequest.headersToAdd = headersToAdd
authorizationRequest.HeadersToAdd = convertToStringMap(authorizationRequestConfig.Get("headers_to_add"))

withRequestBody := authorizationRequestConfig.Get("with_request_body")
if withRequestBody.Exists() {
// withRequestBody is true and the request method is GET, OPTIONS or HEAD
if withRequestBody.Bool() &&
(httpService.requestMethod == http.MethodGet || httpService.requestMethod == http.MethodOptions || httpService.requestMethod == http.MethodHead) {
return errors.New(fmt.Sprintf("requestMethod %s does not support with_request_body set to true", httpService.requestMethod))
(httpService.RequestMethod == http.MethodGet || httpService.RequestMethod == http.MethodOptions || httpService.RequestMethod == http.MethodHead) {
return errors.New(fmt.Sprintf("requestMethod %s does not support with_request_body set to true", httpService.RequestMethod))
}
authorizationRequest.withRequestBody = withRequestBody.Bool()
authorizationRequest.WithRequestBody = withRequestBody.Bool()
}

maxRequestBodyBytes := uint32(authorizationRequestConfig.Get("max_request_body_bytes").Uint())
if maxRequestBodyBytes == 0 {
maxRequestBodyBytes = DefaultMaxRequestBodyBytes
}
authorizationRequest.maxRequestBodyBytes = maxRequestBodyBytes
authorizationRequest.MaxRequestBodyBytes = maxRequestBodyBytes

httpService.authorizationRequest = authorizationRequest
httpService.AuthorizationRequest = authorizationRequest
}
return nil
}
Expand All @@ -233,7 +229,7 @@ func parseAuthorizationResponseConfig(json gjson.Result, httpService *HttpServic
if err != nil {
return err
}
authorizationResponse.allowedUpstreamHeaders = result
authorizationResponse.AllowedUpstreamHeaders = result
}

allowedClientHeaders := authorizationResponseConfig.Get("allowed_client_headers")
Expand All @@ -242,10 +238,27 @@ func parseAuthorizationResponseConfig(json gjson.Result, httpService *HttpServic
if err != nil {
return err
}
authorizationResponse.allowedClientHeaders = result
authorizationResponse.AllowedClientHeaders = result
}

httpService.authorizationResponse = authorizationResponse
httpService.AuthorizationResponse = authorizationResponse
}
return nil
}

func convertToStringList(results []gjson.Result) []string {
interfaces := make([]string, len(results))
for i, result := range results {
interfaces[i] = result.String()
}
return interfaces
}

func convertToStringMap(result gjson.Result) map[string]string {
m := make(map[string]string)
result.ForEach(func(key, value gjson.Result) bool {
m[key.String()] = value.String()
return true // keep iterating
})
return m
}
Loading
Loading