Liking cljdoc? Tell your friends :D

scopula.core

Handles scopes logic.

Scopes are case-sensitive strings without any whitespace, that represent authorization access. From OAuth2 RFC (https://tools.ietf.org/html/rfc6749#section-3.3):

The value of the scope parameter is expressed as a list of space- delimited, case-sensitive strings. The strings are defined by the authorization server. If the value contains multiple space-delimited strings, their order does not matter, and each string adds an additional access range to the requested scope.

scope = scope-token ( SP scope-token ) scope-token = 1( %x21 / %x23-5B / %x5D-7E )

In order to manage fine-grained authorizations, this lib uses a convention for scope formats. For example, we often need to distinguish between a full scope that will provides full access to some resource, and read-only access. Sometimes we also want to limit the access to some sub-resource. Here are some examples of our convention:

users full access to users resource users/profile access to users profile only users/profile:read access to users profile read-only users/profile/email:write access to users profile only email write-only

Mainly : is only authorized to split between access read/write/rw (nothing implies rw).

Sub-resources can be separated by /.

This library provides helper functions to check that a given scope will also grant e.g. users/profile/email and users/profile:read.

We also provide helpers to normalize sets of scopes:

(normalize-scopes #{"users" "users/profile/email:read" "admin"}) #{"users" "admin"}

...as users/profile/email:read is redundant, it is removed.

Note that scopes are meant to be used in an OAuth2 access in mind, and thus are generally manipulated as a set of scopes.

scopes that do not have any subpath are called root scopes.

This is important because it is easy to add, union scopes. But it is generally impossible to remove just a sub-scope as it would mean we should know all the sub-paths of some root-scope and add the difference.

Scope are additive by nature.

Handles scopes logic.

Scopes are case-sensitive strings without any whitespace, that represent
authorization access. From OAuth2 RFC (https://tools.ietf.org/html/rfc6749#section-3.3):

> The value of the scope parameter is expressed as a list of space-
> delimited, case-sensitive strings.  The strings are defined by the
> authorization server.  If the value contains multiple space-delimited
> strings, their order does not matter, and each string adds an
> additional access range to the requested scope.
>
>   scope       = scope-token *( SP scope-token )
>   scope-token = 1*( %x21 / %x23-5B / %x5D-7E )

In order to manage fine-grained authorizations, this lib uses a convention
for scope formats.
For example, we often need to distinguish between a full scope that will provides
full access to some resource, and read-only access.
Sometimes we also want to limit the access to some sub-resource.
Here are some examples of our convention:

`users`                      full access to users resource
`users/profile`              access to users profile only
`users/profile:read`         access to users profile read-only
`users/profile/email:write`  access to users profile only email write-only

Mainly `:` is only authorized to split between access read/write/rw
(nothing implies rw).

Sub-resources can be separated by `/`.

This library provides helper functions to check that
a given scope will also grant e.g. `users/profile/email` and `users/profile:read`.

We also provide helpers to normalize sets of scopes:

>>> (normalize-scopes #{"users" "users/profile/email:read" "admin"})
#{"users" "admin"}

...as `users/profile/email:read` is redundant, it is removed.

Note that scopes are meant to be used in an OAuth2 access in mind, and thus
are generally manipulated as a set of scopes.

scopes that do not have any subpath are called _root scopes_.

This is important because it is easy to add, union scopes.
But it is generally impossible to remove just a sub-scope as it would
mean we should know all the sub-paths of some root-scope and add the difference.

Scope are additive by nature.
raw docstring

accepted-by-scopesclj/s

(accepted-by-scopes scopes required)

scopes should be strings. if none of the string contains a / nor a :. It works as is a subset of.

:scopes #{"foo" "bar"} only people with scopes which are super sets of #{"foo" "bar"} will be allowed to use the route.

scopes are considered as path with read/write access. so "foo/bar/baz:read" is a sub-scope of "foo" and of "foo:read".

So the more precise rule of access is. All mandatory scopes must be sub-scopes of at least one user scopes.

Also mandatory the scopes and required should be normalized

`scopes` should be strings.
if none of the string contains a `/` nor a `:`.
It works as is a subset of.

:scopes #{"foo" "bar"}
only people with scopes which are super sets of
#{"foo" "bar"}
will be allowed to use the route.

scopes are considered as path with read/write access.
so "foo/bar/baz:read" is a sub-scope of "foo"
and of "foo:read".

So the more precise rule of access is.
All mandatory scopes must be sub-scopes of at least one user scopes.

Also mandatory the scopes and required should be normalized
sourceraw docstring

access-grantedclj/s

(access-granted scopes required)

Checks that the first parameter contains all the required scopes given as second parameter.

Checks that the first parameter contains all the required scopes
given as second parameter.
sourceraw docstring

add-scopeclj/s

(add-scope scope scopes)

Add the scope to a set of scopes.

Add the scope to a set of scopes.
sourceraw docstring

allowed-chars-no-colon-no-slashclj/s

source

allowed-wordclj/s

source

is-root-scope?clj/s

(is-root-scope? scope)
source

is-scope-alias?clj/s

(is-scope-alias? scope)
source

is-scope-aliases-map?clj/s

(is-scope-aliases-map? aliases)
source

is-scope-format-valid?clj/s

(is-scope-format-valid? scope)
source

is-sub-list?clj/s

(is-sub-list? lst super-lst)

Does super-lst begin with lst?

Does `super-lst` begin with `lst`?
sourceraw docstring

is-subscope?clj/s

(is-subscope? scope-to-check super-scope)

Returns whether the scope-to-check is a subscope of the super-scope

Returns whether the `scope-to-check` is a subscope of the `super-scope`
sourceraw docstring

merge-accessesclj/s

(merge-accesses [path reprs])
source

normalize-scopesclj/s

(normalize-scopes scopes)

Given a set of scopes, remove reduntant ones, and merge them by access if possible.

Given a set of scopes, remove reduntant ones, and merge them by access if possible.
sourceraw docstring

raw-repr-scope-disjclj/s

(raw-repr-scope-disj rscopes rs-to-remove)

Removes a scope from a set of scopes.

Removes a scope from a set of scopes.
sourceraw docstring

repr-is-strict-subpath?clj/s

(repr-is-strict-subpath? r1 r2)

Return whether the first argument is strictly a sub-path of the second argument.

Return whether the first argument is strictly a sub-path of the second argument.
sourceraw docstring

repr-is-subscope?clj/s

(repr-is-subscope? scope-to-check super-scope)

Returns whether the scope-to-check is a subscope of the super-scope

Returns whether the `scope-to-check` is a subscope of the `super-scope`
sourceraw docstring

repr-is-subsummedclj/s

(repr-is-subsummed repr-scope repr-scopes)

Return whether a scope is contained by all the scopes.

Examples that return true:

(is-subsummed "foo" #{"foo"}) (is-subsummed "foo:read" #{"foo"}) (is-subsummed "foo/sub/scope" #{"foo"}) (is-subsummed "foo/sub/scope:read" #{"foo"})

Examples that return false:

(is-subsummed "foo" #{"foo:read" "bar"}) (is-subsummed "foo:read" #{"foo:read" "bar"}) (is-subsummed "foo/sub/scope" #{"foo:read"})

Return whether a scope is contained by all the scopes.

Examples that return true:

(is-subsummed "foo" #{"foo"})
(is-subsummed "foo:read" #{"foo"})
(is-subsummed "foo/sub/scope" #{"foo"})
(is-subsummed "foo/sub/scope:read" #{"foo"})

Examples that return false:

(is-subsummed "foo" #{"foo:read" "bar"})
(is-subsummed "foo:read" #{"foo:read" "bar"})
(is-subsummed "foo/sub/scope" #{"foo:read"})
sourceraw docstring

repr-normalize-scopesclj/s

(repr-normalize-scopes scopes-repr)
source

repr-scope-disjclj/s

(repr-scope-disj repr-scopes rs-to-rm)

Remove a scope for a set of scopes. Will throw an exception if the scope to remove is a subscope of some scope in the scopes set.

Remove a scope for a set of scopes.
Will throw an exception if the scope to remove is a subscope of some scope in
the scopes set.
sourceraw docstring

repr-scope-intersectionclj/s

(repr-scope-intersection r1 r2)

Returns the maximal intersection between two scopes reprs.

(to-scope-repr "foo:write") and (to-scope-repr "foo/bar") => (to-scope-repr "foo/bar:write")

Returns the maximal intersection between two scopes reprs.

`(to-scope-repr "foo:write")` and `(to-scope-repr "foo/bar")`
=> `(to-scope-repr "foo/bar:write")`
sourceraw docstring

repr-scope-removeclj/s

(repr-scope-remove rs rs-to-remove)

While inputs should be in repr form, removes the single scope rs-to-remove from the single scope rs.

Returns nil if the two scopes do not intersect.

If the operation is not possible (for example, remove foo/bar from foo) this function throw an exception.

If the two scopes intersect for the path but their access is different that mean some access should be remove. As exemple, removing foo:write from foo/bar/baz should endup with foo/bar/baz:read.

While inputs should be in repr form,
removes the single scope `rs-to-remove` from the single scope `rs`.

Returns `nil` if the two scopes do not intersect.

If the operation is not possible (for example, remove `foo/bar` from `foo`)
this function throw an exception.

If the two scopes intersect for the path but their access is different that
mean some access should be remove. As exemple, removing `foo:write` from
`foo/bar/baz` should endup with `foo/bar/baz:read`.
sourceraw docstring

repr-scopes-intersect?clj/s

(repr-scopes-intersect? r1 r2)

Returns whether r1 and r2 intersect.

For example: (to-scope-repr foo:write) and (to-scope-repr foo/bar) intersect, while neither of those scopes reprs is a subscope of another.

Returns whether r1 and r2 intersect.

For example: `(to-scope-repr foo:write)` and `(to-scope-repr foo/bar)`
intersect, while neither of those scopes reprs is a subscope of another.
sourceraw docstring

repr-scopes-intersectingclj/s

(repr-scopes-intersecting rs-1 rs-2)

Asymmetrical operation; returns the list of first scopes repr that intersect with some scopes repr of the second set of scopes repr.

Asymmetrical operation; returns the list of first scopes repr that intersect
with some scopes repr of the second set of scopes repr.
sourceraw docstring

repr-scopes-intersectionclj/s

(repr-scopes-intersection sr1 sr2)

Return the intersection between two set of scopes.

Return the intersection between two set of scopes.
sourceraw docstring

repr-scopes-missingclj/s

(repr-scopes-missing scopes-1 scopes-2)

Return the list of scopes-1 that is not in scopes-2

Return the list of `scopes-1` that is not in `scopes-2`
sourceraw docstring

root-scopeclj/s

(root-scope scope)

Returns the root of a scope.

(root-scope "foo/bar:read") foo

Returns the root of a scope.

>>> (root-scope "foo/bar:read")
foo
sourceraw docstring

safe-scopes-expandclj/s

(safe-scopes-expand scopes aliases)

Same as scope expand but return nil instead of throwing and exception if a scope alias is missing

Same as scope expand but return nil instead of throwing and exception if a scope alias is missing
sourceraw docstring

scope-alias-regexclj/s

source

scope-consclj/s

source

scope-differenceclj/s

(scope-difference scopes scopes-to-remove)

Very similar to scopes-missing, but taking care of throwing an exception if some sub-scope cannot be removed. This would prevent an error when trying to reduce a set of scopes.

(scope-difference #{"foo/bar"} #{"foo:write"}) => #{"foo/bar:read"}

keep foo/bar but removed all :write from super-scope foo.

Very similar to `scopes-missing`, but taking care of throwing an exception if
some sub-scope cannot be removed. This would prevent an error when trying to
reduce a set of scopes.

(scope-difference #{"foo/bar"} #{"foo:write"})
=> #{"foo/bar:read"}

keep foo/bar but removed all :write from super-scope foo.
sourceraw docstring

scope-disjclj/s

(scope-disj scopes scope-to-remove)

Remove a scope from a set of scopes. Throw an error if trying to remove a subscope of an existing scope.

Remove a scope from a set of scopes. Throw an error if trying to remove a
subscope of an existing scope.
sourceraw docstring

scope-intersectionclj/s

(scope-intersection scope-1 scope-2)

Returns the maximal intersection between two scopes.

foo:write and foo/bar => foo/bar:write

Returns the maximal intersection between two scopes.

`foo:write` and `foo/bar` => `foo/bar:write` 
sourceraw docstring

scope-regexclj/s

source

scope-repr-to-strclj/s

(scope-repr-to-str {:keys [path access]})
source

scope-rootclj/s

(scope-root scope)

Displays the root of a scope.

(scope-root "foo/bar:read") foo

Displays the root of a scope.

>>> (scope-root "foo/bar:read")
foo
sourceraw docstring

scope-unionclj/s

(scope-union scopes-1 scopes-2)

Unionize two set of scopes.

Unionize two set of scopes.
sourceraw docstring

scopes-compressclj/s

(scopes-compress scopes aliases)

Given a set of scopes and a dictionary of scopes aliases use a fast heuristic to compress scopes with scope aliases.

It is more important to have a fast function than an efficient one. The best possible compression is clearly an NP-complete problem.

What we do, we first sort aliases by the size of string that would be generated to list all the scopes. So for example:

{"+foo" {"x" "y"}
"+bar" {"very-long-name-for-a-scope"}
}

the scope alias +bar will be preferred as even if the set contain fewer elements, the sum of the length of the scopes in the scopes set is longer.

Given a set of scopes and a dictionary of scopes aliases
use a fast heuristic to compress scopes with scope aliases.

It is more important to have a fast function than an efficient one.
The best possible compression is clearly an NP-complete problem.

What we do, we first sort aliases by the size of string that would be generated to list all the scopes.
So for example:

```
{"+foo" {"x" "y"}
"+bar" {"very-long-name-for-a-scope"}
}
```

the scope alias +bar will be preferred as even if the set contain fewer elements, the sum of the length
of the scopes in the scopes set is longer.
sourceraw docstring

scopes-expandclj/s

(scopes-expand scopes aliases)

Given a set of scopes containing scope aliases expand them.

Scopes aliases will be replaced, so the output of scopes-expand should not contain any scope alias.

If some scope alias is missing in the scope-aliases-map, scope expand will throw an exception.

Given a set of scopes containing scope aliases expand them.

Scopes aliases will be replaced, so the output of scopes-expand should not contain
any scope alias.

If some scope alias is missing in the scope-aliases-map, scope expand will throw an exception.
sourceraw docstring

scopes-intersect?clj/s

(scopes-intersect? scope-1 scope-2)

Returns whether scope-1 and scope-2 intersect.

For example: foo:write and foo/bar intersect while neither of those scope is a subscope of another.

Returns whether scope-1 and scope-2 intersect.

For example: `foo:write` and `foo/bar` intersect while
neither of those scope is a subscope of another.
sourceraw docstring

scopes-intersectingclj/s

(scopes-intersecting scopes-1 scopes-2)

Asymmetrical operation; returns the list of first scopes that intersect with some scopes of the second set of scopes.

Asymmetrical operation; returns the list of first scopes that intersect with
some scopes of the second set of scopes.
sourceraw docstring

scopes-intersectionclj/s

(scopes-intersection scopes-1 scopes-2)

Return the intersection between two set of scopes.

Return the intersection between two set of scopes.
sourceraw docstring

scopes-lengthclj/s

(scopes-length scopes)

Return the sum of the length of string in a set of scopes.

Return the sum of the length of string in a set of scopes.
sourceraw docstring

scopes-missingclj/s

(scopes-missing scopes-1 scopes-2)

Return the elements of the first set of scopes, removing those in the second set of scopes

Return the elements of the first set of scopes, removing those in the second set
of scopes
sourceraw docstring

scopes-subset?clj/s

(scopes-subset? required scopes)

Flipped version of scopes-superset?. Returns true if the first set is a subset of the second set of scopes.

Flipped version of scopes-superset?.
Returns true if the first set is a subset of the second set of scopes.
sourceraw docstring

scopes-superset?clj/s

Returns true if the first set of scopes is a superset of the second set of scopes. This is another name for access-granted function

Returns true if the first set of scopes is a superset of the second set of scopes.
This is another name for `access-granted` function
sourceraw docstring

to-scope-reprclj/s

(to-scope-repr txt)

Transforms a textual scope as an internal representation to help check rules, typically:

"foo" {:path ["foo"] :access #{:read :write}}

"foo/bar/baz:write" {:path ["foo" "bar" "baz"] :access #{:write}}

Transforms a textual scope as an internal representation to help
check rules, typically:

> "foo"
{:path ["foo"]
 :access #{:read :write}}

> "foo/bar/baz:write"
{:path ["foo" "bar" "baz"]
 :access #{:write}}
sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close