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