Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop
[akkoma] / test / web / oauth / ldap_authorization_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 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 ExUnit.CaptureLog
11 import Mock
12
13 @skip if !Code.ensure_loaded?(:eldap), do: :skip
14
15 clear_config_all([:ldap, :enabled]) do
16 Pleroma.Config.put([:ldap, :enabled], true)
17 end
18
19 clear_config_all(Pleroma.Web.Auth.Authenticator) do
20 Pleroma.Config.put(Pleroma.Web.Auth.Authenticator, Pleroma.Web.Auth.LDAPAuthenticator)
21 end
22
23 @tag @skip
24 test "authorizes the existing user using LDAP credentials" do
25 password = "testpassword"
26 user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
27 app = insert(:oauth_app, scopes: ["read", "write"])
28
29 host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
30 port = Pleroma.Config.get([:ldap, :port])
31
32 with_mocks [
33 {:eldap, [],
34 [
35 open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
36 simple_bind: fn _connection, _dn, ^password -> :ok end,
37 close: fn _connection ->
38 send(self(), :close_connection)
39 :ok
40 end
41 ]}
42 ] do
43 conn =
44 build_conn()
45 |> post("/oauth/token", %{
46 "grant_type" => "password",
47 "username" => user.nickname,
48 "password" => password,
49 "client_id" => app.client_id,
50 "client_secret" => app.client_secret
51 })
52
53 assert %{"access_token" => token} = json_response(conn, 200)
54
55 token = Repo.get_by(Token, token: token)
56
57 assert token.user_id == user.id
58 assert_received :close_connection
59 end
60 end
61
62 @tag @skip
63 test "creates a new user after successful LDAP authorization" do
64 password = "testpassword"
65 user = build(:user)
66 app = insert(:oauth_app, scopes: ["read", "write"])
67
68 host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
69 port = Pleroma.Config.get([:ldap, :port])
70
71 with_mocks [
72 {:eldap, [],
73 [
74 open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
75 simple_bind: fn _connection, _dn, ^password -> :ok end,
76 equalityMatch: fn _type, _value -> :ok end,
77 wholeSubtree: fn -> :ok end,
78 search: fn _connection, _options ->
79 {:ok,
80 {:eldap_search_result, [{:eldap_entry, '', [{'mail', [to_charlist(user.email)]}]}],
81 []}}
82 end,
83 close: fn _connection ->
84 send(self(), :close_connection)
85 :ok
86 end
87 ]}
88 ] do
89 conn =
90 build_conn()
91 |> post("/oauth/token", %{
92 "grant_type" => "password",
93 "username" => user.nickname,
94 "password" => password,
95 "client_id" => app.client_id,
96 "client_secret" => app.client_secret
97 })
98
99 assert %{"access_token" => token} = json_response(conn, 200)
100
101 token = Repo.get_by(Token, token: token) |> Repo.preload(:user)
102
103 assert token.user.nickname == user.nickname
104 assert_received :close_connection
105 end
106 end
107
108 @tag @skip
109 test "falls back to the default authorization when LDAP is unavailable" do
110 password = "testpassword"
111 user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
112 app = insert(:oauth_app, scopes: ["read", "write"])
113
114 host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
115 port = Pleroma.Config.get([:ldap, :port])
116
117 with_mocks [
118 {:eldap, [],
119 [
120 open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:error, 'connect failed'} end,
121 simple_bind: fn _connection, _dn, ^password -> :ok end,
122 close: fn _connection ->
123 send(self(), :close_connection)
124 :ok
125 end
126 ]}
127 ] do
128 log =
129 capture_log(fn ->
130 conn =
131 build_conn()
132 |> post("/oauth/token", %{
133 "grant_type" => "password",
134 "username" => user.nickname,
135 "password" => password,
136 "client_id" => app.client_id,
137 "client_secret" => app.client_secret
138 })
139
140 assert %{"access_token" => token} = json_response(conn, 200)
141
142 token = Repo.get_by(Token, token: token)
143
144 assert token.user_id == user.id
145 end)
146
147 assert log =~ "Could not open LDAP connection: 'connect failed'"
148 refute_received :close_connection
149 end
150 end
151
152 @tag @skip
153 test "disallow authorization for wrong LDAP credentials" do
154 password = "testpassword"
155 user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
156 app = insert(:oauth_app, scopes: ["read", "write"])
157
158 host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
159 port = Pleroma.Config.get([:ldap, :port])
160
161 with_mocks [
162 {:eldap, [],
163 [
164 open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
165 simple_bind: fn _connection, _dn, ^password -> {:error, :invalidCredentials} end,
166 close: fn _connection ->
167 send(self(), :close_connection)
168 :ok
169 end
170 ]}
171 ] do
172 conn =
173 build_conn()
174 |> post("/oauth/token", %{
175 "grant_type" => "password",
176 "username" => user.nickname,
177 "password" => password,
178 "client_id" => app.client_id,
179 "client_secret" => app.client_secret
180 })
181
182 assert %{"error" => "Invalid credentials"} = json_response(conn, 400)
183 assert_received :close_connection
184 end
185 end
186 end