From 2e08a8b6fd687653925dad61d596421252c21012 Mon Sep 17 00:00:00 2001 From: Eduardo Gurgel Date: Tue, 31 Dec 2013 05:44:14 -0300 Subject: [PATCH] Add '/basic-auth/:user/:passwd' --- lib/httparrot.ex | 1 + lib/httparrot/basic_auth_handler.ex | 35 ++++++++++++++++++++++ test/basic_auth_handler_test.exs | 45 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 lib/httparrot/basic_auth_handler.ex create mode 100644 test/basic_auth_handler_test.exs diff --git a/lib/httparrot.ex b/lib/httparrot.ex index cdd5a50..696ae83 100644 --- a/lib/httparrot.ex +++ b/lib/httparrot.ex @@ -10,6 +10,7 @@ defmodule HTTParrot do {'/post', HTTParrot.PostHandler, []}, {'/status/:code', HTTParrot.StatusCodeHandler, []}, {'/redirect-to', HTTParrot.RedirectToHandler, []}, + {'/basic-auth/:user/:passwd', HTTParrot.BasicAuthHandler, []}, {'/html', :cowboy_static, {:priv_file, :httparrot, "html.html"}} ] } ]) {:ok, port} = :application.get_env(:httparrot, :port) diff --git a/lib/httparrot/basic_auth_handler.ex b/lib/httparrot/basic_auth_handler.ex new file mode 100644 index 0000000..2920c11 --- /dev/null +++ b/lib/httparrot/basic_auth_handler.ex @@ -0,0 +1,35 @@ +defmodule HTTParrot.BasicAuthHandler do + alias HTTParrot.GeneralRequestInfo + + def init(_transport, _req, _opts) do + {:upgrade, :protocol, :cowboy_rest} + end + + def allowed_methods(req, state) do + {["GET"], req, state} + end + + def is_authorized(req, state) do + {user, req} = :cowboy_req.binding(:user, req) + {passwd, req} = :cowboy_req.binding(:passwd, req) + {:ok, auth, req} = :cowboy_req.parse_header("authorization", req) + case auth do + {"basic", {^user, ^passwd}} -> {true, req, user} + _ -> {{false, "Basic realm=\"Fake Realm\""}, req, state} + end + end + + def content_types_provided(req, state) do + {[{{"application", "json", []}, :get_json}], req, state} + end + + def get_json(req, user) do + {response(user), req, nil} + end + + defp response(user) do + [authenticated: true, user: user] |> JSEX.encode! + end + + def terminate(_, _, _), do: :ok +end diff --git a/test/basic_auth_handler_test.exs b/test/basic_auth_handler_test.exs new file mode 100644 index 0000000..cdd85c6 --- /dev/null +++ b/test/basic_auth_handler_test.exs @@ -0,0 +1,45 @@ +defmodule HTTParrot.BasicAuthHandlerTest do + use ExUnit.Case + import :meck + import HTTParrot.BasicAuthHandler + + setup do + new :cowboy_req + new JSEX + end + + teardown do + unload :cowboy_req + unload JSEX + end + + test "is_authorized returns true if user and passwd match" do + expect(:cowboy_req, :binding, [{[:user, :req1], {:user, :req2}}, + {[:passwd, :req2], {:passwd, :req3}}]) + expect(:cowboy_req, :parse_header, [{["authorization", :req3], {:ok, {"basic", {:user, :passwd}}, :req4}}]) + + assert is_authorized(:req1, :state) == {true, :req4, :user} + + assert validate :cowboy_req + assert validate JSEX + end + + test "is_authorized returns false if user and passwd doesnt match" do + expect(:cowboy_req, :binding, [{[:user, :req1], {:user, :req2}}, + {[:passwd, :req2], {:passwd, :req3}}]) + expect(:cowboy_req, :parse_header, [{["authorization", :req3], {:ok, {"basic", {:not_the_user, :passwd}}, :req4}}]) + + assert is_authorized(:req1, :state) == {{false, "Basic realm=\"Fake Realm\""}, :req4, :state} + + assert validate :cowboy_req + assert validate JSEX + end + + test "returns user and if it's authenticated" do + expect(JSEX, :encode!, [{[[authenticated: true, user: :user]], :json}]) + + assert get_json(:req1, :user) == {:json, :req1, nil} + + assert validate JSEX + end +end