Current section
Files
Jump to
Current section
Files
lib/easy_auth.ex
defmodule EasyAuth do
alias Plug.Crypto
alias Plug.Conn
def init(options) do
options
end
@doc """
Extracts an header when present, or return nil
"""
defp extract_header(header) do
if Enum.count(header) > 0 do
Enum.at(header, 0)
end
end
@doc """
Get the authorization header value
"""
defp authorization_header(conn) do
conn
|> Conn.get_req_header("authorization")
|> extract_header()
end
@doc """
Creates the comparison token
"""
defp get_token(options) do
string =
(options[:username] <> ":" <> options[:password])
|> Base.encode64()
"Basic " <> string
end
@doc """
Finds out whether auth and token match
"""
defp tokens_match(authorization, token) do
if Crypto.secure_compare(authorization, token) do
true
end
end
@doc """
Produces a 401 response
"""
defp unauthorised(conn, options) do
conn
|> Conn.put_resp_header("www-authenticate", "Basic realm=\"#{options[:realm]}\"")
|> Conn.put_resp_content_type("text/plain")
|> Conn.send_resp(401, "401 Unauthorized")
|> Conn.halt()
end
@doc """
Verifies the auth header is correct
"""
def verify_auth(conn, options) do
token = get_token(options)
authorization = authorization_header(conn)
if authorization do
if tokens_match(authorization, token) do
true
end
end
end
def call(conn, options) do
if verify_auth(conn, options) do
conn
else
unauthorised(conn, options)
end
end
end