
Kit向けの柔軟で構成可能な認可フレームワーク(Action Policyに触発)
Kit向けの柔軟で構成可能な認可フレームワーク。RubyのAction Policyにインスパイアされています。
[TOC]
| ファイル | 説明 |
|---|---|
.editorconfig | エディタのフォーマット設定 |
.gitignore | ビルド成果物と依存関係のGit無視ルール |
.tool-versions | asdfツールバージョン(Zig, Kit) |
LICENSE | MITライセンスファイル |
README.md | このファイル |
examples/blog-policy.kit | ブログ認可の例 |
kit.toml | メタデータ、タスク、リンター設定を含むパッケージマニフェスト |
src/core.kit | コア認可ヘルパー |
src/error.kit | 認可エラー、結果型、失敗理由 |
src/main.kit | パッケージルートモジュール |
src/scope.kit | スコープ、述語、ページネーションヘルパー |
tests/policy.test.kit | ポリシーのエンドツーエンド動作テスト |
tests/types.test.kit |
Kitパッケージの依存関係はありません。
kit add gitlab.com/kit-lang/packages/kit-policy.git
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
Result Bool PolicyError を返すポリシー関数のためのコアヘルパー。
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
事前チェックヘルパーは Option Bool を返します:Some true は許可、Some false は拒否、None はメインルールに継続します。
PolicyCore.admin-bypass is-admin? ctx
PolicyCore.owner-check is-owner? resource ctx
PolicyCore.first-pre-check [check1, check2, check3]
アクションヘルパーは、一般的なアクショングループとエイリアスを提供します。
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
ポリシー合成ヘルパーは、複数の認可結果を組み合わせます。
PolicyCore.all-allowed? [result1, result2, result3]
PolicyCore.any-allowed? [result1, result2, result3]
スコープヘルパーは、呼び出し元にデータを返す前にコレクションをフィルタリングします。
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
述語コンビネータは、再利用可能なスコープチェックを構築するのに便利です。
PolicyScope.both? pred1 pred2 item
PolicyScope.either? pred1 pred2 item
PolicyScope.not-matching? pred item
ページネーションヘルパーは1始まりです。
page1 = PolicyScope.paginate 1 10 items
pages = PolicyScope.total-pages 10 items
info = PolicyScope.pagination-info 1 10 items
認可失敗のためのエラー型と結果型。
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
ヘルパー関数はモジュールからエクスポートされており、PolicyError としてインポートするとモジュール関数として呼び出せます。
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
Result Bool PolicyError を返します。:index、:show、:create、:update、:destroy といったキーワードを使用します。インタプリタでブログポリシーの例を実行する:
kit run examples/blog-policy.kit
サンプルをネイティブバイナリにコンパイルする:
kit build examples/blog-policy.kit && ./blog-policy
テストスイートを実行する:
kit test
カバレッジ付きでテストスイートを実行する:
kit test --coverage
標準の開発ワークフロー(フォーマット、チェック、テスト)を実行する:
kit dev
これにより:
src/ 内のソースファイルのフォーマットとチェックexamples/ 内のサンプルの型チェックtests/ 内のテストをカバレッジ付きで実行サンプルでパリティチェックを実行する:
kit parity --failures-only
ドキュメントコメントからAPIドキュメントを生成する:
kit doc
注意: ドキュメントコメント(##)を含むKitソースは、docs/*.html にHTMLドキュメントを生成します。
生成ファイル、キャッシュ、ビルド成果物を削除する:
kit task clean
注意: kit.toml で定義されています。
開発用にこのパッケージをローカルにインストールする:
kit install
これにより、パッケージが ~/.kit/packages/@kit/policy/ にインストールされ、他のプロジェクトで Kit.Policy としてインポートできるようになります。
このパッケージはMITライセンスのもとで公開されています - 詳細は LICENSE を参照してください。
| ポリシーの型とヘルパーのテスト |