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 any, 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.Pointer { t = t.Elem() } for field := range t.Fields() { field := field // 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.SplitSeq(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 }