Skip to content

Access Control and Data Validation for Clojure(Script) written in Clojure Spec.

License

Notifications You must be signed in to change notification settings

degree9/covenant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Covenant

Clojars Project Dependencies Status Downloads CircleCI

Access Control and Data Validation for Clojure(Script) written in Clojure Spec.

A covenant, is a solemn promise to engage in or refrain from a specified action. - Wikipedia



Covenant is developed and maintained by Degree9


Covenant is divided into a few namespaces:

  • covenant.core ICovenant protocol and public api.
  • covenant.schema type/value based data comparison on top of clojure.spec.
  • covenant.acl provides covenants around Access Control List's (ACL).
  • covenant.rbac provides covenants around Role Based Access Control (RBAC).
  • covenant.abac provides covenants around Attribute Based Access Control (ABAC).

Usage

ICovenant Protocol

Covenant exposes a protocol that closely matches cljs native spec.

(defprotocol ICovenant
  "Provides an abstraction for validating data using clojure.spec based on a covenant."
  (assert   [covenant data] "See clojure.spec/assert.")
  (conform  [covenant data] "See clojure.spec/conform.")
  (explain  [covenant data] "See clojure.spec/explain.")
  (problems [covenant data] "See clojure.spec/explain-data.")
  (validate [covenant data] "See clojure.spec/valid?.")
  (spec     [covenant]      "Returns related spec for `covenant`."))

The spec function will return a spec based on the passed data.

A simple example is that (covenant.core/spec nil) will return :covenant.core/nil which is preregistered with spec as (clojure.spec.alpha/def :covenant.core/nil nil?).

Scalar primitives simply return a spec/predicate based on their data type while collections also compare their contents.

RBAC

covenant.rbac provides validation fns that are "loose" for collections.

If some values in the passed collection (deep) matches the passed covenant then covenant.core/validate returns true after covenant.rbac has been required.

(require 'covenant.rbac)
(covenant.core/validate {:roles [:admin :editor]} {:roles [:admin]}) ; true
(covenant.core/validate {:roles [:admin :editor]} {:roles [:admin :editor]}) ; true
(covenant.core/validate {:roles [:admin :editor]} {:roles [:editor]}) ; true
(covenant.core/validate {:roles [:admin :editor]} {:roles []}) ; false
(covenant.core/validate {:roles [:admin :editor]} {:roles [:foo]}) ; false

Examples

(:require covenant.core :as covenant)

For more examples check out the test suite.

A vanilla spec + scalar primitive will pass covenant/explain.

(covenant/explain :covenant.core/number 1)
; =>
;Success!

Patreon
Support this and other open-source projects on Patreon!


Releases

No releases published

Packages

No packages published