The shared library crate providing authentication, session management, and utilities for all IAAA-based CLI tools.
crates/info-common/~/.config/info/<name>/ for each consumer crateiaaa.rs — IAAA Unified Authentication#PKU's Single Sign-On system supporting both password and QR code login
Each consumer provides its own IaaaConfig with app_id and redirect_url:
app_id="PKU Helper", redirect to /chapi/cas_iaaa_loginapp_id="blackboard", redirect to Blackboard SSOapp_id="portal2017", redirect to portal → berserker-authapp_id="elective", redirect to elective SSOReturns a token that the consumer exchanges with its target service
otp.rs — TOTP Code Generation#session.rs — Session & Cookie Persistence#Store::new(APP_NAME) creates storage at ~/.config/info/<name>/session.json — token, expires_at, uid, created_at, extra (serde_json::Value)cookies.json — reqwest CookieStore serialized as JSONcredential.rs — Unified Credential Resolution#Resolves user credentials in priority order: OS keyring → env vars → interactive input
Keyring: Uses keyring crate with platform-specific backends:
Environment variables: PKU_USERNAME, PKU_PASSWORD, PKU_SMS_CODE
SMS code resolution: resolve_sms_code() — env var PKU_SMS_CODE → interactive
SMS auto-confirm: confirm_send_sms() — auto-confirms when PKU_SMS_CODE is set
Keyring management: keyring_store(), keyring_clear(), keyring_has_credential()
Session check: check_session(app_name) — returns Valid / Expired / NotFound
Passwords never written to disk — keyring is OS-encrypted, env vars are in-memory only
qr.rs — Terminal QR Code Display#viuer crateAll IAAA-based CLI tools use credential::resolve_credential() for login. The resolution order:
info-pku service) — set by info-auth storePKU_USERNAME + PKU_PASSWORD)AI Agents should:
info-auth check to verify session status before operations<tool> login -p to trigger auto-login from keyringPKU_SMS_CODE env var if SMS verification is neededTo add a new IAAA-based CLI tool:
crates/info-common in Cargo.tomlIaaaConfig with the service's app_id and redirect_urlcredential::resolve_credential() instead of manual stdin inputcomplete_*_login() to exchange the IAAA token with the target servicesession.expires_at when saving sessionsStore::new("tool-name") for session persistenceclient.rs pattern: build() for auth requests, build_simple() for IAAA loginanyhow::Result with .context("中文描述")#[allow(dead_code)]