MySQL + Go + GORM + Docker で作る、最小のRBACサンプルです。
この記事 docs/なぜ壊れた権限設計が生まれるのか(RBAC設計の実務).md のテーブル設計をそのまま採用しています。
usersrolespermissionsuser_rolesrole_permissions
DDL は db/init/001_schema.sql を参照してください。
docker compose up -d mysqlMySQL接続情報(デフォルト):
- host:
127.0.0.1 - port:
3306 - database:
sample_rbac - user:
app - password:
app
このサンプルでは、業務処理の入口で権限を確認します。
db, _ := rbac.OpenMySQL("app:app@tcp(127.0.0.1:3306)/sample_rbac?parseTime=true")
repo := rbac.NewRepository(db)
authorizer := usecase.NewAuthorizer(repo)
exporter := usecase.NewReportExporter(authorizer)
fileName, err := exporter.ExportMonthlyReport(ctx, userID)
if errors.Is(err, usecase.ErrForbidden) {
// 403 相当の扱い
}処理の流れ:
ReportExporter.ExportMonthlyReportが呼ばれるAuthorizer.Requireがreport.exportをチェックする- 内部で
Repository.HasPermissionが DB から権限を判定する - 権限があれば業務処理を続行、なければ
ErrForbidden
先に失敗テストを作成し、後から実装しています。
対象テスト:
Repositoryの統合テストHasPermission: ユーザーが特定権限を持つかHasPermission_FalseWhenNotGranted: 権限未付与時の判定ListPermissions_DistinctSorted: 権限一覧の重複排除とソート
Usecaseの統合テストExportMonthlyReport_Success: 権限ありで成功ExportMonthlyReport_Forbidden: 権限なしで拒否
実行:
go test ./...- internal/rbac/mysql.go: GORMでMySQL接続を開く
- internal/rbac/repository.go: RBAC用クエリ実装
- internal/rbac/repository_test.go: Repositoryの実DB統合テスト
- internal/usecase/authorizer.go: 権限判定ユースケース
- internal/usecase/report_exporter.go: 業務ユースケース例
- internal/usecase/report_exporter_test.go: Usecaseの実DB統合テスト
docker compose downデータも削除する場合:
docker compose down -v