Merge branch 'feature/rich-media-part-2-electric-boogaloo' into 'develop'
[akkoma] / test / web / oauth / oauth_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.OAuth.OAuthControllerTest do
6 use Pleroma.Web.ConnCase
7 import Pleroma.Factory
8
9 alias Pleroma.Repo
10 alias Pleroma.Web.OAuth.{Authorization, Token}
11
12 test "redirects with oauth authorization" do
13 user = insert(:user)
14 app = insert(:oauth_app)
15
16 conn =
17 build_conn()
18 |> post("/oauth/authorize", %{
19 "authorization" => %{
20 "name" => user.nickname,
21 "password" => "test",
22 "client_id" => app.client_id,
23 "redirect_uri" => app.redirect_uris,
24 "state" => "statepassed"
25 }
26 })
27
28 target = redirected_to(conn)
29 assert target =~ app.redirect_uris
30
31 query = URI.parse(target).query |> URI.query_decoder() |> Map.new()
32
33 assert %{"state" => "statepassed", "code" => code} = query
34 assert Repo.get_by(Authorization, token: code)
35 end
36
37 test "correctly handles wrong credentials", %{conn: conn} do
38 user = insert(:user)
39 app = insert(:oauth_app)
40
41 result =
42 conn
43 |> post("/oauth/authorize", %{
44 "authorization" => %{
45 "name" => user.nickname,
46 "password" => "wrong",
47 "client_id" => app.client_id,
48 "redirect_uri" => app.redirect_uris,
49 "state" => "statepassed"
50 }
51 })
52 |> html_response(:unauthorized)
53
54 # Keep the details
55 assert result =~ app.client_id
56 assert result =~ app.redirect_uris
57
58 # Error message
59 assert result =~ "Invalid"
60 end
61
62 test "issues a token for an all-body request" do
63 user = insert(:user)
64 app = insert(:oauth_app)
65
66 {:ok, auth} = Authorization.create_authorization(app, user)
67
68 conn =
69 build_conn()
70 |> post("/oauth/token", %{
71 "grant_type" => "authorization_code",
72 "code" => auth.token,
73 "redirect_uri" => app.redirect_uris,
74 "client_id" => app.client_id,
75 "client_secret" => app.client_secret
76 })
77
78 assert %{"access_token" => token} = json_response(conn, 200)
79 assert Repo.get_by(Token, token: token)
80 end
81
82 test "issues a token for `password` grant_type with valid credentials" do
83 password = "testpassword"
84 user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
85
86 app = insert(:oauth_app)
87
88 conn =
89 build_conn()
90 |> post("/oauth/token", %{
91 "grant_type" => "password",
92 "username" => user.nickname,
93 "password" => password,
94 "client_id" => app.client_id,
95 "client_secret" => app.client_secret
96 })
97
98 assert %{"access_token" => token} = json_response(conn, 200)
99 assert Repo.get_by(Token, token: token)
100 end
101
102 test "issues a token for request with HTTP basic auth client credentials" do
103 user = insert(:user)
104 app = insert(:oauth_app)
105
106 {:ok, auth} = Authorization.create_authorization(app, user)
107
108 app_encoded =
109 (URI.encode_www_form(app.client_id) <> ":" <> URI.encode_www_form(app.client_secret))
110 |> Base.encode64()
111
112 conn =
113 build_conn()
114 |> put_req_header("authorization", "Basic " <> app_encoded)
115 |> post("/oauth/token", %{
116 "grant_type" => "authorization_code",
117 "code" => auth.token,
118 "redirect_uri" => app.redirect_uris
119 })
120
121 assert %{"access_token" => token} = json_response(conn, 200)
122 assert Repo.get_by(Token, token: token)
123 end
124
125 test "rejects token exchange with invalid client credentials" do
126 user = insert(:user)
127 app = insert(:oauth_app)
128
129 {:ok, auth} = Authorization.create_authorization(app, user)
130
131 conn =
132 build_conn()
133 |> put_req_header("authorization", "Basic JTIxOiVGMCU5RiVBNCVCNwo=")
134 |> post("/oauth/token", %{
135 "grant_type" => "authorization_code",
136 "code" => auth.token,
137 "redirect_uri" => app.redirect_uris
138 })
139
140 assert resp = json_response(conn, 400)
141 assert %{"error" => _} = resp
142 refute Map.has_key?(resp, "access_token")
143 end
144
145 test "rejects token exchange for valid credentials belonging to unconfirmed user and confirmation is required" do
146 setting = Pleroma.Config.get([:instance, :account_activation_required])
147
148 unless setting do
149 Pleroma.Config.put([:instance, :account_activation_required], true)
150 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
151 end
152
153 password = "testpassword"
154 user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
155 info_change = Pleroma.User.Info.confirmation_changeset(user.info, :unconfirmed)
156
157 {:ok, user} =
158 user
159 |> Ecto.Changeset.change()
160 |> Ecto.Changeset.put_embed(:info, info_change)
161 |> Repo.update()
162
163 refute Pleroma.User.auth_active?(user)
164
165 app = insert(:oauth_app)
166
167 conn =
168 build_conn()
169 |> post("/oauth/token", %{
170 "grant_type" => "password",
171 "username" => user.nickname,
172 "password" => password,
173 "client_id" => app.client_id,
174 "client_secret" => app.client_secret
175 })
176
177 assert resp = json_response(conn, 403)
178 assert %{"error" => _} = resp
179 refute Map.has_key?(resp, "access_token")
180 end
181
182 test "rejects an invalid authorization code" do
183 app = insert(:oauth_app)
184
185 conn =
186 build_conn()
187 |> post("/oauth/token", %{
188 "grant_type" => "authorization_code",
189 "code" => "Imobviouslyinvalid",
190 "redirect_uri" => app.redirect_uris,
191 "client_id" => app.client_id,
192 "client_secret" => app.client_secret
193 })
194
195 assert resp = json_response(conn, 400)
196 assert %{"error" => _} = json_response(conn, 400)
197 refute Map.has_key?(resp, "access_token")
198 end
199 end