meta/lib/recycledcloud/LDAP.ex

81 lines
2.1 KiB
Elixir

defmodule RecycledCloud.LDAP do
require Logger
require Exldap
use GenServer
# Every request to the LDAP backend go through this GenServer.
def start_link(_) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(_) do
{:ok, connect()}
end
def handle_call({:pool, query}, _from, state) do
case state do
%{status: :ok, conn: ldap_conn} ->
result = internal_execute_query(query, ldap_conn)
if (result == {:error, :ldap_closed}) do
{:reply, result, connect()}
else
{:reply, result, state}
end
%{status: :error, conn: nil} ->
state = connect()
if (state.status == :ok) do
result = internal_execute_query(query, state.conn)
{:reply, result, state}
else
error = {:error, "Unable to contact backend"}
{:reply, error, state}
end
end
end
def handle_call({:single, query}, _from, state) do
single_state = connect()
case single_state do
%{status: :ok, conn: ldap_conn} ->
result = internal_execute_query(query, ldap_conn)
close(ldap_conn)
{:reply, result, state}
%{status: :error, conn: nil} ->
error = {:error, "Unable to contact backend"}
{:reply, error, state}
end
end
def terminate(reason, state) do
if (state.status == :ok), do: close(state.conn)
IO.inspect(reason)
#Logger.info "Terminating LDAP backend: #{reason}."
end
###
def execute(query), do: GenServer.call(__MODULE__, {:pool, query})
def execute_single(query), do: GenServer.call(__MODULE__, {:single, query})
###
defp internal_execute_query(query, ldap_conn), do: query.(ldap_conn)
defp connect do
case Exldap.connect do
{:ok, ldap_conn} ->
Logger.info "Successfuly connected to LDAP server."
%{status: :ok, conn: ldap_conn}
{:error, err} ->
Logger.warning "Failed to connect to LDAP server: #{err}. Authentication will not be possible."
%{status: :error, conn: nil}
end
end
defp close(ldap_conn) do
ldap_conn |> Exldap.close
Logger.debug("An LDAP connection was closed.")
end
end