mirror of https://github.com/veypi/OneAuth.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
5.5 KiB
Markdown
165 lines
5.5 KiB
Markdown
|
7 days ago
|
# CLAUDE.md
|
||
|
|
|
||
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
|
|
||
|
|
## Project Overview
|
||
|
|
|
||
|
|
VBase is a Go-based identity authentication and permission management framework built on the [Vigo](https://github.com/veypi/vigo) web framework (onion-model middleware architecture). It provides user management, organization (multi-tenant), RBAC permissions, and OAuth2 authentication services.
|
||
|
|
|
||
|
|
- **Language**: Go 1.24+
|
||
|
|
- **Framework**: Vigo (onion-model middleware)
|
||
|
|
- **ORM**: GORM (MySQL, PostgreSQL, SQLite supported)
|
||
|
|
- **Authentication**: JWT + OAuth2
|
||
|
|
- **Frontend**: vhtml (embedded HTML-based UI at `/vb/`)
|
||
|
|
|
||
|
|
## Common Commands
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Run development server (default port 4001)
|
||
|
|
make run
|
||
|
|
|
||
|
|
# Database operations
|
||
|
|
go run ./cli/main.go db migrate
|
||
|
|
go run ./cli/main.go db drop
|
||
|
|
|
||
|
|
# Run integration tests
|
||
|
|
go test -v ./tests/...
|
||
|
|
```
|
||
|
|
|
||
|
|
Tests in `tests/` use an in-memory SQLite database with mock Redis. The `ensureUsers(t)` helper sets up test users (admin, user1, user2) with tokens stored in globals (`AdminToken`, `User1Token`, etc.).
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
### Onion Model Request Flow
|
||
|
|
|
||
|
|
```
|
||
|
|
Request -> [Global Before Middlewares] -> [Router] -> [Handler] -> [Service] -> [Model] -> Database
|
||
|
|
|
|
||
|
|
Response <- [Global After Middleware] <--------+
|
||
|
|
```
|
||
|
|
|
||
|
|
Key middleware stages:
|
||
|
|
|
||
|
|
- **Before**: Authentication, preprocessing, context injection (parent hooks run before child hooks)
|
||
|
|
- **Handler**: Business logic, returns data (does not write response directly)
|
||
|
|
- **After**: Response formatting (parent hooks run after child hooks)
|
||
|
|
|
||
|
|
### Directory Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
├── api/ # REST API handlers and routing
|
||
|
|
│ ├── auth/ # Login, register, refresh token, SMS
|
||
|
|
│ ├── oauth/ # OAuth2 provider endpoints
|
||
|
|
│ ├── org/ # Organization/tenant management
|
||
|
|
│ ├── role/ # Role management
|
||
|
|
│ ├── user/ # User management
|
||
|
|
│ └── init.go # Router aggregation
|
||
|
|
├── auth/ # Core RBAC permission system
|
||
|
|
│ ├── auth.go # Permission checking implementation
|
||
|
|
│ └── middleware.go # Auth middleware
|
||
|
|
├── cfg/ # Configuration (DB, Redis, JWT settings)
|
||
|
|
├── models/ # GORM data models
|
||
|
|
│ ├── auth.go # Role, Policy, UserRole models
|
||
|
|
│ ├── user.go # User, Identity, Session models
|
||
|
|
│ ├── org.go # Org, OrgMember models
|
||
|
|
│ └── init.go # Model registration and migrations
|
||
|
|
├── libs/ # Utilities (cache, crypto, jwt, sms, email)
|
||
|
|
├── ui/ # Frontend admin interface (vhtml framework)
|
||
|
|
├── cli/ # Application entry point
|
||
|
|
└── tests/ # Go integration tests
|
||
|
|
```
|
||
|
|
|
||
|
|
### Permission System (RBAC)
|
||
|
|
|
||
|
|
Permission format: `resource:action` or `app:resource:action`
|
||
|
|
|
||
|
|
Examples: `user:read`, `org:create`, `oauth-client:delete`
|
||
|
|
|
||
|
|
**Important**: Resource identifiers must NOT contain colons (use kebab-case or snake_case).
|
||
|
|
|
||
|
|
Permission middleware usage:
|
||
|
|
|
||
|
|
```go
|
||
|
|
// Basic permission
|
||
|
|
Router.Post("/articles", AppAuth.Perm("article:create"), createArticle)
|
||
|
|
|
||
|
|
// Owner check - allows if user is resource owner
|
||
|
|
Router.Patch("/articles/{id}", AppAuth.PermWithOwner("article:update", "id"), updateArticle)
|
||
|
|
|
||
|
|
// Wildcard support
|
||
|
|
AppAuth.AddRole("admin", "Admin", "*:*") // All permissions
|
||
|
|
```
|
||
|
|
|
||
|
|
### Multi-Tenancy (Org)
|
||
|
|
|
||
|
|
Organizations provide data isolation. Three usage patterns:
|
||
|
|
|
||
|
|
1. **B2C (Single Tenant)**: Ignore Org, bind roles to global (`org_id=""`)
|
||
|
|
2. **B2B SaaS (Multi-Tenant)**: Require `X-Org-ID` header on all business APIs
|
||
|
|
3. **Platform (Hybrid)**: Merchant side uses Org, consumer side is global
|
||
|
|
|
||
|
|
The `AuthMiddleware` extracts `X-Org-ID` header and loads user's roles for that org context.
|
||
|
|
|
||
|
|
### API Response Format
|
||
|
|
|
||
|
|
All responses are JSON formatted by `common.JsonResponse` middleware:
|
||
|
|
|
||
|
|
**Success:**
|
||
|
|
|
||
|
|
```json
|
||
|
|
{"code": 200, "data": { ... }}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Error:**
|
||
|
|
|
||
|
|
```json
|
||
|
|
{ "code": 40001, "message": "Error description" }
|
||
|
|
```
|
||
|
|
|
||
|
|
Error codes combine HTTP status (3 digits) + scenario (2 digits), e.g., `40001` = Bad Request + invalid argument.
|
||
|
|
|
||
|
|
### Configuration
|
||
|
|
|
||
|
|
Configuration is loaded from:
|
||
|
|
|
||
|
|
1. Config file (`-f ./cfg/dev.yml`)
|
||
|
|
2. Environment variables (uppercase with underscores, e.g., `DB_DSN`, `JWT_SECRET`)
|
||
|
|
|
||
|
|
Key config in `cfg/cfg.go`:
|
||
|
|
|
||
|
|
- `DB`: Database connection (type: mysql/postgres/sqlite)
|
||
|
|
- `Redis`: Use `memory` for development
|
||
|
|
- `Key`: System encryption key (32+ chars recommended)
|
||
|
|
- `JWT`: Token expiry settings
|
||
|
|
- `InitAdmin`: Auto-create admin on first run (empty password = first registered user becomes admin)
|
||
|
|
|
||
|
|
### Handler Pattern (Vigo Framework)
|
||
|
|
|
||
|
|
Handlers use generics with automatic parameter binding:
|
||
|
|
|
||
|
|
```go
|
||
|
|
type CreateReq struct {
|
||
|
|
Name string `json:"name" src:"json"` // Required
|
||
|
|
Email *string `json:"email" src:"json"` // Optional (pointer)
|
||
|
|
Page int `src:"query" default:"1"` // Query param with default
|
||
|
|
}
|
||
|
|
|
||
|
|
func CreateUser(x *vigo.X, req *CreateReq) (*User, error) {
|
||
|
|
// Business logic
|
||
|
|
return user, nil // Framework handles JSON response
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Parameter sources: `path`, `query`, `header`, `json`, `form`. Non-pointer fields are required by default.
|
||
|
|
|
||
|
|
### Frontend (vhtml)
|
||
|
|
|
||
|
|
The admin UI is in `ui/` using the vhtml framework:
|
||
|
|
|
||
|
|
- Pages in `ui/page/` (e.g., `user_list.html` → route `/user_list`)
|
||
|
|
- Components as HTML files, referenced with hyphens (e.g., `<form-user_create>` for `/ui/form/user_create.html`)
|
||
|
|
- Routes defined in `ui/routes.js`
|
||
|
|
- Access UI at `/vb/` path when server is running
|
||
|
|
|
||
|
|
Full API documentation is available at `/_api.json` when the server is running.
|