1
0
forked from baron/baron-sso
Files
baron-sso/backend/internal/validator/schema_validator.go
2026-01-23 16:27:30 +09:00

63 lines
1.6 KiB
Go

package validator
import (
"baron-sso-backend/internal/domain"
"fmt"
"reflect"
"strings"
)
// ValidateIDPCompatibility checks if the provided IDP supports all required fields defined in the BrokerUser model.
func ValidateIDPCompatibility(brokerModel interface{}, idp domain.IdentityProvider) error {
metadata, err := idp.GetMetadata()
if err != nil {
return fmt.Errorf("failed to fetch metadata from IDP %s: %w", idp.Name(), err)
}
supportedMap := make(map[string]bool)
for _, f := range metadata.SupportedFields {
supportedMap[f] = true
}
t := reflect.TypeOf(brokerModel)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
// Check "required" tag
isRequired := field.Tag.Get("required") == "true"
jsonTag := field.Tag.Get("json")
fieldName := strings.Split(jsonTag, ",")[0]
// Skip if fieldName is empty or if it's the Attributes map (handled separately)
if fieldName == "" {
continue
}
if fieldName != "attributes" {
if isRequired && !supportedMap[fieldName] {
return fmt.Errorf("IDP %s does not support required field: %s", idp.Name(), fieldName)
}
}
// Check "required_keys" tag for map types (Custom Attributes)
if fieldName == "attributes" {
reqKeys := field.Tag.Get("required_keys")
if reqKeys != "" {
keys := strings.Split(reqKeys, ",")
for _, key := range keys {
key = strings.TrimSpace(key)
if !supportedMap[key] {
return fmt.Errorf("IDP %s does not support required custom attribute: %s", idp.Name(), key)
}
}
}
}
}
return nil
}