Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable DateTime types #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/deps
erl_crash.dump
*.ez
/.elixir_ls
3 changes: 2 additions & 1 deletion lib/coherence/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ defmodule Coherence.Config do
:user_schema,
:user_token,
{:verify_user_token, &Coherence.SessionService.verify_user_token/2},
:web_module
:web_module,
{:datetime_module, NaiveDateTime}
]
|> Enum.each(fn
{key, default} ->
Expand Down
2 changes: 1 addition & 1 deletion lib/coherence/controllers/confirmation_controller_base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ defmodule Coherence.ConfirmationControllerBase do
end
|> Map.merge(%{
confirmation_token: nil,
confirmed_at: NaiveDateTime.utc_now()
confirmed_at: Config.datetime_module().utc_now()
})

changeset = Controller.changeset(:confirmation, user_schema, user, attrs)
Expand Down
8 changes: 3 additions & 5 deletions lib/coherence/controllers/controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,11 @@ defmodule Coherence.Controller do
iex> ~N(2016-10-10 10:10:10)
...> |> Coherence.Controller.shift(days: -2)
...> |> to_string
"2016-10-08 10:10:10Z"
"2016-10-08 10:10:10"
"""
@spec shift(struct, Keyword.t()) :: struct
def shift(datetime, opts) do
datetime
|> NaiveDateTime.to_erl()
|> Timex.to_datetime()
|> Timex.shift(opts)
end

Expand Down Expand Up @@ -174,7 +172,7 @@ defmodule Coherence.Controller do
token = random_string(48)
url = router_helpers().confirmation_url(conn, :edit, token)
Logger.debug("confirmation email url: #{inspect(url)}")
dt = NaiveDateTime.utc_now()
dt = Config.datetime_module().utc_now()

user
|> user_schema.changeset(%{
Expand Down Expand Up @@ -226,7 +224,7 @@ defmodule Coherence.Controller do
can set this data far in the future to do a pseudo permanent lock.
"""
@spec lock!(Ecto.Schema.t(), struct) :: schema_or_error
def lock!(user, locked_at \\ NaiveDateTime.utc_now()) do
def lock!(user, locked_at \\ Config.datetime_module().utc_now()) do
user_schema = Config.user_schema()
changeset = user_schema.lock(user, locked_at)

Expand Down
2 changes: 1 addition & 1 deletion lib/coherence/controllers/password_controller_base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ defmodule Coherence.PasswordControllerBase do
def recover_password(conn, user_schema, user, params) do
token = random_string(48)
url = router_helpers().password_url(conn, :edit, token)
dt = NaiveDateTime.utc_now()
dt = Config.datetime_module().utc_now()
info = Messages.backend().reset_email_sent()

Config.repo().update!(
Expand Down
2 changes: 1 addition & 1 deletion lib/coherence/controllers/session_controller_base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ defmodule Coherence.SessionControllerBase do
|> track_lock(user, user.__struct__.trackable_table?())

{put_flash(new_conn, :error, Messages.backend().maximum_login_attempts_exceeded()),
%{locked_at: NaiveDateTime.utc_now()}}
%{locked_at: Config.datetime_module().utc_now()}}

true ->
{put_flash(
Expand Down
23 changes: 13 additions & 10 deletions lib/coherence/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ defmodule Coherence.Schema do

Returns a changeset ready for Repo.update
"""
def lock(user, locked_at \\ NaiveDateTime.utc_now()) do
def lock(user, locked_at \\ nil) do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use Config.datetime_module().utc_now() as a default param?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that default parameters are decided at compile time - then all locked users would have the same locked_at date.

Copy link
Author

@narrowtux narrowtux Jun 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I got this wrong - this suggests that the expression is only evaluated when needed: https://elixir-lang.org/getting-started/modules-and-functions.html#default-arguments

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, look:

defmodule MarsRover do
  def time(foo \\ NaiveDateTime.utc_now()) do
    foo
  end
end

iex [1] > MarsRover.time
~N[2019-06-20 13:58:51.149503]
iex [2] > MarsRover.time
~N[2019-06-20 13:58:52.923541]
iex [3] >

Again, thank you! <3

locked_at = locked_at || Config.datetime_module().utc_now()
Config.user_schema().changeset(user, %{locked_at: locked_at})
end

Expand All @@ -270,7 +271,8 @@ defmodule Coherence.Schema do
deprecated! Please use Coherence.ControllerHelpers.lock!/1.
"""

def lock!(user, locked_at \\ NaiveDateTime.utc_now()) do
def lock!(user, locked_at \\ nil) do
locked_at = locked_at || Config.datetime_module().utc_now()
IO.warn(
"#{inspect(Config.user_schema())}.lock!/1 has been deprecated. Please use Coherence.ControllerHelpers.lock!/1 instead."
)
Expand Down Expand Up @@ -419,7 +421,8 @@ defmodule Coherence.Schema do
end

"""
defmacro coherence_schema do
defmacro coherence_schema(opts \\ []) do
datetime_type = Keyword.get(opts, :datetime, :naive_datetime)
quote do
if Coherence.Config.has_option(:authenticatable) do
field(Config.password_hash(), :string)
Expand All @@ -434,17 +437,17 @@ defmodule Coherence.Schema do

if Coherence.Config.has_option(:recoverable) do
field(:reset_password_token, :string)
field(:reset_password_sent_at, :naive_datetime)
field(:reset_password_sent_at, unquote(datetime_type))
end

if Coherence.Config.has_option(:rememberable) do
field(:remember_created_at, :naive_datetime)
field(:remember_created_at, unquote(datetime_type))
end

if Coherence.Config.has_option(:trackable) do
field(:sign_in_count, :integer, default: 0)
field(:current_sign_in_at, :naive_datetime)
field(:last_sign_in_at, :naive_datetime)
field(:current_sign_in_at, unquote(datetime_type))
field(:last_sign_in_at, unquote(datetime_type))
field(:current_sign_in_ip, :string)
field(:last_sign_in_ip, :string)
end
Expand All @@ -455,7 +458,7 @@ defmodule Coherence.Schema do

if Coherence.Config.has_option(:lockable) do
field(:failed_attempts, :integer, default: 0)
field(:locked_at, :naive_datetime)
field(:locked_at, unquote(datetime_type))
end

if Coherence.Config.has_option(:unlockable_with_token) do
Expand All @@ -464,8 +467,8 @@ defmodule Coherence.Schema do

if Coherence.Config.has_option(:confirmable) do
field(:confirmation_token, :string)
field(:confirmed_at, :naive_datetime)
field(:confirmation_sent_at, :naive_datetime)
field(:confirmed_at, unquote(datetime_type))
field(:confirmation_sent_at, unquote(datetime_type))

if Coherence.Config.get(:confirm_email_updates) do
field(:unconfirmed_email, :string)
Expand Down
8 changes: 4 additions & 4 deletions lib/coherence/services/confirmable_service.ex
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ defmodule Coherence.ConfirmableService do
"""
def confirm(user) do
Schemas.change_user(user, %{
confirmed_at: NaiveDateTime.utc_now(),
confirmed_at: Config.datetime_module().utc_now(),
confirmation_token: nil
})
end
Expand All @@ -80,7 +80,7 @@ defmodule Coherence.ConfirmableService do

changeset =
Schemas.change_user(user, %{
confirmed_at: NaiveDateTime.utc_now(),
confirmed_at: Config.datetime_module().utc_now(),
confirmation_token: nil
})

Expand Down Expand Up @@ -114,7 +114,7 @@ defmodule Coherence.ConfirmableService do
"""
@spec confirm(Ecto.Schema.t()) :: Ecto.Changeset.t()
def confirm(user) do
Schemas.change_user(user, %{confirmed_at: NaiveDateTime.utc_now(), confirmation_token: nil})
Schemas.change_user(user, %{confirmed_at: Config.datetime_module().utc_now(), confirmation_token: nil})
end

@doc """
Expand All @@ -127,7 +127,7 @@ defmodule Coherence.ConfirmableService do
@spec confirm!(Ecto.Schema.t()) :: Ecto.Changeset.t() | {:error, Ecto.Changeset.t()}
def confirm!(user) do
changeset =
Schemas.change_user(user, %{confirmed_at: NaiveDateTime.utc_now(), confirmation_token: nil})
Schemas.change_user(user, %{confirmed_at: Config.datetime_module().utc_now(), confirmation_token: nil})

if confirmed?(user) do
changeset =
Expand Down
2 changes: 1 addition & 1 deletion lib/coherence/services/password_service.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule Coherence.PasswordService do
"""
def reset_password_token(user) do
token = Controller.random_string(48)
dt = NaiveDateTime.utc_now()
dt = Config.datetime_module().utc_now()

:password
|> Controller.changeset(user.__struct__, user, %{
Expand Down
6 changes: 3 additions & 3 deletions lib/coherence/services/trackable_service.ex
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ defmodule Coherence.TrackableService do
changeset =
Controller.changeset(:session, user.__struct__, user, %{
sign_in_count: user.sign_in_count + 1,
current_sign_in_at: NaiveDateTime.utc_now(),
current_sign_in_at: Config.datetime_module().utc_now(),
current_sign_in_ip: ip,
last_sign_in_at: last_at,
last_sign_in_ip: last_ip
Expand All @@ -98,7 +98,7 @@ defmodule Coherence.TrackableService do
Controller.changeset(:session, schema, schema.__struct__, %{
action: "login",
sign_in_count: trackable.sign_in_count + 1,
current_sign_in_at: NaiveDateTime.utc_now(),
current_sign_in_at: Config.datetime_module().utc_now(),
current_sign_in_ip: ip,
last_sign_in_at: last_at,
last_sign_in_ip: last_ip,
Expand Down Expand Up @@ -226,7 +226,7 @@ defmodule Coherence.TrackableService do
end

defp last_at_and_ip(conn, schema) do
now = NaiveDateTime.utc_now()
now = Config.datetime_module().utc_now()
ip = Plug.Conn.get_peer_data(conn) |> Map.get(:address) |> inspect()

cond do
Expand Down