Skip to content

Commit 5caf4f5

Browse files
committed
Update password validation post
1 parent 4c28c9f commit 5caf4f5

File tree

1 file changed

+56
-9
lines changed

1 file changed

+56
-9
lines changed

_guides/2019-09-14-password-breach-lookup-and-other-password-validation-rules.md

+56-9
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ defmodule MyApp.Users.User do
216216
|> String.downcase()
217217
|> password_in_dictionary?()
218218
|> case do
219-
true -> [password: "is too common"]
219+
true -> [password: "is dictionary word"]
220220
false -> []
221221
end
222222
end)
@@ -245,8 +245,8 @@ You may want to ensure that users update their password if they have been breach
245245
This can be dealt with in a plug, or [custom controller](https://hexdocs.pm/pow/custom_controllers.html). A plug method could look like this:
246246

247247
```elixir
248-
def check_password(conn, _opts) do
249-
changeset = MyApp.Users.User.changeset(%MyApp.Users.User{}, conn.params["user"])
248+
def check_password(%{params: %{"user" => user_params}} = conn, _opts) do
249+
changeset = MyApp.Users.User.changeset(%MyApp.Users.User{}, user_params)
250250

251251
case changeset.errors[:password] do
252252
nil ->
@@ -299,13 +299,13 @@ defmodule MyApp.Users.UserTest do
299299
end
300300

301301
# The below is for username user id
302-
changeset = User.changeset(%User{}, %{"username" => "john.doe", "password" => "password12"})
303-
refute changeset.errors[:password]
302+
# changeset = User.changeset(%User{}, %{"username" => "john.doe", "password" => "password12"})
303+
# refute changeset.errors[:password]
304304

305-
for invalid <- ["john.doe00", "johndoe", "johndoe1"] do
306-
changeset = User.changeset(%User{}, %{"username" => "john.doe", "password" => invalid})
307-
assert changeset.errors[:password] == {"is too similar to username, email or My Demo App", []}
308-
end
305+
# for invalid <- ["john.doe00", "johndoe", "johndoe1"] do
306+
# changeset = User.changeset(%User{}, %{"username" => "john.doe", "password" => invalid})
307+
# assert changeset.errors[:password] == {"is too similar to username, email or My Demo App", []}
308+
# end
309309
end
310310

311311
test "changeset/2 validates repetitive and sequential password" do
@@ -327,5 +327,52 @@ defmodule MyApp.Users.UserTest do
327327
changeset = User.changeset(%User{}, %{"password" => "secretafgh"})
328328
refute changeset.errors[:password]
329329
end
330+
331+
@dictionary_word "anteater"
332+
333+
test "changeset/2 validates dictionary word" do
334+
changeset = User.changeset(%User{}, %{"password" => @dictionary_word})
335+
assert changeset.errors[:password] == {"is dictionary word", []}
336+
337+
changeset = User.changeset(%User{}, %{"password" => "#{@dictionary_word} battery staple"})
338+
refute changeset.errors[:password]
339+
end
340+
end
341+
```
342+
343+
```elixir
344+
defmodule Pow.Controllers.SessionControllerTest do
345+
use MyAppWeb.ConnCase
346+
347+
alias MyApp.{Repo, Users.User}
348+
349+
describe "POST /session" do
350+
@weak_password "123456"
351+
@strong_password "horse battery staple"
352+
353+
test "with insecure password", %{conn: conn} do
354+
user = user_fixture(@weak_password)
355+
conn = post(conn, Routes.pow_session_path(conn, :create), %{"user" => %{"email" => user.email, password: @weak_password}})
356+
357+
assert redirected_to(conn) == Routes.pow_reset_password_reset_password_path(conn, :new)
358+
refute Pow.Plug.current_user(conn)
359+
assert get_flash(conn, :error) == "You have to reset your password because it has sequential characters"
360+
end
361+
362+
test "with strong password", %{conn: conn} do
363+
user = user_fixture(@strong_password)
364+
conn = post(conn, Routes.pow_session_path(conn, :create), %{"user" => %{"email" => user.email, password: @strong_password}})
365+
366+
assert redirected_to(conn) == Routes.pow_reset_password_reset_password_path(conn, :new)
367+
assert Pow.Plug.current_user(conn)
368+
end
369+
end
370+
371+
defp user_fixture(password) do
372+
Repo.insert!(%User{
373+
374+
password_hash: Pow.Ecto.Schema.Password.pbkdf2_hash(password)
375+
})
376+
end
330377
end
331378
```

0 commit comments

Comments
 (0)