View Source LetMe (LetMe v0.2.0)
LetMe is library for defining and evaluating authorization rules and handling query scopes and field redactions.
This module only defines auxiliary functions. The main functionality lies in
the LetMe.Policy
module.
Link to this section Summary
Functions
Takes a list of rules and a list of filter options and returns a filtered list of rules.
Takes a struct or a list of structs and redacts fields depending on the subject (user).
Removes redacted fields from a given list of fields.
Link to this section Functions
Takes a list of rules and a list of filter options and returns a filtered list of rules.
This function is used by LetMe.Policy.list_rules/1
.
filter-options
Filter options
:object
- Matches an object exactly.:action
- Matches an action exactly.:allow
- Either a check name as an atom or a 2-tuple with the check name and the options.:deny
- Either a check name as an atom or a 2-tuple with the check name and the options.
If an atom is passed as allow
or deny
, the atom is interpreted as a check
name and all rules using the given check name are returned, regardless of
whether additional options are passed to the check. If a 2-tuple is passed,
the first tuple element must be the check name as an atom and the second
tuple element must be the check options. In this case, all rules are returned
that use the given check with exactly the same options. In either case, rules
that have more checks in addition to the given one will also be returned.
examples
Examples
iex> rules = [
...> %LetMe.Rule{action: :create, name: :article_create, object: :article},
...> %LetMe.Rule{action: :create, name: :category_create, object: :category}
...> ]
iex> filter_rules(rules, object: :article)
[%LetMe.Rule{action: :create, name: :article_create, object: :article}]
iex> rules = [
...> %LetMe.Rule{
...> action: :create,
...> name: :article_create,
...> object: :article,
...> allow: [[role: :editor]]
...> },
...> %LetMe.Rule{
...> action: :update,
...> name: :article_update,
...> object: :article,
...> allow: [:own_resource, [role: :writer]]
...> }
...> ]
iex> filter_rules(rules, allow: :own_resource)
[%LetMe.Rule{action: :update, name: :article_update, object: :article, allow: [:own_resource, [role: :writer]]}]
iex> match?([_, _], filter_rules(rules, allow: :role))
true
iex> filter_rules(rules, allow: {:role, :editor})
[%LetMe.Rule{action: :create, name: :article_create, object: :article, allow: [[role: :editor]]}]
iex> filter_rules(rules, allow: {:role, :writer})
[%LetMe.Rule{action: :update, name: :article_update, object: :article, allow: [:own_resource, [role: :writer]]}]
@spec redact(struct(), any(), keyword()) :: struct()
@spec redact( [struct()], any(), keyword() ) :: [struct()]
@spec redact( nil, any(), keyword() ) :: nil
Takes a struct or a list of structs and redacts fields depending on the subject (user).
Uses the callback implementation for LetMe.Schema.redacted_fields/2
in the
struct module.
options
Options
:redact_value
- The value to be used for redacted fields. Defaults to:redacted
.
example
Example
iex> article = %MyApp.Blog.Article{}
iex> user = %{id: 2, role: :user}
iex> redact(article, user)
%MyApp.Blog.Article{like_count: :redacted, title: "Give us back our moon dust and cockroaches", user_id: 1, view_count: :redacted}
iex> article = %MyApp.Blog.Article{}
iex> user = %{id: 2, role: :user}
iex> redact(article, user, redact_value: nil)
%MyApp.Blog.Article{like_count: nil, title: "Give us back our moon dust and cockroaches", user_id: 1, view_count: nil}
iex> articles = [
...> %MyApp.Blog.Article{},
...> %MyApp.Blog.Article{user_id: 2, title: "Joey Chestnut is chomp champ"}
...> ]
iex> user = %{id: 2, role: :user}
iex> redact(articles, user)
[%MyApp.Blog.Article{like_count: :redacted, title: "Give us back our moon dust and cockroaches", user_id: 1, view_count: :redacted}, %MyApp.Blog.Article{like_count: 25, title: "Joey Chestnut is chomp champ", user_id: 2, view_count: :redacted}]
Removes redacted fields from a given list of fields.
Uses the LetMe.Schema.redacted_fields/2
callback implementation of the
struct module to determine the fields to remove.
examples
Examples
iex> fields = [:like_count, :title, :user_id, :view_count]
iex> user = %{id: 1, role: :user}
iex> article = %MyApp.Blog.Article{}
iex> reject_redacted_fields(fields, article, user)
[:like_count, :title, :user_id]
This can be useful as a safeguard to prevent accidentally casting fields the user is not allowed to see and thereby nilifying or replacing them.
def update_changeset(%Article{} = article, attrs, %User{} = user) do
fields = LetMe.reject_redacted_fields(
[:title, :body, :internal_reference],
article,
user
)
article
|> cast(attrs, fields)
|> validate_required([:title, :body])
end