validateHeadersAndCookies makes sure headers and cookies are of an allowed type and the method payload defines the corresponding attributes.
()
| 923 | // validateHeadersAndCookies makes sure headers and cookies are of an allowed |
| 924 | // type and the method payload defines the corresponding attributes. |
| 925 | func (e *HTTPEndpointExpr) validateHeadersAndCookies() *eval.ValidationErrors { |
| 926 | verr := new(eval.ValidationErrors) |
| 927 | |
| 928 | // We have to figure out the actual type because it is initialized during |
| 929 | // the finalize phase. In the validation phase, all param types are string |
| 930 | // type by default unless specified explicitly. |
| 931 | headers := DupMappedAtt(e.Headers) |
| 932 | cookies := DupMappedAtt(e.Cookies) |
| 933 | initAttr(headers, e.MethodExpr.Payload) |
| 934 | initAttr(cookies, e.MethodExpr.Payload) |
| 935 | WalkMappedAttr(headers, func(name, _ string, a *AttributeExpr) error { // nolint: errcheck |
| 936 | switch { |
| 937 | case IsObject(a.Type), IsUnion(a.Type): |
| 938 | verr.Add(e, "header %q must be primitive or array", name) |
| 939 | case IsArray(a.Type): |
| 940 | arr := AsArray(a.Type) |
| 941 | if !IsPrimitive(arr.ElemType.Type) { |
| 942 | verr.Add(e, "elements of array header %q must be primitive", name) |
| 943 | } |
| 944 | default: |
| 945 | ctx := fmt.Sprintf("header %q", name) |
| 946 | verr.Merge(a.Validate(ctx, e)) |
| 947 | } |
| 948 | return nil |
| 949 | }) |
| 950 | WalkMappedAttr(cookies, func(name, _ string, a *AttributeExpr) error { // nolint: errcheck |
| 951 | switch { |
| 952 | case IsObject(a.Type), IsUnion(a.Type), IsArray(a.Type): |
| 953 | verr.Add(e, "cookie %q must be primitive", name) |
| 954 | default: |
| 955 | ctx := fmt.Sprintf("cookie %q", name) |
| 956 | verr.Merge(a.Validate(ctx, e)) |
| 957 | } |
| 958 | return nil |
| 959 | }) |
| 960 | switch e.MethodExpr.Payload.Type.(type) { |
| 961 | case *Object, UserType: |
| 962 | hasBasicAuth := TaggedAttribute(e.MethodExpr.Payload, "security:username") != "" |
| 963 | WalkMappedAttr(headers, func(name, elem string, _ *AttributeExpr) error { // nolint: errcheck |
| 964 | if e.MethodExpr.Payload.Find(name) == nil { |
| 965 | verr.Add(e, "header %q not found in payload.", name) |
| 966 | } |
| 967 | if elem == "Authorization" && hasBasicAuth { |
| 968 | // BasicAuth security implicitly sets the Authorization header. If any |
| 969 | // payload attribute is mapped to Authorization header, raise a |
| 970 | // validation error. |
| 971 | verr.Add(e, "Attribute %q is mapped to \"Authorization\" header in the endpoint secured by BasicAuth which also sets \"Authorization\" header. Specify a different header to map attribute %q.", name, name) |
| 972 | } |
| 973 | return nil |
| 974 | }) |
| 975 | WalkMappedAttr(cookies, func(name, _ string, _ *AttributeExpr) error { // nolint: errcheck |
| 976 | if e.MethodExpr.Payload.Find(name) == nil { |
| 977 | verr.Add(e, "cookie %q not found in payload.", name) |
| 978 | } |
| 979 | return nil |
| 980 | }) |
| 981 | case *Array: |
| 982 | if len(*AsObject(headers.Type)) > 1 { |
no test coverage detected