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