2017-05-26 4 views
0

http://rny.io/elixir/phoenix/ldap/2016/09/20/ldap-authenication-with-phoenix.htmlのガイドに従って、PhoenixのGuardianでLDAP認証を設定しました。私はフェニックスとエリクシールにはかなり新しいので、物事を設定してテストするという動きを見ています。LDAPで認証するときにGuardian.Plug.EnsureAuthenticatedでテストに合格する

ガイドごとにすべての作業を行っていますが、コントローラーテストを作成するときにGuardian.Plug.EnsureAuthenticatedをどのように取得するかわかりません。私はここにいくつかのガイドが見つかりましたが、何も動作しているようです。

誰かが、exLDAPとGuardianでLDAP認証を設定していて、何らかのガイダンスを提供できるテスト用の適切なユーザーログインがありますか?どんな助けもありがとう。

以下

は私の設定です:

のlib/ldap_example/guardian_serializer.ex

defmodule LdapExample.GuardianSerializer do 
@behaviour Guardian.Serializer 
alias LdapExample.User 
alias LdapExample.Repo 

def for_token(user = %User{}), do: { :ok, "User:#{user.id}" } 
def for_token(_), do: { :error, "Unknown resource type" } 

def from_token("User:" <> id), do: { :ok, Repo.get(User, id) } 
def from_token(_), do: { :error, "Unknown resource type" } 
end 

のlib/ldap_example/ldap.ex

defmodule LdapExample.Ldap do 

    def authenticate(uid, password) do 
     {:ok, ldap_conn} = Exldap.open 
    bind = "uid=#{uid},dc=example,dc=com" 
    case Exldap.verify_credentials(ldap_conn, bind, password) do 
     :ok -> :ok 
     _ -> {:error, "Invalid username/password"} 
    end 
    end 



def get_by_uid(uid) do 
    {:ok, ldap_conn} = Exldap.connect 
    {:ok, search_results} = Exldap.search_field(ldap_conn, "uid", uid) 
    case search_results do 
     [] -> {:error, "Could not find user with uid #{uid}"} 
     _ -> search_results |> Enum.fetch(0) 
    end 
    end 



def to_map(entry) do 
    username = Exldap.search_attributes(entry, "uid") 
    name = Exldap.search_attributes(entry, "cn") 
    email = Exldap.search_attributes(entry, "mail") 
    %{username: username, name: name, email: email} 
    end 
end 

ウェブ/コントローラ/ session_controller.ex

defmodule LdapExample.SessionController do 
    use LdapExample.Web, :controller 
    alias LdapExample.{User, Repo, Ldap} 

    def new(conn, _params) do 
    render conn, "new.html", changeset: User.login_changeset 
    end 



def create(conn, %{"user" => params}) do 
    username = params["username"] 
    password = params["password"] 
    case Ldap.authenticate(username, password) do 
     :ok -> handle_sign_in(conn, username) 
     _ -> handle_error(conn) 
    end 
    end 

defp handle_sign_in(conn, username) do 
    {:ok, user} = insert_or_update_user(username) 
    conn 
    |> put_flash(:info, "Logged in.") 
    |> Guardian.Plug.sign_in(user) 
    |> redirect(to: page_path(conn, :index)) 
end 

defp insert_or_update_user(username) do 
    {:ok, ldap_entry} = Ldap.get_by_uid(username) 
    user_attributes = Ldap.to_map(ldap_entry) 
    user = Repo.get_by(User, username: username) 
    changeset = 
    case user do 
     nil -> User.changeset(%User{}, user_attributes) 
     _ -> User.changeset(user, user_attributes) 
    end 
    Repo.insert_or_update changeset 
end 

defp handle_error(conn) do 
    conn 
    |> put_flash(:error, "Wrong username or password") 
    |> redirect(to: session_path(conn, :new)) 
end 

def delete(conn, _params) do 
    Guardian.Plug.sign_out(conn) 
    |> put_flash(:info, "Logged out successfully.") 
    |> redirect(to: "/") 
end 

エンド

ウェブ/モデル/ user.ex

defmodule LdapExample.User do 
use LdapExample.Web, :model 

schema "users" do 
    field :username, :string 
    field :name, :string 
    field :email, :string 
    field :password, :string, virtual: true 
    timestamps() 
end 



def changeset(struct, params \\ %{}) do 
    struct 
    |> cast(params, [:username, :name, :email]) 
    |> validate_required([:username, :name, :email]) 
    end 



def login_changeset do 
    %__MODULE__{} |> cast(%{}, ~w(username password), ~w()) 
    end 
end 

次のように私はsession_controller_text.exを作成しました:

defmodule LdapExample.SessionControllerTest do 
    use LdapExample.ConnCase 
    alias LdapExample.User 



test "Get to Login page", %{conn: conn} do 
    conn = get conn, session_path(conn, :new) 
    assert html_response(conn, 200) =~ "Sign In" 
    end 

test "shows page only when logged in", %{conn: conn} do 
    conn = get conn, page_path(conn, :index) 
    assert html_response(conn, 200) =~ "Hello" 
    end 
end 

を、それがログインページに私をリダイレクトするよう最後のテストが失敗しました。

答えて

0

もちろん、bypass_throughを使用してテスト目的の認証プロセスをスキップする必要があります。 docsを詳しく読んでください。

+0

ありがとうございました。私は実際にテスト用のログインをシミュレートする方法を探していました。 – willfore

+0

LDAPとの接続を担当するモジュールを模擬しようとすると、ここに示すようなものがあります:http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/ – PatNowak

+0

これらは私の質問に答えました。ありがとうございました – willfore