fixup! NXD blob/auth: Teach it to handle HTTP Basic Auth too
@rafael approached me and asked why URLs like
https://gitlab-ci-token:XXX@hostname/group/project/raw/master/file
work in CURL, but not in Chrome under AJAX requests.
After investigation it turned out they neither work in WGET and give 302 redirect to http://localhost:8080/users/sign_in:
kirr@deco:~$ wget https://gitlab-ci-token:XXX@lab.nexedi.com/kirr/test/raw/master/hello.txt
--2018-06-04 13:14:04-- https://gitlab-ci-token:*password*@lab.nexedi.com/kirr/test/raw/master/hello.txt
Resolving lab.nexedi.com (lab.nexedi.com)... 176.31.129.213, 85.118.38.162
Connecting to lab.nexedi.com (lab.nexedi.com)|176.31.129.213|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://localhost:8080/users/sign_in [following]
--2018-06-04 13:14:04-- http://localhost:8080/users/sign_in
Resolving localhost (localhost)... 127.0.0.1, ::1
Connecting to localhost (localhost)|127.0.0.1|:8080... failed: Connection refused.
Connecting to localhost (localhost)|::1|:8080... failed: Connection refused.
This turned out to be due to most clients (in fine accordance with RFC2617 / RFC7617) first send request without Authorization header set and retry it with that header only if server challenges it to(*), and our authorization code was only trying to handle HTTP basic auth if Authorization header was provided without issuing any challenge on server side.
Fix it by checking Rails backend reply for 302, which it gives for unauthorized non-raw requests, and on our side convert it HTTP Basic auth challenge if raw request does not contain any token. This way it now works with user:password in URLs for both WGET and Chrome.
If any tokens were provided we leave Rails auth response as is because we handle user/password only for that "no token provided at all" case.
(*) see https://en.wikipedia.org/wiki/Basic_access_authentication for overview. /cc @alain.takoudjou, @jerome