Skip to content

Commit 0ef125a

Browse files
committed
New CLAUDE.md from MiniMAX M2
1 parent 3f64c40 commit 0ef125a

File tree

1 file changed

+323
-0
lines changed

1 file changed

+323
-0
lines changed

CLAUDE.md

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
**Oauth2id** is a production-ready Rails 7.2.2 Single Sign-On (SSO) Portal implementing OAuth2, OpenID Connect, and SAML 2.0 authentication protocols. It's a multi-protocol identity provider suitable for enterprise authentication scenarios.
8+
9+
### Key Technologies
10+
- **Backend**: Ruby 3.0+ on Rails 7.2.2 with Puma
11+
- **Database**: SQLite (default) - configurable to PostgreSQL/MySQL
12+
- **Frontend**: Stimulus controllers + Webpacker 5.4.4 + Bootstrap 4 (Vali Admin theme)
13+
- **Authentication**: Devise + devise-jwt, Doorkeeper, doorkeeper-openid_connect, SAML IdP
14+
- **Package Manager**: pnpm for Node.js dependencies
15+
16+
## Architecture Overview
17+
18+
### MVC Rails Application Structure
19+
```
20+
app/
21+
controllers/ # Rails controllers
22+
models/ # ActiveRecord models (User, Doorkeeper::Application, Department, Position, Profile, Jwt)
23+
views/ # ERB templates
24+
javascript/ # Stimulus controllers + Webpack packs
25+
policies/ # Pundit authorization policies
26+
datatables/ # AJAX data tables for admin interfaces
27+
28+
config/
29+
routes.rb # OAuth2/OIDC/SAML routes + user admin routes
30+
initializers/ # Devise, Doorkeeper, SAML, OpenID Connect configs
31+
environments/ # Environment-specific configs (development/test/production)
32+
credentials.yml.enc # Encrypted credentials (managed via bin/rails credentials:edit)
33+
34+
db/
35+
migrate/ # Database migrations
36+
schema.rb # Current database schema
37+
seeds.rb # Seed data
38+
39+
test/
40+
controllers/ # Controller tests
41+
models/ # Model tests
42+
system/ # Capybara system tests
43+
fixtures/ # Test fixtures
44+
```
45+
46+
### Authentication Architecture
47+
48+
**Multi-Protocol SSO Implementation:**
49+
50+
1. **OAuth2 Provider** (Doorkeeper)
51+
- Routes: `/oauth/authorize`, `/oauth/token`, `/oauth/authorize`, `/oauth/discovery/keys`
52+
- Controller glue: `app/controllers/doorkeeper_controller.rb`
53+
- App model: `app/models/doorkeeper_application.rb`
54+
55+
2. **OpenID Connect** (doorkeeper-openid_connect)
56+
- Extends OAuth2 with OIDC support
57+
- Requires `openid` scope minimum
58+
- Discovery endpoint: `/oauth/discovery/keys`
59+
- Initializer: `config/initializers/doorkeeper_openid_connect.rb`
60+
61+
3. **SAML 2.0 Identity Provider** (saml_idp)
62+
- Routes: `/saml/auth`, `/saml/metadata`, `/saml/logout`
63+
- Controller: `app/controllers/saml_idp_controller.rb`
64+
- Initializer: `config/initializers/saml_idp.rb`
65+
66+
4. **User Authentication** (Devise)
67+
- Session-based authentication
68+
- JWT support via devise-jwt
69+
- Allowlisted JWT management: `app/models/allowlisted_jwt.rb`
70+
71+
## Common Development Commands
72+
73+
### Initial Setup
74+
```bash
75+
# First-time setup (installs gems, packages, prepares DB, runs seeds)
76+
bin/setup
77+
78+
# Install frontend dependencies
79+
pnpm install --frozen-lockfile
80+
```
81+
82+
### Running the Application
83+
```bash
84+
# Standard Rails server
85+
bin/rails s
86+
87+
# Hot asset reloading (two terminals)
88+
bin/rails s # Terminal 1
89+
bin/webpack-dev-server # Terminal 2
90+
91+
# Or use Foreman (both processes)
92+
foreman start -f Procfile.dev
93+
94+
# Access the application
95+
# Development: http://localhost:3000
96+
# HTTPS local (with puma-dev): https://oauth2id.test
97+
```
98+
99+
### Database Operations
100+
```bash
101+
# Create/migrate DB
102+
bin/rails db:prepare
103+
104+
# Run migrations only
105+
bin/rails db:migrate
106+
107+
# Load seed data
108+
bin/rails db:seed
109+
110+
# Load fixtures
111+
bin/rails db:fixtures:load
112+
```
113+
114+
### Testing
115+
```bash
116+
# Run all tests
117+
bin/rails test:all
118+
119+
# Run specific test file
120+
bin/rails test test/models/user_test.rb
121+
122+
# Run system tests
123+
bin/rails test:system
124+
125+
# Run tests with coverage
126+
COVERAGE=true bin/rails test
127+
```
128+
129+
### Linting & Formatting
130+
```bash
131+
# Ruby linting
132+
bundle exec rubocop
133+
134+
# Fix Ruby linting issues
135+
bundle exec rubocop -A
136+
137+
# JavaScript linting
138+
npx eslint app/javascript/
139+
```
140+
141+
### Asset Management
142+
```bash
143+
# Compile assets for production
144+
bin/rails assets:precompile
145+
146+
# Build Webpack bundles
147+
bin/webpack
148+
149+
# Watch mode for asset compilation
150+
bin/webpack --watch
151+
```
152+
153+
### Docker Operations
154+
```bash
155+
# Build image
156+
docker build --tag ericguo/oauth2id:main .
157+
158+
# Run container
159+
docker run -p 3000:3000 -d --restart always --name oauth2id \
160+
--env RAILS_MASTER_KEY=YourMasterKey \
161+
-v ./storage:/rails/storage \
162+
ericguo/oauth2id:main
163+
164+
# Debug container
165+
docker run --env RAILS_MASTER_KEY=YourMasterKey \
166+
-v ./storage:/rails/storage \
167+
-it ericguo/oauth2id:main bash
168+
169+
# Push to registry
170+
docker push ericguo/oauth2id:main
171+
```
172+
173+
### Deployment (Capistrano)
174+
```bash
175+
# Deploy to production
176+
cap production deploy
177+
178+
# Run migrations in production
179+
cap production deploy:migrate
180+
```
181+
182+
### Key Generation
183+
184+
#### OIDC Keys (Required for OpenID Connect)
185+
```bash
186+
openssl genpkey -algorithm RSA -out oauth2id_oidc_private_key.pem -pkeyopt rsa_keygen_bits:2048
187+
openssl rsa -pubout -in oauth2id_oidc_private_key.pem -out oauth2id_oidc_public_key.pem
188+
# Public key available at: /oauth/discovery/keys
189+
```
190+
191+
#### SAML 2.0 Keys
192+
```bash
193+
openssl req -x509 -sha256 -nodes -days 3650 -newkey rsa:2048 \
194+
-keyout oauth2id_saml_key.key -out oauth2id_saml_cert.crt
195+
# View fingerprint:
196+
openssl x509 -in oauth2id_saml_cert.crt -noout -sha256 -fingerprint
197+
```
198+
199+
#### JWT RS256 Keys
200+
```bash
201+
openssl genpkey -algorithm RSA -out oauth2id_jwt_private_key.pem -pkeyopt rsa_keygen_bits:2048
202+
openssl rsa -pubout -in oauth2id_jwt_private_key.pem -out oauth2id_jwt_public_key.pem
203+
```
204+
205+
## Development Patterns & Conventions
206+
207+
### Rails Conventions
208+
- **Strong Parameters**: Permit attributes in controllers following existing patterns
209+
- **Authorization**: Use Pundit policies in `app/policies/*` with `authorize(record)` and `policy_scope(Model)`
210+
- **Authentication**: Devise handles user auth; JWT via devise-jwt and Warden strategies
211+
- **I18n**: Use `t('key')` instead of literals; add keys to `config/locales/*`
212+
- **Controllers**: Keep lean; offload logic to helpers (`app/helpers/application_helper.rb`) or presenters
213+
214+
### Frontend (Stimulus + Webpacker)
215+
- **Entry pack**: `app/javascript/packs/application.js`
216+
- **Controllers**: Auto-loaded from `app/javascript/controllers/*`
217+
- **Naming**: Controllers named `*_controller.js`, export default class with targets/actions
218+
- **View integration**: Use `data-controller`, `data-action`, `data-target` in ERB
219+
- **Pack loading**: Include via `javascript_pack_tag 'application'` in layouts
220+
- **Auto-loading**: Controllers auto-registered via `definitionsFromContext(require.context('controllers', true, /.js$/))`
221+
- **Polyfills**: `regenerator-runtime` and `@stimulus/polyfills` included globally
222+
223+
### DataTables
224+
- AJAX-powered data tables for admin interfaces
225+
- Keep query/filtering logic in datatable classes under `app/datatables/*`
226+
- Initialize via Ajax, respond with JSON from Datatable classes
227+
- Column mapping kept in the table class
228+
229+
### Security
230+
- **CSRF Protection**: Always enabled for web endpoints
231+
- **API OPTIONS endpoints** (e.g., `/api/me`): Follow existing implementation in `Api::ApplicationController`
232+
- **Credentials**: Use `Rails.application.credentials` or environment variables (never hardcode secrets)
233+
234+
### Background Jobs & Mailers
235+
- Extend `ApplicationJob` and `ApplicationMailer` base classes
236+
- Keep idempotent and side-effect aware
237+
238+
### Testing
239+
- **Framework**: Minitest + Capybara
240+
- **System tests**: Capybara with selenium-webdriver
241+
- **Fixtures**: Prefer fixtures; avoid depending on `db/seeds.rb` for tests
242+
- **CI integration**: `minitest-ci`, `simplecov` in `:ci` gem group
243+
- Layout: `test/*` with fixtures in `test/fixtures/*`
244+
245+
## Key Configuration Files
246+
247+
### Core Application
248+
- `config/application.rb` - Main Rails config (i18n: zh-CN, ActiveStorage/ActionCable/ActionMailbox/ActionText disabled)
249+
- `config/routes.rb` - SSO routes (Doorkeeper, SAML) + admin routes
250+
- `config/database.yml` - Database configuration (SQLite default)
251+
252+
### Authentication & Security
253+
- `config/initializers/devise.rb` - Devise authentication
254+
- `config/initializers/doorkeeper.rb` - OAuth2 provider config
255+
- `config/initializers/doorkeeper_openid_connect.rb` - OIDC config
256+
- `config/initializers/saml_idp.rb` - SAML IdP configuration
257+
- `config/credentials.yml.enc` - Encrypted credentials (managed via `bin/rails credentials:edit`)
258+
- `config/master.key` - Encryption key (NOT in repo!)
259+
260+
### Frontend
261+
- `config/webpacker.yml` - Webpacker configuration
262+
- `package.json` - Node.js dependencies
263+
- `.eslintrc.js` - ESLint configuration
264+
265+
### Deployment
266+
- `Dockerfile` - Multi-stage Docker build
267+
- `Capfile` + `config/deploy.rb` - Capistrano deployment config
268+
- `Procfile.dev` - Foreman process definitions
269+
- `.gitlab-ci.yml` - GitLab CI pipeline
270+
- `.circleci/config.yml` - CircleCI configuration
271+
272+
## Critical Routes & Endpoints
273+
274+
### OAuth2 / OpenID Connect
275+
- Authorization: `GET /oauth/authorize`
276+
- Token: `POST /oauth/token`
277+
- Discovery Keys: `GET /oauth/discovery/keys`
278+
- User info: `GET /oauth/userinfo` (OIDC only)
279+
280+
### SAML 2.0
281+
- Auth: `GET /saml/auth`
282+
- Metadata: `GET /saml/metadata`
283+
- Logout: `GET /saml/logout`
284+
285+
### Admin & Management
286+
- Users: `/users` (Devise-managed)
287+
- Applications: `/oauth/applications` (Doorkeeper)
288+
- JWT Management: `/jwt` endpoints
289+
- Departments/Positions: `/departments`, `/positions`
290+
291+
## Environment Setup Notes
292+
293+
### puma-dev (HTTPS Local Development)
294+
```bash
295+
brew install puma/puma/puma/puma-dev
296+
sudo puma-dev -setup
297+
puma-dev -install
298+
cd ~/.puma-dev
299+
ln -s /path/to/oauth2id oauth2id
300+
# Visit: https://oauth2id.test
301+
```
302+
303+
**Known Issues:**
304+
- For newer MacOS: Add Puma-dev CA to System keychain and restart browser
305+
- For Faraday: Add CA to OpenSSL cert list using openssl-osx-ca
306+
- For httpclient: Copy cert.pem to httpclient gem directory
307+
308+
### Database Migration (MySQL → PostgreSQL)
309+
Use mysql-postgresql-converter:
310+
```bash
311+
mysqldump --set-gtid-purged=OFF --no-tablespaces --compatible=postgresql --default-character-set=utf8 -r db.mysql -u user pass dbname
312+
python ./db_converter.py db.mysql db.psql
313+
psql -d new_db -f db.psql
314+
# Replace ' datetime(6) ' with ' timestamp(6) without time zone '
315+
```
316+
317+
## Important Notes
318+
319+
- **Storage**: SQLite databases stored in `storage/*.sqlite3` (mounted in Docker)
320+
- **UI Theme**: Vali Admin v2.4.1 based on Bootstrap 4, supports IE 11
321+
- **Locales**: Chinese (zh-CN) configured in `config/locales/*`
322+
- **Master Key**: Required for encrypted credentials; never commit `config/master.key`
323+
- **Production Data**: Users may need `u.confirm` to enable sign-in

0 commit comments

Comments
 (0)