     |> set_body("401 Unauthorized")
   end
 
-  @doc """
-
-  ## Examples
-
-      iex> authentication_header("Aladdin", "open sesame")
-      Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
-  """
-  def authentication_header(user_id, password) do
+  defp authentication_header(user_id, password) do
     "Basic " <> Base.encode64(user_pass(user_id, password))
   end
 


  Basic Authentication is specified in RFC 7617 (which obsoletes RFC 2617).

  ## Examples
  # Authenticate is Authenticated

  ## NOTE

  The Basic authentication scheme is not a secure method of user authentication
  https://tools.ietf.org/html/rfc7617#section-4


  """

  defmacro __using__(_opts) do
    quote do
      def authenticate(request) do
        case get_credential(request) do
          {user_id, password} ->
            verify_credentials(user_id, password)
          {:error, reason} ->
            {:error, reason}
        end
      end
# TODO define your own verify_credentials -> user
    end
  end

  @authentication_header "authorization"
  @default_realm "Site"
  @default_charset "UTF-8"

  def set_authentication(request, user_id, password) do
    request
    |> set_header(@authentication_header, authentication_header(user_id, password))
  end

  # TODO expose credentials function
  def authenticate(request) do
    # Raxx does not need to include OK
    # ~>> fetch_authentication_header
    case Raxx.get_header(request, @authentication_header) do
      nil ->
        {:error, :not_authorization_header}
      authorization ->
        case String.split(authorization, " ", parts: 2) do
          ["Basic", encoded] ->
            case Base.decode64(encoded) do
              {:ok, user_pass} ->
                case String.split(authorization, " ", parts: 2) do
                  [user_id, password] ->
                    :ok
                  _ ->
                    {:error, :invalid_user_pass}
                end
              :error ->
                {:error, :unable_to_decode_user_pass}
            end
          [unknown, _] ->
            {:error, :unknown_authentication_method}
          _ ->
            {:error, :invalid_authentication_header}
        end
    end
  end


  def challenge_header(realm, nil) do
    "Basic realm=\"#{realm}\""
  end

  def challenge_header(realm, charset) do
    "Basic realm=\"#{realm}\", charset=\"#{charset}\""
  end

  defp user_pass(user_id, password) do
    :ok =
      case :binary.match(user_id, [":"]) do
        {_, _} ->
          raise "a user-id containing a colon character is invalid"

        :nomatch ->
          :ok
      end

    user_id <> ":" <> password
  end

  @doc """
  Compares the two binaries in constant-time to avoid timing attacks.
  See: http://codahale.com/a-lesson-in-timing-attacks/
  """
  def secure_compare(left, right) do
    if byte_size(left) == byte_size(right) do
      secure_compare(left, right, 0) == 0
    else
      false
    end
  end

  def secure_compare(<<x, left::binary>>, <<y, right::binary>>, acc) do
    import Bitwise
    xorred = x ^^^ y
    secure_compare(left, right, acc ||| xorred)
  end

  def secure_compare(<<>>, <<>>, acc) do
    acc
  end
end
