Skip to content

Commit fb47dc9

Browse files
committed
Fixed the auth header missing error to 401
1 parent ccbdcde commit fb47dc9

File tree

2 files changed

+80
-2
lines changed

2 files changed

+80
-2
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2021 - 2023 Sporta Technologies PVT LTD & the ZIO HTTP contributors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package zio.http.endpoint
18+
19+
import zio._
20+
import zio.test._
21+
22+
import zio.http._
23+
import zio.http.codec._
24+
import zio.http.endpoint._
25+
26+
object MissingAuthHeaderSpec extends ZIOHttpSpec {
27+
28+
def spec = suite("MissingAuthHeaderSpec")(
29+
test("missing Authorization header should return 401 not 400") {
30+
val endpoint = Endpoint(Method.GET / "test")
31+
.header(HeaderCodec.authorization)
32+
.out[String]
33+
34+
val routes = endpoint.implementHandler(
35+
Handler.succeed("success"),
36+
)
37+
38+
for {
39+
response <- routes.toRoutes.runZIO(
40+
Request.get(url"/test").addHeader(Header.Accept(MediaType.application.`json`)),
41+
)
42+
status = response.status
43+
} yield assertTrue(
44+
status.code == 401,
45+
status == Status.Unauthorized,
46+
)
47+
},
48+
test("missing non-auth header should still return 400") {
49+
val endpoint = Endpoint(Method.GET / "test")
50+
.header(HeaderCodec.headerAs[String]("X-Custom-Header"))
51+
.out[String]
52+
53+
val routes = endpoint.implementHandler(
54+
Handler.succeed("success"),
55+
)
56+
57+
for {
58+
response <- routes.toRoutes.runZIO(
59+
Request.get(url"/test").addHeader(Header.Accept(MediaType.application.`json`)),
60+
)
61+
status = response.status
62+
} yield assertTrue(
63+
status.code == 400,
64+
status == Status.BadRequest,
65+
)
66+
},
67+
)
68+
69+
}

zio-http/shared/src/main/scala/zio/http/endpoint/Endpoint.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ final case class Endpoint[PathInput, Input, Err, Output, Auth <: AuthType](
298298
def implementHandler[Env](original: Handler[Env, Err, Input, Output])(implicit trace: Trace): Route[Env, Nothing] = {
299299
import HttpCodecError.asHttpCodecError
300300

301+
def isAuthHeader(headerName: String): Boolean = {
302+
val lowerName = headerName.toLowerCase
303+
lowerName == "authorization" || lowerName == "www-authenticate" || lowerName.startsWith("x-auth")
304+
}
305+
301306
def authCodec(authType: AuthType): HttpCodec[HttpCodecType.RequestType, Unit] = authType match {
302307
case AuthType.None => HttpCodec.empty
303308
case AuthType.Basic =>
@@ -384,7 +389,11 @@ final case class Endpoint[PathInput, Input, Err, Output, Auth <: AuthType](
384389
case Some(HttpCodecError.CustomError("SchemaTransformationFailure", message))
385390
if maybeUnauthedResponse.isDefined && message.endsWith(" auth required") =>
386391
maybeUnauthedResponse.get
387-
case Some(_) =>
392+
case Some(HttpCodecError.MissingHeader(headerName)) if isAuthHeader(headerName) =>
393+
Handler.succeed(Response.unauthorized)
394+
case Some(HttpCodecError.MissingHeaders(headerNames)) if headerNames.exists(isAuthHeader) =>
395+
Handler.succeed(Response.unauthorized)
396+
case Some(_) =>
388397
Handler.fromFunctionZIO { (request: zio.http.Request) =>
389398
val error = cause.defects.head.asInstanceOf[HttpCodecError]
390399
val response = {
@@ -399,7 +408,7 @@ final case class Endpoint[PathInput, Input, Err, Output, Auth <: AuthType](
399408
}
400409
ZIO.succeed(response)
401410
}
402-
case None =>
411+
case None =>
403412
Handler.failCause(cause)
404413
}
405414
}

0 commit comments

Comments
 (0)