wire time_format into scope, add settings UI selector, change defaults to 24h, and replace all user-facing Calendar.strftime calls with centralized TimeHelpers using the user's timezone and time format.
84 lines
2.5 KiB
Elixir
84 lines
2.5 KiB
Elixir
defmodule Towerops.Accounts.Scope do
|
|
@moduledoc """
|
|
Defines the scope of the caller to be used throughout the app.
|
|
|
|
The `Towerops.Accounts.Scope` allows public interfaces to receive
|
|
information about the caller, such as if the call is initiated from an
|
|
end-user, and if so, which user. Additionally, such a scope can carry fields
|
|
such as "super user" or other privileges for use as authorization, or to
|
|
ensure specific code paths can only be access for a given scope.
|
|
|
|
It is useful for logging as well as for scoping pubsub subscriptions and
|
|
broadcasts when a caller subscribes to an interface or performs a particular
|
|
action.
|
|
|
|
Feel free to extend the fields on this struct to fit the needs of
|
|
growing application requirements.
|
|
"""
|
|
|
|
alias Towerops.Accounts.User
|
|
alias Towerops.Organizations.Organization
|
|
|
|
defstruct user: nil, superuser: nil, impersonating?: false, organization: nil, timezone: "UTC", time_format: "24h"
|
|
|
|
@doc """
|
|
Creates a scope for the given user.
|
|
|
|
Returns nil if no user is given.
|
|
"""
|
|
def for_user(%User{} = user) do
|
|
%__MODULE__{
|
|
user: user,
|
|
superuser: nil,
|
|
impersonating?: false,
|
|
timezone: user.timezone || "UTC",
|
|
time_format: user.time_format || "24h"
|
|
}
|
|
end
|
|
|
|
def for_user(nil), do: nil
|
|
|
|
@doc """
|
|
Creates a scope for a superuser impersonating another user.
|
|
|
|
The `user` field contains the impersonated user (what the superuser sees as),
|
|
while the `superuser` field contains the actual superuser performing the impersonation.
|
|
"""
|
|
def for_impersonation(%User{} = superuser, %User{} = target_user) do
|
|
%__MODULE__{
|
|
user: target_user,
|
|
superuser: superuser,
|
|
impersonating?: true,
|
|
timezone: target_user.timezone || "UTC",
|
|
time_format: target_user.time_format || "24h"
|
|
}
|
|
end
|
|
|
|
@doc """
|
|
Adds organization context to an existing scope.
|
|
|
|
Returns updated scope with organization field set.
|
|
"""
|
|
def put_organization(%__MODULE__{} = scope, %Organization{} = organization) do
|
|
%{scope | organization: organization}
|
|
end
|
|
|
|
def put_organization(%__MODULE__{} = scope, nil) do
|
|
%{scope | organization: nil}
|
|
end
|
|
|
|
def put_organization(nil, _organization), do: nil
|
|
|
|
@doc """
|
|
Returns true if the scope has superuser privileges.
|
|
|
|
This includes both:
|
|
- Regular users with is_superuser = true
|
|
- Superusers who are currently impersonating another user
|
|
"""
|
|
def superuser?(%__MODULE__{user: user, superuser: superuser}) do
|
|
(user && user.is_superuser) || (superuser && superuser.is_superuser)
|
|
end
|
|
|
|
def superuser?(nil), do: false
|
|
end
|