pow icon indicating copy to clipboard operation
pow copied to clipboard

Multitenancy without multiple schemas

Open choallin opened this issue 4 years ago • 2 comments

I have an app where I need multitenancy without schemas.
I have a column in the users table which I use for that. How can I achieve this with pow? Is there a repository function that I can implement to use for a user lookup?

choallin avatar Oct 12 '20 08:10 choallin

This is pretty application specific, but you would likely need something similar to the multitenancy guide: https://hexdocs.pm/pow/1.0.21/multitenancy.html#content

As you fetch the tenant in the conn, you would then pass that value on to the repo to use for any calls thereafter. I would use the :repo_opts for that, and implement a custom MyApp.MultitenancyRepo module. That repo module needs to implement get_by/3, delete/2, insert/2 and update/2 where you handle the table-based multitenancy by pulling the tenant from the :repo_opts, modify the query in get_by/2 or the changeset in the other functions, and then call MyApp.Repo.

danschultzer avatar Oct 12 '20 15:10 danschultzer

Sorry to come back to this again. :-/ I have a created this repo as you mentioned, also I am trying to fetch the data from the conn which is working for me.
But I don't know how to configure this custom "repo" to have access to this tenant_id field.
Here is what I have done so far:

Fetching the subdomain to access the tenant name:

defmodule AppointmentManagerWeb.Pow.TenantPlug do
  def init(config), do: config

  def call(conn, config) do
    subdomain = conn.host |> String.split(".") |> List.first
    config = Keyword.put(config, :repo_opts, [prefix: subdomain])

    Pow.Plug.Session.call(conn, config)
  end
end

endpoint.ex

plug Plug.Session,
    store: :cookie,
    key: "_my_app_key",
    signing_salt: "stuff"

  plug MyApp.Pow.TenantPlug
  plug Pow.Plug.Session,
    otp_app: :my_app,
    credentials_cache_store: {Pow.Store.CredentialsCache,
                              ttl: :timer.minutes(60*12),
                              namespace: "credentials"}

pow config:

config :my_app, :pow,
  user: MyApp.Users.User,
  repo: MyApp.MultitenancyRepo,
  extensions: [PowResetPassword],
  controller_callbacks: Pow.Extension.Phoenix.ControllerCallbacks,
  mailer_backend: MyApp.Mailer,
  web_module: MyAppWeb,
  users_context: MyApp.Users

What do I have to do, to get access to the configuration in my "Repo"?

choallin avatar Dec 10 '20 12:12 choallin