Async user / group / permission management library backed by a Rust core (SQLite, Argon2, JWT, optional HTTP relay)
Project description
UserPermission
ユーザーとグループを管理するための非同期ライブラリです。 v0.4.0 から Rust 実装に移行し、Python 側は PyO3 + maturin による薄いラッパーになりました。
- Rust コア: tokio + sqlx(SQLite) + argon2 + jsonwebtoken
- Python API:
async with Database(...)の使い勝手はそのまま、ネイティブ拡張で高速化 - HTTP サーバー: axum で実装した REST API を
await user_permission.serve(...)またはuser-permission serveCLI から起動
v0.3 からの移行:
create_router/create_app/create_webui_router/create_relay_routerは廃止されました。Python の FastAPI に直接埋め込む代わりに、サーバーが必要な場合はawait user_permission.serve(...)を呼ぶか、Rust バイナリ (cargo install user-permission) を別プロセスで起動してください。fastapi/server/webui/relayの optional extras は不要になり、依存も含めて削除されました。
リポジトリ構成: 現在は単一リポジトリ (Cargo workspace + maturin) ですが、近日中に Rust クレートを
mokuichi147/user-permissionに分離し、本リポジトリは PyO3 バインディングのみ (user-permission-pyにリネーム予定) に縮小する計画です。Python パッケージ名 (user-permission) と Rust クレート名 (user-permission) は据え置きです。
インストール
Python
pip install user-permission # PyPI からビルド済 wheel
# またはソースから:
maturin develop # 開発用に現在の venv に組み込む
依存パッケージはありません (Rust 拡張に同梱)。Python 3.9 以降の abi3 wheel を公開しています。
Rust
cargo add user-permission-core # コア (DB / 認証 / JWT) のみ
cargo add user-permission # axum ルーターを別アプリに組み込む
cargo install user-permission # 単体サーバーとしてインストール
使い方 (Python)
初期化
import asyncio
from user_permission import Database
async def main():
# 初回実行時にシークレットキーを自動生成(以降はファイルから読み込み)
async with Database("app.db", secret="secret.key") as db:
user = await db.users.create("alice", "password123")
group = await db.groups.create("admins")
asyncio.run(main())
ユーザー管理
user = await db.users.create("alice", "password123", display_name="Alice")
user = await db.users.get_by_id(1)
user = await db.users.get_by_username("alice")
users = await db.users.list_all()
await db.users.update(user.id, password="new_password")
await db.users.update(user.id, display_name="Alice Smith")
await db.users.update(user.id, is_active=False)
await db.users.delete(user.id)
認証・トークン
from datetime import timedelta
token = await db.users.authenticate("alice", "password123")
token = await db.users.authenticate(
"alice", "password123", expires_delta=timedelta(hours=24)
)
payload = db.token_manager.verify_token(token)
print(payload["sub"]) # ユーザーID(文字列)
print(payload["username"]) # ユーザー名
print(payload["is_admin"]) # bool
グループ管理
group = await db.groups.create("admins", description="Administrator group")
group = await db.groups.get_by_id(1)
group = await db.groups.get_by_name("admins")
groups = await db.groups.list_all()
await db.groups.update(group.id, description="Updated description")
await db.groups.delete(group.id)
グループメンバー管理
await db.groups.add_user(group.id, user.id)
await db.groups.remove_user(group.id, user.id)
members = await db.groups.get_members(group.id)
groups = await db.groups.get_user_groups(user.id)
サーバー起動
import asyncio
from user_permission import serve
asyncio.run(serve(host="0.0.0.0", port=8001, prefix="/api", webui=True))
CLI からも起動できます。
# Python から (pip install user-permission した場合)
user-permission serve --host 0.0.0.0 --port 8001 --prefix /api --webui
# Rust バイナリ (パフォーマンス重視)
cargo install user-permission
user-permission serve --host 0.0.0.0 --port 8001 --prefix /api --webui
| オプション | デフォルト | 説明 |
|---|---|---|
--host |
127.0.0.1 |
バインドアドレス |
--port |
8000 |
バインドポート |
--database |
user_permission.db |
SQLiteデータベースのパス |
--secret |
secret.key |
シークレットキーファイルのパス |
--prefix |
(なし) | APIルートプレフィックス(例: /api) |
--webui |
無効 | Web管理画面(HTMX+Tailwind)を有効化 |
--webui-prefix |
/ui |
管理画面のURLプレフィックス |
Web 管理画面の移植状況: v0.4 系列ではプレースホルダ画面のみ提供しています。HTMX/Tailwind ベースの完全な管理画面は v0.4.x の追加リリースで再実装予定です。当面はREST API か legacy v0.3 を利用してください。
リレー(中継)
Database に URL を渡すと、ローカル SQLite と中央サーバーを同じインターフェースで切り替えられます。
from user_permission import Database
# ファイルパス → ローカル SQLite
db = Database("app.db", secret="secret.key")
# URL → リモートサーバーへ HTTP 中継
db = Database("http://localhost:8001")
async with Database("http://localhost:8001") as db:
token = await db.login("alice", "password123")
users = await db.users.list_all()
group = await db.groups.create("admins", "Admin group")
await db.groups.add_user(group.id, user.id)
db.login(...) で取得したトークンは Database が内部に保持し、以降のリクエストの Authorization: Bearer に自動付与されます。
使い方 (Rust)
コアだけ使う場合 (user-permission-core):
use std::time::Duration;
use user_permission_core::Database;
#[tokio::main]
async fn main() -> user_permission_core::Result<()> {
let db = Database::open_local("app.db", Some("secret.key")).await?;
let alice = db.users().create("alice", "password123", "Alice").await?;
let token = db
.users()
.authenticate("alice", "password123", Duration::from_secs(3600))
.await?
.expect("credentials");
println!("token = {token}");
let editors = db.groups().create("editors", "Editors", false).await?;
db.groups().add_user(editors.id, alice.id).await?;
Ok(())
}
axum ルーターを別アプリに組み込む場合 (user-permission):
use user_permission::{build_app, WebConfig};
use user_permission_core::Database;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let db = Database::open_local("app.db", Some("secret.key")).await?;
let app = build_app(db, WebConfig { api_prefix: "/api".into(), ..Default::default() });
let listener = tokio::net::TcpListener::bind("0.0.0.0:8001").await?;
axum::serve(listener, app).await?;
Ok(())
}
REST API
| メソッド | パス | 説明 | 認証 |
|---|---|---|---|
| POST | /token |
ログイン(トークン取得) | 不要 |
| GET | /me |
現在のユーザー情報(is_admin を含む) |
必要 |
| POST | /users |
ユーザー作成 | 不要 |
| GET | /users |
ユーザー一覧 | 必要 |
| GET | /users/{id} |
ユーザー取得 | 必要 |
| PATCH | /users/{id} |
ユーザー更新 | 本人 or 管理者 |
| DELETE | /users/{id} |
ユーザー削除 | 本人 or 管理者 |
| POST | /groups |
グループ作成 | 管理者 |
| GET | /groups |
グループ一覧 | 必要 |
| GET | /groups/{id} |
グループ取得 | 必要 |
| PATCH | /groups/{id} |
グループ更新 | 管理者 |
| DELETE | /groups/{id} |
グループ削除 | 管理者 |
| POST | /groups/{id}/members |
メンバー追加 | 管理者 |
| DELETE | /groups/{id}/members/{user_id} |
メンバー削除 | 管理者 |
| GET | /groups/{id}/members |
メンバー一覧 | 必要 |
| GET | /users/{id}/groups |
所属グループ一覧 | 必要 |
管理者ロール
UserPermission サーバー自身の管理権限は groups.is_admin = 1 のグループで表現します。
このフラグが立った 管理者グループ に所属しているユーザーが「UserPermission 管理者」です。
- 管理者は他ユーザーの編集・削除、グループの作成・更新・削除、メンバー管理が可能
- 他ユーザーの管理者昇格/降格は、管理者グループへの加入/脱退で行う
- 管理者グループは複数作れる(運用で分けたい場合)
- 消費サービス側の「アプリ管理者」などの概念はこの権限とは別で、通常のグループ(
is_admin = 0)で自由に表現してください
初回セットアップ
最初に作成されたユーザーは 自動的に管理者グループに加入 します。admin という名前のグループが無ければ、is_admin = 1 で新規作成されます。
既存DBのマイグレーション
v0.4 起動時には groups.is_admin 列の存在を確認し、無ければ ALTER TABLE で追加します。既存データは壊しません。
スキーマ自体は v0.2 以降と互換で、v0.3 で作成された SQLite ファイルはそのまま使えます。
データベーススキーマ
| テーブル | 説明 |
|---|---|
users |
ユーザー情報(username は UNIQUE) |
groups |
グループ情報(name は UNIQUE) |
user_groups |
ユーザーとグループの多対多リレーション(複合PRIMARY KEY) |
ユーザーまたはグループを削除すると、関連する user_groups レコードも自動的に削除されます(CASCADE)。
開発
# Rust 単体テスト
cargo test --workspace
# Python wheel をビルドして現在の venv に組み込む
maturin develop
# Python 統合テスト
pip install pytest pytest-asyncio
pytest tests/python
# リリース wheel をビルド
maturin build --release
ライセンス
MIT OR Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file user_permission-0.4.0.tar.gz.
File metadata
- Download URL: user_permission-0.4.0.tar.gz
- Upload date:
- Size: 71.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ffb01b7a17fa423cc28daa0c69f0581dfc5ad37e4812a8a327c15144331e601
|
|
| MD5 |
42a1fa686a28677c279e007422f1c571
|
|
| BLAKE2b-256 |
9b628ba4fc03b3e4de2740ba623c691252747c160cd886f183383d5b84d56fce
|
Provenance
The following attestation bundles were made for user_permission-0.4.0.tar.gz:
Publisher:
release.yml on Mokuichi147/UserPermission
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.4.0.tar.gz -
Subject digest:
3ffb01b7a17fa423cc28daa0c69f0581dfc5ad37e4812a8a327c15144331e601 - Sigstore transparency entry: 1562085210
- Sigstore integration time:
-
Permalink:
Mokuichi147/UserPermission@5565e22c5faeda9f21792a8df188cf492cef4557 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5565e22c5faeda9f21792a8df188cf492cef4557 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.4.0-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: user_permission-0.4.0-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 4.0 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
592d8044b2c67a65019deb1f81b4b7f694a1900c5fea73cd1bf75ebfa7515f28
|
|
| MD5 |
f41dd4f6bed2f20e92d6cb2762e20f9e
|
|
| BLAKE2b-256 |
2b93155371e71c94d130ef1a5437eda855cbf9306d6189ac4da77f4cba0b4bbc
|
Provenance
The following attestation bundles were made for user_permission-0.4.0-cp39-abi3-win_amd64.whl:
Publisher:
release.yml on Mokuichi147/UserPermission
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.4.0-cp39-abi3-win_amd64.whl -
Subject digest:
592d8044b2c67a65019deb1f81b4b7f694a1900c5fea73cd1bf75ebfa7515f28 - Sigstore transparency entry: 1562085638
- Sigstore integration time:
-
Permalink:
Mokuichi147/UserPermission@5565e22c5faeda9f21792a8df188cf492cef4557 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5565e22c5faeda9f21792a8df188cf492cef4557 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.4.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: user_permission-0.4.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 3.9 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ced683789d15f3e9a34d5a56efec294ce24a82858684a30ea3a31f729b483aa1
|
|
| MD5 |
12bce6d3383ab28286aac75f8e11df07
|
|
| BLAKE2b-256 |
0047d83dbacc6e5c46eba4d57e12d3a50ab247a5d64b1c6fce6ebbb7aa581775
|
Provenance
The following attestation bundles were made for user_permission-0.4.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on Mokuichi147/UserPermission
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.4.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
ced683789d15f3e9a34d5a56efec294ce24a82858684a30ea3a31f729b483aa1 - Sigstore transparency entry: 1562085934
- Sigstore integration time:
-
Permalink:
Mokuichi147/UserPermission@5565e22c5faeda9f21792a8df188cf492cef4557 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5565e22c5faeda9f21792a8df188cf492cef4557 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.4.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: user_permission-0.4.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 3.6 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aece2daec364d37426dfd2a07db46bd8aee93409ac1b8421650b2e7b2103517b
|
|
| MD5 |
df1f4d4fc64f317cb5ac6be14747adae
|
|
| BLAKE2b-256 |
17fd5c1fc28868ccdb5faf9c69abfb519ffca1acaf3ab8c9db8ea7027805c65a
|
Provenance
The following attestation bundles were made for user_permission-0.4.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on Mokuichi147/UserPermission
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.4.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
aece2daec364d37426dfd2a07db46bd8aee93409ac1b8421650b2e7b2103517b - Sigstore transparency entry: 1562085347
- Sigstore integration time:
-
Permalink:
Mokuichi147/UserPermission@5565e22c5faeda9f21792a8df188cf492cef4557 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5565e22c5faeda9f21792a8df188cf492cef4557 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.4.0-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: user_permission-0.4.0-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.5 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1bfc99ad492ea733736ca599c5c259977ec26c65d665365fa02bd48465c4657
|
|
| MD5 |
3df9963944603324f3cf51d98faaede7
|
|
| BLAKE2b-256 |
e6fa61331620448c7a4f3e601acacdfe33ef8934a1b3bcd6a8468fb534591e74
|
Provenance
The following attestation bundles were made for user_permission-0.4.0-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on Mokuichi147/UserPermission
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.4.0-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
f1bfc99ad492ea733736ca599c5c259977ec26c65d665365fa02bd48465c4657 - Sigstore transparency entry: 1562085475
- Sigstore integration time:
-
Permalink:
Mokuichi147/UserPermission@5565e22c5faeda9f21792a8df188cf492cef4557 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5565e22c5faeda9f21792a8df188cf492cef4557 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.4.0-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: user_permission-0.4.0-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd1d7106193fb9968327011e23f489cb3828640048412567cec1542ffedab302
|
|
| MD5 |
6deea030eb0a96977dd64ab8ceef9e4e
|
|
| BLAKE2b-256 |
46c6a59692fa4dbbe1181132a7a3d9cf9de45b40f149cbfa1fe8fef7cfd88d51
|
Provenance
The following attestation bundles were made for user_permission-0.4.0-cp39-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on Mokuichi147/UserPermission
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.4.0-cp39-abi3-macosx_10_12_x86_64.whl -
Subject digest:
bd1d7106193fb9968327011e23f489cb3828640048412567cec1542ffedab302 - Sigstore transparency entry: 1562085770
- Sigstore integration time:
-
Permalink:
Mokuichi147/UserPermission@5565e22c5faeda9f21792a8df188cf492cef4557 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5565e22c5faeda9f21792a8df188cf492cef4557 -
Trigger Event:
push
-
Statement type: