First
[anni] / test / pleroma / web / o_auth / ldap_authorization_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
6   use Pleroma.Web.ConnCase
7   alias Pleroma.Repo
8   alias Pleroma.Web.OAuth.Token
9   import Pleroma.Factory
10   import Mock
11
12   @skip if !Code.ensure_loaded?(:eldap), do: :skip
13
14   setup_all do: clear_config([:ldap, :enabled], true)
15
16   setup_all do: clear_config(Pleroma.Web.Auth.Authenticator, Pleroma.Web.Auth.LDAPAuthenticator)
17
18   @tag @skip
19   test "authorizes the existing user using LDAP credentials" do
20     password = "testpassword"
21     user = insert(:user, password_hash: Pleroma.Password.Pbkdf2.hash_pwd_salt(password))
22     app = insert(:oauth_app, scopes: ["read", "write"])
23
24     host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
25     port = Pleroma.Config.get([:ldap, :port])
26
27     with_mocks [
28       {:eldap, [],
29        [
30          open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
31          simple_bind: fn _connection, _dn, ^password -> :ok end,
32          close: fn _connection ->
33            send(self(), :close_connection)
34            :ok
35          end
36        ]}
37     ] do
38       conn =
39         build_conn()
40         |> post("/oauth/token", %{
41           "grant_type" => "password",
42           "username" => user.nickname,
43           "password" => password,
44           "client_id" => app.client_id,
45           "client_secret" => app.client_secret
46         })
47
48       assert %{"access_token" => token} = json_response(conn, 200)
49
50       token = Repo.get_by(Token, token: token)
51
52       assert token.user_id == user.id
53       assert_received :close_connection
54     end
55   end
56
57   @tag @skip
58   test "creates a new user after successful LDAP authorization" do
59     password = "testpassword"
60     user = build(:user)
61     app = insert(:oauth_app, scopes: ["read", "write"])
62
63     host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
64     port = Pleroma.Config.get([:ldap, :port])
65
66     with_mocks [
67       {:eldap, [],
68        [
69          open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
70          simple_bind: fn _connection, _dn, ^password -> :ok end,
71          equalityMatch: fn _type, _value -> :ok end,
72          wholeSubtree: fn -> :ok end,
73          search: fn _connection, _options ->
74            {:ok, {:eldap_search_result, [{:eldap_entry, '', []}], []}}
75          end,
76          close: fn _connection ->
77            send(self(), :close_connection)
78            :ok
79          end
80        ]}
81     ] do
82       conn =
83         build_conn()
84         |> post("/oauth/token", %{
85           "grant_type" => "password",
86           "username" => user.nickname,
87           "password" => password,
88           "client_id" => app.client_id,
89           "client_secret" => app.client_secret
90         })
91
92       assert %{"access_token" => token} = json_response(conn, 200)
93
94       token = Repo.get_by(Token, token: token) |> Repo.preload(:user)
95
96       assert token.user.nickname == user.nickname
97       assert_received :close_connection
98     end
99   end
100
101   @tag @skip
102   test "disallow authorization for wrong LDAP credentials" do
103     password = "testpassword"
104     user = insert(:user, password_hash: Pleroma.Password.Pbkdf2.hash_pwd_salt(password))
105     app = insert(:oauth_app, scopes: ["read", "write"])
106
107     host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
108     port = Pleroma.Config.get([:ldap, :port])
109
110     with_mocks [
111       {:eldap, [],
112        [
113          open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
114          simple_bind: fn _connection, _dn, ^password -> {:error, :invalidCredentials} end,
115          close: fn _connection ->
116            send(self(), :close_connection)
117            :ok
118          end
119        ]}
120     ] do
121       conn =
122         build_conn()
123         |> post("/oauth/token", %{
124           "grant_type" => "password",
125           "username" => user.nickname,
126           "password" => password,
127           "client_id" => app.client_id,
128           "client_secret" => app.client_secret
129         })
130
131       assert %{"error" => "Invalid credentials"} = json_response(conn, 400)
132       assert_received :close_connection
133     end
134   end
135 end