
Un framework d'autorisation flexible et composable pour Kit (inspiré par Action Policy)
# kit-policy
Un cadre d'autorisation flexible et composable pour Kit, inspiré de l'[Action Policy](https://actionpolicy.evilmartians.io/) de Ruby.
---
[TOC]
---
## Fichiers
| Fichier | Description |
|------|-------------|
| [`.editorconfig`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/.editorconfig) | Configuration de formatage de l'éditeur |
| [`.gitignore`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/.gitignore) | Règles Git ignore pour les artefacts de construction et dépendances |
| [`.tool-versions`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/.tool-versions) | Versions d'outils asdf (Zig, Kit) |
| [`LICENSE`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/LICENSE) | Fichier de licence MIT |
| [`README.md`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/README.md) | Ce fichier |
| [`examples/blog-policy.kit`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/examples/blog-policy.kit) | Exemple d'autorisation de blog |
| [`kit.toml`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/kit.toml) | Manifeste du paquet avec métadonnées, tâches et configuration de lint |
| [`src/core.kit`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/src/core.kit) | Aides d'autorisation principales |
| [`src/error.kit`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/src/error.kit) | Erreurs d'autorisation, types de résultats et raisons d'échec |
| [`src/main.kit`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/src/main.kit) | Module racine du paquet |
| [`src/scope.kit`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/src/scope.kit) | Aides de portée, prédicats et pagination |
| [`tests/policy.test.kit`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/tests/policy.test.kit) | Tests de comportement de politique de bout en bout |
| [`tests/types.test.kit`](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/tests/types.test.kit) | Tests de types et d'aides de politique |
## Dépendances
_Aucune dépendance de paquet Kit._
## Installation
```console
kit add gitlab.com/kit-lang/packages/kit-policy.git
```
## Utilisation
```kit
import Kit.Policy.Core as PolicyCore
import Kit.Policy.Error as PolicyError
import Kit.Policy.Scope as PolicyScope
type Post = {id: Int, author-id: Int, published?: Bool, title: String}
type User = {id: Int, admin?: Bool}
type AuthContext = {user: User}
post-policy = fn(post, ctx, action) =>
if ctx.user.admin? then
PolicyCore.allow
else
match PolicyCore.resolve-alias action
| :show -> PolicyCore.allow-if post.published?
| :update -> PolicyCore.allow-if (ctx.user.id == post.author-id)
| :destroy -> PolicyCore.allow-if (ctx.user.id == post.author-id)
| _ -> PolicyCore.no-rule action
post-scope = fn(posts, ctx) =>
if ctx.user.admin? then
posts
else
posts |>> List.filter (fn(post) => post.published?)
main = fn =>
user = {id: 1, admin?: false}
ctx = {user: user}
post = {id: 1, author-id: 1, published?: true, title: "Hello"}
posts = [post]
if PolicyCore.can-with? post-policy post ctx :update then
println "Can update post"
else
println "Cannot update post"
visible-posts = PolicyScope.scope-with post-scope posts ctx
page = PolicyScope.paginate 1 10 visible-posts
info = PolicyScope.pagination-info 1 10 visible-posts
println "Visible posts: ${page}"
println "Pages: ${info.pages}"
err = PolicyError.not-authorized "Post" :update "not the author"
println (PolicyError.message err)
main
```
## Aperçu de l'API
### Policy.Core
Aides principales pour les fonctions de politique qui retournent `Result Bool PolicyError`.
```kit
PolicyCore.can-with? policy resource context action
PolicyCore.may-with? policy resource context action
PolicyCore.allow
PolicyCore.deny
PolicyCore.allow-if condition
PolicyCore.deny-if condition
PolicyCore.no-rule action
PolicyCore.allow-or-deny condition resource-name reason action
```
Les aides de pré-vérification retournent `Option Bool` : `Some true` autorise, `Some false` refuse, et `None` continue vers la règle principale.
```kit
PolicyCore.admin-bypass is-admin? ctx
PolicyCore.owner-check is-owner? resource ctx
PolicyCore.first-pre-check [check1, check2, check3]
```
Les aides d'action fournissent des groupes d'actions et des alias courants.
```kit
PolicyCore.crud-actions
PolicyCore.read-actions
PolicyCore.write-actions
PolicyCore.read-action? action
PolicyCore.write-action? action
PolicyCore.resolve-alias :new # :create
PolicyCore.resolve-alias :edit # :update
PolicyCore.resolve-alias :delete # :destroy
PolicyCore.resolve-alias :view # :show
```
Les aides de composition de politique combinent plusieurs résultats d'autorisation.
```kit
PolicyCore.all-allowed? [result1, result2, result3]
PolicyCore.any-allowed? [result1, result2, result3]
```
### Policy.Scope
Les aides de portée filtrent les collections avant de renvoyer les données à un appelant.
```kit
PolicyScope.scope-with scope-fn items ctx
PolicyScope.filter-by predicate items
PolicyScope.is-owned-by? get-owner-id get-user-id item ctx
PolicyScope.is-published? get-published item
PolicyScope.is-in-state? get-state target-state item
PolicyScope.is-admin-or? check-admin fallback-check ctx item
```
Les combinateurs de prédicats sont utiles pour construire des vérifications de portée réutilisables.
```kit
PolicyScope.both? pred1 pred2 item
PolicyScope.either? pred1 pred2 item
PolicyScope.not-matching? pred item
```
Les aides de pagination sont indexées à partir de 1.
```kit
page1 = PolicyScope.paginate 1 10 items
pages = PolicyScope.total-pages 10 items
info = PolicyScope.pagination-info 1 10 items
```
### Policy.Error
Types d'erreur et de résultat pour les échecs d'autorisation.
```kit
type PolicyError =
| NotAuthorized {resource: String, action: Keyword, reason: String}
| RuleNotFound {action: Keyword}
| ContextMissing {field: String}
| PolicyNotFound {resource-type: String}
| CustomError String
type FailureReason = FailureReason {
policy: String,
action: Keyword,
details: String
}
type AuthResult =
| Allowed
| Denied String
```
Les fonctions d'aide sont exportées depuis le module, donc lorsqu'elles sont importées en tant que `PolicyError`, elles sont appelées comme des fonctions du module.
```kit
PolicyError.not-authorized resource action reason
PolicyError.rule-not-found action
PolicyError.context-missing field
PolicyError.policy-not-found resource-type
PolicyError.custom message
PolicyError.message err
PolicyError.kind err
PolicyError.is-not-authorized? err
PolicyError.is-rule-not-found? err
PolicyError.new policy action
PolicyError.with-details policy action details
PolicyError.policy reason
PolicyError.action reason
PolicyError.details reason
PolicyError.format reason
PolicyError.allowed
PolicyError.denied reason
PolicyError.is-allowed? result
PolicyError.is-denied? result
PolicyError.reason result
PolicyError.to-result resource-name action result
```
## Notes de conception
- Les politiques sont de simples fonctions, donc faciles à tester et à composer.
- L'autorisation est explicite : les aides retournent `Result Bool PolicyError` au lieu de lever des exceptions.
- Les portées sont séparées des vérifications de politique afin que le filtrage de liste puisse avoir lieu avant le rendu ou la sérialisation.
- Les actions courantes utilisent des mots-clés tels que `:index`, `:show`, `:create`, `:update` et `:destroy`.
- Le paquet est indépendant de tout framework et peut être utilisé avec n'importe quel code d'application Kit.
## Développement
### Exécution des exemples
Exécutez l'exemple de politique de blog avec l'interpréteur :
```console
kit run examples/blog-policy.kit
```
Compilez l'exemple en binaire natif :
```console
kit build examples/blog-policy.kit && ./blog-policy
```
### Exécution des tests
Exécutez la suite de tests :
```console
kit test
```
Exécutez la suite de tests avec couverture :
```console
kit test --coverage
```
### Exécution de kit dev
Exécutez le workflow de développement standard (formatage, vérification, tests) :
```console
kit dev
```
Cela va :
1. Formater et vérifier les fichiers sources dans `src/`
2. Vérifier les types des exemples dans `examples/`
3. Exécuter les tests dans `tests/` avec couverture
### Vérification de la parité interpréteur/compilateur
Exécutez les vérifications de parité pour les exemples :
```console
kit parity --failures-only
```
### Génération de documentation
Générez la documentation API à partir des commentaires de documentation :
```console
kit doc
```
**Note** : Les sources Kit avec des commentaires de documentation (`##`) généreront des documents HTML dans `docs/*.html`.
### Nettoyage des artefacts de construction
Supprimez les fichiers générés, caches et artefacts de construction :
```console
kit task clean
```
**Note** : Défini dans [kit.toml](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/kit.toml).
## Installation locale
Pour installer ce paquet localement pour le développement :
```console
kit install
```
Cela installe le paquet dans `~/.kit/packages/@kit/policy/`, le rendant disponible pour importation en tant que `Kit.Policy` dans d'autres projets.
## Licence
Ce paquet est publié sous la licence MIT - voir [LICENSE](https://gitlab.com/kit-lang/packages/kit-policy/-/blob/main/LICENSE) pour les détails.