55 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Elixir
		
	
	
	
	
	
			
		
		
	
	
			55 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Elixir
		
	
	
	
	
	
defmodule Pleroma.Password do
 | 
						|
  @moduledoc """
 | 
						|
  This module handles password hashing and verification.
 | 
						|
  It will delegate to the appropriate module based on the password hash.
 | 
						|
  It also handles upgrading of password hashes.
 | 
						|
  """
 | 
						|
 | 
						|
  alias Pleroma.User
 | 
						|
  alias Pleroma.Password.Pbkdf2
 | 
						|
  require Logger
 | 
						|
 | 
						|
  @hashing_module Argon2
 | 
						|
 | 
						|
  @spec hash_pwd_salt(String.t()) :: String.t()
 | 
						|
  defdelegate hash_pwd_salt(pass), to: @hashing_module
 | 
						|
 | 
						|
  @spec checkpw(String.t(), String.t()) :: boolean()
 | 
						|
  def checkpw(password, "$2" <> _ = password_hash) do
 | 
						|
    # Handle bcrypt passwords for Mastodon migration
 | 
						|
    Bcrypt.verify_pass(password, password_hash)
 | 
						|
  end
 | 
						|
 | 
						|
  def checkpw(password, "$pbkdf2" <> _ = password_hash) do
 | 
						|
    Pbkdf2.verify_pass(password, password_hash)
 | 
						|
  end
 | 
						|
 | 
						|
  def checkpw(password, "$argon2" <> _ = password_hash) do
 | 
						|
    Argon2.verify_pass(password, password_hash)
 | 
						|
  end
 | 
						|
 | 
						|
  def checkpw(_password, _password_hash) do
 | 
						|
    Logger.error("Password hash not recognized")
 | 
						|
    false
 | 
						|
  end
 | 
						|
 | 
						|
  @spec maybe_update_password(User.t(), String.t()) ::
 | 
						|
          {:ok, User.t()} | {:error, Ecto.Changeset.t()}
 | 
						|
  def maybe_update_password(%User{password_hash: "$2" <> _} = user, password) do
 | 
						|
    do_update_password(user, password)
 | 
						|
  end
 | 
						|
 | 
						|
  def maybe_update_password(%User{password_hash: "$6" <> _} = user, password) do
 | 
						|
    do_update_password(user, password)
 | 
						|
  end
 | 
						|
 | 
						|
  def maybe_update_password(%User{password_hash: "$pbkdf2" <> _} = user, password) do
 | 
						|
    do_update_password(user, password)
 | 
						|
  end
 | 
						|
 | 
						|
  def maybe_update_password(user, _), do: {:ok, user}
 | 
						|
 | 
						|
  defp do_update_password(user, password) do
 | 
						|
    User.reset_password(user, %{password: password, password_confirmation: password})
 | 
						|
  end
 | 
						|
end
 |