In my app, I have the need for multiple user tables.
Devise does a killer job (via warden) to authenticate via varying tables & warden scopes.
Is there a good mechanism to do this with this library (without an umbrella)?
Yeah, Pow is built to be very flexible in this regard. The configuration happens in the plug:
plug Pow.Plug.Session,
repo: MyApp.Repo,
user: MyApp.User,
current_user_assigns_key: :current_user,
session_key: "auth",
session_store: {Pow.Store.CredentialsCache,
ttl: :timer.minutes(30),
namespace: "credentials"},
session_ttl_renewal: :timer.minutes(15),
cache_store_backend: Pow.Store.Backend.EtsCache,
users_context: Pow.Ecto.Users
So you should be able to set it up with scopes.
I would love to see a tutorial or demo for how it works in Devise so I can confirm that Pow can do the same thing. Is this what you want? https://github.com/plataformatec/devise/wiki/How-to-Setup-Multiple-Devise-User-Models
That's basically it (for devise).
For my needs devise is perfect b/c I don't deal with scoping/authorization. I can use the devise scope current_admin, current_buyer, current_seller respectively, and it pretty well isolates the concerns of those users. 馃槂
This is a great use case for Pow 馃槃 I'll test it out to see what tweaks are necessary, but I think that it's almost doable. The user sessions themselves are isolated.
But if Pow.Plug.Session is called multiple times in the same scope, it'll only fetch the last plug configuration in the controllers. It should be possible to fix if I can pass namespace configuration to routes.
I'll get back to this later when I've got a chance to work on it.
I'm working on a PR to make this possible right now. It will work like this:
Let's say that you would like to access both a user and admin session in the same scope.
Pow has built-in isolation with :namespace configuration, so this will be simple. Note that the same can be done with less configuration in an umbrella setup using the :otp_app configuration.
mix pow.ecto.install -r MyApp.Repo Admin admins
mix pow.ecto.install -r MyApp.Repo User users
Update WEB_PATH/endpoint.ex with the two namespaced configurations:
plug Pow.Plug.Session,
repo: MyApp.Repo,
user: MyApp.User,
namespace: :user
plug Pow.Plug.Session,
repo: MyApp.Repo,
user: MyApp.Admin,
namespace: :admin
The user can be accessed in assigns[:current_user][:user] and assigns[:current_user][:admin], and the configurations can be accessed in conn.private[:pow_config][:user] and conn.private[:pow_config][:admin].
Update WEB_PATH/router.ex to access the namespaced configurations:
scope "/user", private: %{pow_config_namespace: :user} do
pipe_through :browser
pow_routes()
end
scope "/admin", private: %{pow_config_namespace: :admin} do
pipe_through :browser
pow_routes()
end
That's it! Your namespaced configuration is now shared with the controller.
If you wish to modify the templates, you'll need to generate run the generate mix task with namespace argument:
mix pow.phoenix.gen.templates --namespace user
mix pow.phoenix.gen.templates --namespace admin
Remember to set up both configurations with web_module: MyAppWeb. The namespace is automatically used from the configuration to discover the templates and views.
Sorry for the delay, other work took my time. I've created a PR #24.
You can read the guide here: https://github.com/danschultzer/pow/blob/e725d04b2a9e91565a1c7c1075411e0ae2cec792/guides/MULTIPLE_USERS_IN_SAME_SCOPE.md
I've closed #24 as I didn't feel it was the right approach. I think this is better left to the developer as there's several things to consider in how the contexts are separated. Pow has been refactored quite a lot and with #56, it's now possible to handle several contexts with routes too. This was the last issue that bugged me. Most of the work will just be in figuring out how the pipelines in the router should be set up.
I'll prepare for a 1.0.0 release first, but eventually I'll look into a guide explaining how to handle multiple contexts in same connection with Pow 馃槃
Most helpful comment
This is a great use case for Pow 馃槃 I'll test it out to see what tweaks are necessary, but I think that it's almost doable. The user sessions themselves are isolated.
But if
Pow.Plug.Sessionis called multiple times in the same scope, it'll only fetch the last plug configuration in the controllers. It should be possible to fix if I can pass namespace configuration to routes.I'll get back to this later when I've got a chance to work on it.