MishkaCmsCore. Runtime. Resources. Validations. TenantContext
(Mishka CMS Core v0.0.1)
Copy Markdown
View Source
Holds an action to the kind of caller it was written for: a master, or a site.
A MASTER is a user whose site_id is nil (MishkaCmsCore.Accounts.Helper.master_user?/1).
Nothing else makes one: not a missing actor, not an actor with no site_id, not a permission
(* included), not the absence of a tenant.
Options
:require_master- Required boolean.true: the action is a master's. The actor must be a master and the tenant must be nil.false: the action is a site's. A tenant must be given. A site user may give only its own site as the tenant; a master may give any site; a visitor with no actor acts on the site it is visiting.
A call made with authorize?: false is a system call (the installer, seeds, workers, internal
reads) and is not checked.
The check reads the actor the changeset, query or action input was BUILT with. Build it with the
actor that runs it: one built with no actor is refused a master action, whoever runs it later.
Who may run an action is still the resource's policies' question; this only keeps each action to
its own kind of caller. The policies ask the actor the action RUNS with, and
MishkaCmsCore.Accounts.Checks.AccessPermissions gives a site user none of its permissions under
another site's tenant or for a master's action (requires_master?/2), so an input built with
another actor, or with none, still keeps a site user to its own site wherever a policy authorizes
through that check.
Usage
alias MishkaCmsCore.Runtime.Resources.Validations.TenantContext
create :master_create do
validate {TenantContext, require_master: true}
end
create :create do
validate {TenantContext, require_master: false}
end
action :master_update, :struct do
validate {TenantContext, require_master: true}
endError messages
- A master action given a tenant: "Tenant context must be nil for this action. Use the tenant action instead."
- A master action run by anyone but a master: "This action requires a master user, an account that belongs to no site. Site users use the tenant action instead." For a site user it is an invalid-input error; for nobody (no actor, or one that is not a user) it is a forbidden error, as a policy refusal is.
- A tenant action given no tenant: Ash's own
Ash.Error.Invalid.TenantRequired, the error Ash gives any query or change that needs a tenant and has none. The JSON:API shows both as400 tenant_required: "Tenant context is required for this action. Use the master action instead." - A tenant action run by a site user for another site: "A site user can act only on their own site.", a forbidden error.
Summary
Functions
Initializes the validation with provided options.
Whether action of resource is a master's: it declares this validation with
require_master: true. Takes the action or its name; nil is no action.
Validates tenant context based on the action requirements.
Functions
Initializes the validation with provided options.
Parameters
opts- Keyword list containing::require_master- Boolean indicating if master context is required
Returns
{:ok, opts}with validated options
@spec requires_master?(Ash.Resource.t(), atom() | struct() | nil) :: boolean()
Whether action of resource is a master's: it declares this validation with
require_master: true. Takes the action or its name; nil is no action.
Validates tenant context based on the action requirements.
Parameters
subject- The Ash changeset or action input being validatedopts- Validation options containing :require_master flagcontext- Context containing tenant and authorization information
Returns
:okif validation passes{:error, message: String.t()}if validation fails