mirror of
https://github.com/LukeHagar/plexterraform.git
synced 2025-12-07 04:20:54 +00:00
ci: regenerated with OpenAPI Doc 0.0.3, Speakeasy CLI 1.129.1
This commit is contained in:
298
internal/sdk/pkg/utils/security.go
Normal file
298
internal/sdk/pkg/utils/security.go
Normal file
@@ -0,0 +1,298 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type HTTPClient interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
const (
|
||||
securityTagKey = "security"
|
||||
)
|
||||
|
||||
type securityTag struct {
|
||||
Option bool
|
||||
Scheme bool
|
||||
Name string
|
||||
Type string
|
||||
SubType string
|
||||
}
|
||||
|
||||
type securityConfig struct {
|
||||
headers map[string]string
|
||||
queryParams map[string]string
|
||||
}
|
||||
|
||||
type SecurityClient struct {
|
||||
HTTPClient
|
||||
security func(ctx context.Context) (interface{}, error)
|
||||
}
|
||||
|
||||
func newSecurityClient(client HTTPClient, security func(ctx context.Context) (interface{}, error)) *SecurityClient {
|
||||
return &SecurityClient{
|
||||
HTTPClient: client,
|
||||
security: security,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *SecurityClient) Do(req *http.Request) (*http.Response, error) {
|
||||
securityCtx, err := c.security(req.Context())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := securityConfig{
|
||||
headers: make(map[string]string),
|
||||
queryParams: make(map[string]string),
|
||||
}
|
||||
parseSecurityStruct(&ctx, securityCtx)
|
||||
|
||||
for k, v := range ctx.headers {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
|
||||
queryParams := req.URL.Query()
|
||||
|
||||
for k, v := range ctx.queryParams {
|
||||
queryParams.Add(k, v)
|
||||
}
|
||||
|
||||
req.URL.RawQuery = queryParams.Encode()
|
||||
|
||||
return c.HTTPClient.Do(req)
|
||||
}
|
||||
|
||||
func ConfigureSecurityClient(c HTTPClient, security func(ctx context.Context) (interface{}, error)) *SecurityClient {
|
||||
return newSecurityClient(c, security)
|
||||
}
|
||||
|
||||
func trueReflectValue(val reflect.Value) reflect.Value {
|
||||
kind := val.Type().Kind()
|
||||
for kind == reflect.Interface || kind == reflect.Ptr {
|
||||
innerVal := val.Elem()
|
||||
if !innerVal.IsValid() {
|
||||
break
|
||||
}
|
||||
val = innerVal
|
||||
kind = val.Type().Kind()
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func parseSecurityStruct(c *securityConfig, security interface{}) {
|
||||
securityValType := trueReflectValue(reflect.ValueOf(security))
|
||||
securityStructType := securityValType.Type()
|
||||
|
||||
if isNil(securityStructType, securityValType) {
|
||||
return
|
||||
}
|
||||
|
||||
if securityStructType.Kind() == reflect.Ptr {
|
||||
securityStructType = securityStructType.Elem()
|
||||
securityValType = securityValType.Elem()
|
||||
}
|
||||
|
||||
for i := 0; i < securityStructType.NumField(); i++ {
|
||||
fieldType := securityStructType.Field(i)
|
||||
valType := securityValType.Field(i)
|
||||
|
||||
kind := valType.Kind()
|
||||
|
||||
if isNil(fieldType.Type, valType) {
|
||||
continue
|
||||
}
|
||||
|
||||
if fieldType.Type.Kind() == reflect.Pointer {
|
||||
kind = valType.Elem().Kind()
|
||||
}
|
||||
|
||||
secTag := parseSecurityTag(fieldType)
|
||||
if secTag != nil {
|
||||
if secTag.Option {
|
||||
handleSecurityOption(c, valType.Interface())
|
||||
} else if secTag.Scheme {
|
||||
// Special case for basic auth which could be a flattened struct
|
||||
if secTag.SubType == "basic" && kind != reflect.Struct {
|
||||
parseSecurityScheme(c, secTag, security)
|
||||
} else {
|
||||
parseSecurityScheme(c, secTag, valType.Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleSecurityOption(c *securityConfig, option interface{}) error {
|
||||
optionValType := trueReflectValue(reflect.ValueOf(option))
|
||||
optionStructType := optionValType.Type()
|
||||
|
||||
if isNil(optionStructType, optionValType) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < optionStructType.NumField(); i++ {
|
||||
fieldType := optionStructType.Field(i)
|
||||
valType := optionValType.Field(i)
|
||||
|
||||
secTag := parseSecurityTag(fieldType)
|
||||
if secTag != nil && secTag.Scheme {
|
||||
parseSecurityScheme(c, secTag, valType.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseSecurityScheme(client *securityConfig, schemeTag *securityTag, scheme interface{}) {
|
||||
schemeVal := trueReflectValue(reflect.ValueOf(scheme))
|
||||
schemeType := schemeVal.Type()
|
||||
|
||||
if isNil(schemeType, schemeVal) {
|
||||
return
|
||||
}
|
||||
|
||||
if schemeType.Kind() == reflect.Struct {
|
||||
if schemeTag.Type == "http" && schemeTag.SubType == "basic" {
|
||||
handleBasicAuthScheme(client, schemeVal.Interface())
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; i < schemeType.NumField(); i++ {
|
||||
fieldType := schemeType.Field(i)
|
||||
valType := schemeVal.Field(i)
|
||||
|
||||
if isNil(fieldType.Type, valType) {
|
||||
continue
|
||||
}
|
||||
|
||||
if fieldType.Type.Kind() == reflect.Ptr {
|
||||
valType = valType.Elem()
|
||||
}
|
||||
|
||||
secTag := parseSecurityTag(fieldType)
|
||||
if secTag == nil || secTag.Name == "" {
|
||||
return
|
||||
}
|
||||
|
||||
parseSecuritySchemeValue(client, schemeTag, secTag, valType.Interface())
|
||||
}
|
||||
} else {
|
||||
parseSecuritySchemeValue(client, schemeTag, schemeTag, schemeVal.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
func parseSecuritySchemeValue(client *securityConfig, schemeTag *securityTag, secTag *securityTag, val interface{}) {
|
||||
switch schemeTag.Type {
|
||||
case "apiKey":
|
||||
switch schemeTag.SubType {
|
||||
case "header":
|
||||
client.headers[secTag.Name] = valToString(val)
|
||||
case "query":
|
||||
client.queryParams[secTag.Name] = valToString(val)
|
||||
case "cookie":
|
||||
client.headers["Cookie"] = fmt.Sprintf("%s=%s", secTag.Name, valToString(val))
|
||||
default:
|
||||
panic("not supported")
|
||||
}
|
||||
case "openIdConnect":
|
||||
client.headers[secTag.Name] = valToString(val)
|
||||
case "oauth2":
|
||||
client.headers[secTag.Name] = valToString(val)
|
||||
case "http":
|
||||
switch schemeTag.SubType {
|
||||
case "bearer":
|
||||
client.headers[secTag.Name] = prefixBearer(valToString(val))
|
||||
default:
|
||||
panic("not supported")
|
||||
}
|
||||
default:
|
||||
panic("not supported")
|
||||
}
|
||||
}
|
||||
|
||||
func prefixBearer(authHeaderValue string) string {
|
||||
if strings.HasPrefix(strings.ToLower(authHeaderValue), "bearer ") {
|
||||
return authHeaderValue
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Bearer %s", authHeaderValue)
|
||||
}
|
||||
|
||||
func handleBasicAuthScheme(client *securityConfig, scheme interface{}) {
|
||||
schemeStructType := reflect.TypeOf(scheme)
|
||||
schemeValType := reflect.ValueOf(scheme)
|
||||
|
||||
var username, password string
|
||||
|
||||
for i := 0; i < schemeStructType.NumField(); i++ {
|
||||
fieldType := schemeStructType.Field(i)
|
||||
valType := schemeValType.Field(i)
|
||||
|
||||
secTag := parseSecurityTag(fieldType)
|
||||
if secTag == nil || secTag.Name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
switch secTag.Name {
|
||||
case "username":
|
||||
username = valType.String()
|
||||
case "password":
|
||||
password = valType.String()
|
||||
}
|
||||
}
|
||||
|
||||
client.headers["Authorization"] = fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password))))
|
||||
}
|
||||
|
||||
func parseSecurityTag(field reflect.StructField) *securityTag {
|
||||
tag := field.Tag.Get(securityTagKey)
|
||||
if tag == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
option := false
|
||||
scheme := false
|
||||
name := ""
|
||||
securityType := ""
|
||||
securitySubType := ""
|
||||
|
||||
options := strings.Split(tag, ",")
|
||||
for _, optionConf := range options {
|
||||
parts := strings.Split(optionConf, "=")
|
||||
if len(parts) < 1 || len(parts) > 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
switch parts[0] {
|
||||
case "name":
|
||||
name = parts[1]
|
||||
case "type":
|
||||
securityType = parts[1]
|
||||
case "subtype":
|
||||
securitySubType = parts[1]
|
||||
case "option":
|
||||
option = true
|
||||
case "scheme":
|
||||
scheme = true
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: validate tag?
|
||||
|
||||
return &securityTag{
|
||||
Option: option,
|
||||
Scheme: scheme,
|
||||
Name: name,
|
||||
Type: securityType,
|
||||
SubType: securitySubType,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user