From e9a5a2977d2f4aaf443f15c1886a1672ead8983a Mon Sep 17 00:00:00 2001 From: Felipe Ripoll Date: Wed, 8 Aug 2018 06:04:52 -0600 Subject: [PATCH] [#36] blacklisting users endpoint --- lib/poa_backend/auth.ex | 16 ++++ lib/poa_backend/auth/router.ex | 26 ++++++ test/auth/api_test.exs | 157 ++++++++++++++++++++++++++++++++- 3 files changed, 195 insertions(+), 4 deletions(-) diff --git a/lib/poa_backend/auth.ex b/lib/poa_backend/auth.ex index e9ce7a5..e1e6c04 100644 --- a/lib/poa_backend/auth.ex +++ b/lib/poa_backend/auth.ex @@ -6,6 +6,7 @@ defmodule POABackend.Auth do alias POABackend.Auth.Models.User alias POABackend.Auth.Repo + alias POABackend.Auth @doc """ Registers a user in the system. @@ -139,6 +140,21 @@ defmodule POABackend.Auth do end end + @doc """ + Validates if a JWT token is valid. + """ + @spec valid_token?(String.t) :: Boolean.t + def valid_token?(jwt_token) do + with {:ok, claims} <- Auth.Guardian.decode_and_verify(jwt_token), + {:ok, user, ^claims} <- Auth.Guardian.resource_from_token(jwt_token), + true <- user_active?(user) + do + true + else + _error -> false + end + end + # --------------------------------------- # Private Functions # --------------------------------------- diff --git a/lib/poa_backend/auth/router.ex b/lib/poa_backend/auth/router.ex index 43704ef..57c0d91 100644 --- a/lib/poa_backend/auth/router.ex +++ b/lib/poa_backend/auth/router.ex @@ -65,6 +65,32 @@ defmodule POABackend.Auth.Router do end end + post "/blacklist/user" do + with {"authorization", "Basic " <> base64} <- List.keyfind(conn.req_headers, "authorization", 0), + {:ok, decoded64} <- Base.decode64(base64), + [admin_name, admin_password] <- String.split(decoded64, ":"), + true <- conn.params["user"] != nil, + {:ok, :valid} <- Auth.authenticate_admin(admin_name, admin_password) + do + case Auth.get_user(conn.params["user"]) do + nil -> + send_resp(conn, 404, "") + user -> + {:ok, _} = Auth.deactivate_user(user) + send_resp(conn, 200, "") + end + else + false -> + conn + |> send_resp(404, "") + |> halt + _error -> + conn + |> send_resp(401, "") + |> halt + end + end + match _ do send_resp(conn, 404, "") end diff --git a/test/auth/api_test.exs b/test/auth/api_test.exs index e2a743c..8454140 100644 --- a/test/auth/api_test.exs +++ b/test/auth/api_test.exs @@ -285,6 +285,155 @@ defmodule Auth.APITest do assert {409, :nobody} == result end + # ---------------------------------------- + # /blackmail/user Endpoint Tests + # ---------------------------------------- + + test "Ban a user correctly [JSON]" do + mime_type = "application/json" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@user <> ":" <> @password)} + ] + + {200, %{"token" => jwt_token}} = + %{:'agent-id' => "agentID"} + |> Poison.encode!() + |> post(@base_url <> "/session", headers) + + user = Auth.get_user(@user) + + assert Auth.valid_token?(jwt_token) + assert Auth.user_active?(user) + + blacklist_url = @base_url <> "/blacklist/user" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@admin <> ":" <> @admin_pwd)} + ] + + {200, :nobody} = + %{:user => @user} + |> Poison.encode!() + |> post(blacklist_url, headers) + + user = Auth.get_user(@user) + + refute Auth.valid_token?(jwt_token) + refute Auth.user_active?(user) + end + + test "Ban a user correctly [MSGPACK]" do + mime_type = "application/msgpack" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@user <> ":" <> @password)} + ] + + {200, %{"token" => jwt_token}} = + %{:'agent-id' => "agentID"} + |> Msgpax.pack!() + |> post(@base_url <> "/session", headers) + + user = Auth.get_user(@user) + + assert Auth.valid_token?(jwt_token) + assert Auth.user_active?(user) + + blacklist_url = @base_url <> "/blacklist/user" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@admin <> ":" <> @admin_pwd)} + ] + + {200, :nobody} = + %{:user => @user} + |> Msgpax.pack!() + |> post(blacklist_url, headers) + + user = Auth.get_user(@user) + + refute Auth.valid_token?(jwt_token) + refute Auth.user_active?(user) + end + + test "Ban a user who doesn't exist [JSON]" do + mime_type = "application/json" + url = @base_url <> "/blacklist/user" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@admin <> ":" <> @admin_pwd)} + ] + + result = + %{:user => "thiUserDoesntexist"} + |> Poison.encode!() + |> post(url, headers) + + assert result == {404, :nobody} + end + + test "Ban a user who doesn't exist [MSGPACK]" do + mime_type = "application/msgpack" + url = @base_url <> "/blacklist/user" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@admin <> ":" <> @admin_pwd)} + ] + + result = + %{:user => "thiUserDoesntexist"} + |> Msgpax.pack!() + |> post(url, headers) + + assert result == {404, :nobody} + end + + test "Ban user with wrong Admin credentials [JSON]" do + mime_type = "application/json" + url = @base_url <> "/blacklist/user" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@admin <> ":" <> "wrongpassword")} + ] + + result = + %{:user => @user} + |> Poison.encode!() + |> post(url, headers) + + assert {401, :nobody} == result + end + + test "Ban user with wrong Admin credentials [MSGPACK]" do + mime_type = "application/msgpack" + url = @base_url <> "/blacklist/user" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@admin <> ":" <> "wrongpassword")} + ] + + result = + %{:user => @user} + |> Msgpax.pack!() + |> post(url, headers) + + assert {401, :nobody} == result + end + + test "Ban user without user field [JSON]" do + mime_type = "application/json" + url = @base_url <> "/blacklist/user" + headers = [ + {"Content-Type", mime_type}, + {"authorization", "Basic " <> Base.encode64(@admin <> ":" <> @admin_pwd)} + ] + + result = post("", url, headers) + + assert {404, :nobody} == result + end + # ---------------------------------------- # Internal functions # ---------------------------------------- @@ -298,12 +447,12 @@ defmodule Auth.APITest do options = [ssl: [{:versions, [:'tlsv1.2']}], recv_timeout: 500] {:ok, response} = HTTPoison.post(url, data, headers, options) - body = case response.status_code do - 200 -> + body = case response.body do + "" -> + :nobody + _ -> {:ok, body} = Poison.decode(response.body) body - _ -> - :nobody end {response.status_code, body}