http4s does not handle 401
Closed this issue · 4 comments
If I define 401 response type like this
"responses": {
"200": {
"type": "account"
},
"400": {
"type": "unit"
},
"401": {
"type": "unit"
}
}
The resulting generated code ...
case PostSignInResponse.HTTP401(headers) => Unauthorized().map(_.putHeaders(headers: _*))
... fails to compile:
[error] ...............: overloaded method value apply with alternatives:
[error] [A](authenticate: org.http4s.headers.WWW-Authenticate, body: A, headers:
org.http4s.Header*)(implicit F: cats.Monad[F], implicit w:
org.http4s.EntityEncoder[F,A])F[org.http4s.Response[F]] <and>
[error] (authenticate: org.http4s.headers.WWW-Authenticate,headers: org.http4s.Header*)(implicit F: cats.Applicative[F])F[org.http4s.Response[F]] <and>
[error] (challenge: org.http4s.Challenge,challenges: org.http4s.Challenge*)(implicit F: cats.Applicative[F])F[org.http4s.Response[F]]
[error] cannot be applied to ()
[error] case PostSignInResponse.HTTP401(headers) => Unauthorized().map(_.putHeaders(headers: _*))
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 19 s, completed Mar 14, 2018 4:27:19 PM
That's because Unauthorized needs WWW-Authenticate
header.
Below would compile, but I'm not sure about "Bearer" and "Organization".
case PostSignInResponse.HTTP401(headers) => Unauthorized(org.http4s.headers.`WWW-Authenticate`(org.http4s.Challenge("Bearer", "Organization"))).map(_.putHeaders(headers: _*))
My first hunch: the apibuilder format doesn't provide enough information to make a 401 actually work. Can a 401 work correctly for any generated server code target?
I'm guessing that most frameworks do not enforce WWW-Authenticate
for 401 (although they should) like http4s does
You can build a Response[F]
value manually rather than with these constructors if necessary. See https://github.com/http4s/http4s/blob/3dda6969adc46fc887da178b5a0976fca9d26c2d/dsl/src/main/scala/org/http4s/dsl/impl/ResponseGenerator.scala#L78 for what the underlying code looks like.
Yeah, we need to fix the HTTP401 response to take a authenticate: WWW-Authenticate
in addtion to the headers. I might be able to look into this tomorrow.