Merge branch 'fix/2302-report-duplicates' into 'develop'
[akkoma] / lib / pleroma / web / plugs / authentication_plug.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.Plugs.AuthenticationPlug do
6 alias Pleroma.User
7
8 import Plug.Conn
9
10 require Logger
11
12 def init(options), do: options
13
14 def checkpw(password, "$6" <> _ = password_hash) do
15 :crypt.crypt(password, password_hash) == password_hash
16 end
17
18 def checkpw(password, "$2" <> _ = password_hash) do
19 # Handle bcrypt passwords for Mastodon migration
20 Bcrypt.verify_pass(password, password_hash)
21 end
22
23 def checkpw(password, "$pbkdf2" <> _ = password_hash) do
24 Pbkdf2.verify_pass(password, password_hash)
25 end
26
27 def checkpw(_password, _password_hash) do
28 Logger.error("Password hash not recognized")
29 false
30 end
31
32 def maybe_update_password(%User{password_hash: "$2" <> _} = user, password) do
33 do_update_password(user, password)
34 end
35
36 def maybe_update_password(%User{password_hash: "$6" <> _} = user, password) do
37 do_update_password(user, password)
38 end
39
40 def maybe_update_password(user, _), do: {:ok, user}
41
42 defp do_update_password(user, password) do
43 user
44 |> User.password_update_changeset(%{
45 "password" => password,
46 "password_confirmation" => password
47 })
48 |> Pleroma.Repo.update()
49 end
50
51 def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
52
53 def call(
54 %{
55 assigns: %{
56 auth_user: %{password_hash: password_hash} = auth_user,
57 auth_credentials: %{password: password}
58 }
59 } = conn,
60 _
61 ) do
62 if checkpw(password, password_hash) do
63 {:ok, auth_user} = maybe_update_password(auth_user, password)
64
65 conn
66 |> assign(:user, auth_user)
67 |> Pleroma.Web.Plugs.OAuthScopesPlug.skip_plug()
68 else
69 conn
70 end
71 end
72
73 def call(%{assigns: %{auth_credentials: %{password: _}}} = conn, _) do
74 Pbkdf2.no_user_verify()
75 conn
76 end
77
78 def call(conn, _), do: conn
79 end