67687883ff
fix: RBAC crash when cache disabled - return roles directly from get_userroles
...
When module_cache.rbac=false in config.json, LRUCache.get() always returns
None and LRUCache.set() is a no-op. This caused get_userroles() to store
roles into a disabled cache, then callers read back None, leading to
TypeError in check_roles_path() when iterating over None.
Fix: get_userroles() now returns the roles list directly. Callers use the
return value instead of relying solely on cache reads. Added safety
fallback to deny access if roles is somehow still None.
2026-05-29 22:43:39 +08:00
fa9f7f5146
fix: wrap Tabular in VBox with cheight for proper scrolling
2026-05-29 22:09:56 +08:00
cf18e592c7
feat: respect module_cache config for RBAC LRU cache
2026-05-29 17:59:04 +08:00
342fc6652a
refactor: rewrite SMS login UI using pure bricks patterns
...
- login.ui: use actiontype:urlwidget for Form submit → code_login.dspy
- Removed custom JavaScript (phone_login.js)
- Send code button: minimal script action to fetch and set form value
- Login flow: bricks returns Message/Error/VBox widgets directly
- Multi-account selection: code_login.dspy returns VBox with Buttons
2026-05-29 11:58:30 +08:00
8528eebf10
revert: restore gen_sms_code.dspy (API used by other systems)
2026-05-29 11:38:35 +08:00
e65fddbe61
revert: restore phone_login.dspy to original (API used by other systems)
2026-05-29 11:37:39 +08:00
cf186a632b
fix: revert uitype to 'hide' (bricks framework uses 'hide' not 'hidden')
2026-05-29 11:36:05 +08:00
567513789e
feat: rewrite SMS login UI with fetch-based flow matching phone_login.dspy API
...
- login.ui: SMS tab now uses fetch for gen_sms_code.dspy and phone_login.dspy
- Added _webbricks_=1 to fetch URLs (prevents HTML wrapping)
- Added 60s countdown timer on send-code button
- Added multi-account selection UI (status=choose response)
- Fixed uitype 'hide' -> 'hidden' for codeid field
- Dispatches user_logined event after successful phone login
- gen_sms_code.dspy: improved error message for SMS service config issues
- phone_login.dspy: added mark_used parameter for multi-account flow
- phone_login.js: sageSelectAccount handler for account selection
2026-05-29 11:31:39 +08:00
cfd3810a0a
fix: remove _webbricks_=1 from SMS code generation API call
...
The _webbricks_=1 parameter was causing the response to be wrapped as a widget instead of plain JSON, which prevented the frontend from correctly parsing the response and setting the codeid field.
Now the API returns plain JSON {status: 'ok', data: {key: '...'}} and the form's hidden codeid field gets properly set after successful SMS generation.
2026-05-28 18:39:25 +08:00
969a72b528
fix: SMS verification code URL - replace undefined bricks.app.baseUrl with entire_url template
...
The send verification code button was sending requests to https://token.opencomputing.cn/undefined/rbac/gen_sms_code.dspy because bricks.app.baseUrl doesn't exist in the bricks framework (it uses baseURI on widgets).
Fix: Use Jinja2 entire_url() template function like all other URLs in the file.
2026-05-28 18:24:39 +08:00
ff03efb50a
fix: Button label更新改用set_otext()支持国际化
...
set_text()直接设置innerHTML跳过i18n翻译,
set_otext()会先调用i18n._()翻译再set_text,
与Button初始化时i18n:true的配置保持一致。
2026-05-28 17:00:57 +08:00
f44104b8a5
fix: Button label更新使用text_w.set_text()替代options.label赋值
...
根因:
1. script上下文中this为undefined,无法通过this.options.label访问
2. btn.options.label只修改属性不更新DOM,需调用text_w.set_text()
3. Button内部label是bricks.Text子组件(text_w),需通过其API更新
2026-05-28 16:52:26 +08:00
53111aa2fd
fix: Form.getValue()返回FormData对象,改用_getValue()获取普通对象
...
根因:bricks Form的getValue()内部调用get_formdata()返回浏览器
原生FormData对象,不支持.cell_no属性访问。
改用_getValue()返回{name:value}普通JS对象。
2026-05-28 16:27:56 +08:00
92627c9c96
fix: 手机验证码tab改用VBox+独立Button,避免toolbar tool触发submit导致tab跳转
...
根因:Form toolbar tool点击会同时触发Form的submit事件,
submit的urlwidget替换Form后TabPanel重置到第一个tab。
改为VBox包裹Form和独立Button,Button通过bricks.getWidgetById
读取Form值,fetch加_webbricks_=1确保返回纯JSON。
2026-05-28 15:03:50 +08:00
7200ee43a0
fix: 手机验证码gen_code按钮用datawidget/datamethod传表单值给script
...
原script中this.getValue()在toolbar tool事件上下文中拿不到表单数据,
改用datawidget/datamethod机制将表单值通过params传入script。
回写codeid用.bind(this)保持Form引用。
2026-05-28 14:10:37 +08:00
de21b9fd38
feat: 手机验证码登录对接 + 注册tab + user_logined事件派发
...
- 新增 code_login.dspy: 接收前端表单(cell_no/codeid/check_code)
映射到sms_engine验证,返回UI widget含自动登录binds
- 修复 login.ui 手机验证码tab: gen_code按钮改用script调用
gen_sms_code.dspy并回写key到隐藏字段,submit指向code_login.dspy
- login.ui 新增注册tab: 用户名/手机号/密码/确认密码表单
- register.dspy: 注册成功后自动remember_user并返回含binds的
Message widget(加载userinfo、销毁登录窗、派发user_logined)
- up_login.dspy: 补充user_logined事件派发bind
- load_path.py: code_login.dspy加入any权限,gen_sms_code.dspy
从logined移至any(验证码发送在登录前)
2026-05-28 13:50:17 +08:00
54b0f3d7b6
fix: dispatch user_logined event after successful login
...
After login message is dismissed, dispatches 'user_logined' on bricks.app
so the sidebar menu reloads without requiring manual page reload.
2026-05-28 13:42:03 +08:00
9d2a94131a
feat: improve logout.dspy with refresh button
...
After logout, show success message with a button to reload the page,
which triggers the sidebar menu to re-render with unauthenticated state.
2026-05-27 17:58:15 +08:00
0a5bfa4c64
feat: add load_path.py RBAC permission registration script
2026-05-27 13:16:09 +08:00
39f8eb7d94
Revert "feat: add cross-process cache invalidation via Redis Pub/Sub"
...
This reverts commit 8cec17c04295665eb4b750e2070c17fa3b06a939.
2026-05-26 18:31:04 +08:00
8fdb31a850
Revert "fix: add app parameter to start_cache_sync for aiohttp on_startup hook"
...
This reverts commit c0bbe63845e1f5ca255a0e2fe821fcf4f88786aa.
2026-05-26 18:31:04 +08:00
c0bbe63845
fix: add app parameter to start_cache_sync for aiohttp on_startup hook
2026-05-26 17:20:52 +08:00
835a2ff3f7
fix: add filler css + overflowY:auto to content container
2026-05-26 13:57:42 +08:00
8cec17c042
feat: add cross-process cache invalidation via Redis Pub/Sub
...
- userperm.py: All invalidate_* and on_* handlers changed to async
- Each invalidation now broadcasts via cache_sync.invalidate()
- invalidate_user_cache() -> 'rbac:ur:{userid}'
- invalidate_all_user_caches() -> 'rbac:ur:all'
- invalidate_rp_cache() -> 'rbac:rp'
- init.py: Added start_cache_sync() async function
- Starts Redis Pub/Sub subscription
- Registers callbacks for rbac:rp and rbac:ur:all channels
- set_role_perms.py: CLI script now sends invalidation after execution
- send_rbac_invalidation() starts cache_sync, publishes, then stops
Compatible with existing EventDispatcher (already supports async handlers)
2026-05-26 13:52:10 +08:00
1b21f46336
feat: add index.ui as module entry with user management, path roles, and unauth file scan cards
2026-05-26 12:11:32 +08:00
f8c8a4ce4d
refactor: move RBAC tools logic to rbac/rbac_tools.py, dspy files call via request._run_ns
2026-05-26 09:32:38 +08:00
0b456486db
feat: add RBAC tools — list_path_roles, find_unauth_files, and permission registration script
2026-05-26 09:18:04 +08:00
c53c16d54c
feat: add RBAC tools — list_path_roles and find_unauth_files
2026-05-26 09:12:33 +08:00
fd9ef322c7
bugfix
2026-05-22 17:21:00 +08:00
04552941e5
bugfix
2026-05-22 16:54:08 +08:00
1b720c4b89
bugfix
2026-05-22 15:58:59 +08:00
ce1521d46a
feat: add json table definitions for all models (converted from xlsx)
2026-05-21 12:46:27 +08:00
0ac6c83ead
bugfix
2026-05-18 16:00:42 +08:00
c0ea3baef1
Merge branch 'main' of git.opencomputing.cn:yumoqing/rbac
2026-05-18 15:57:36 +08:00
d168326f09
bugfix
2026-05-18 15:31:00 +08:00
3f2001378e
bugfix
2026-05-18 15:25:43 +08:00
4f103000b9
feat: implement real-time cache invalidation via DB event binding
...
- Fixed syntax errors in userperm.py __init__ (removed broken 'this' reference
and incomplete method definition)
- Added 7 production-grade event handlers on UserPermissions:
- on_user_create/update/delete: invalidate specific user cache
- on_rolepermission_change: invalidate role-permission cache
- on_permission_change: invalidate role-permission cache
- on_role_change: invalidate ALL user + role-permission caches
- on_userrole_change: invalidate specific user cache by userid
- Added _bind_rbac_events() in init.py with 13 event bindings covering:
users C/U/D, rolepermission C/U/D, permission U, role C/U/D, userrole C/U/D
- All handlers have try/except error isolation to prevent one failure
from breaking other handlers
- Events auto-dispatched by sqlor after C/U/D operations (no service restart needed)
- Cleaned up unused imports (DBPools, exception)
2026-05-18 12:42:17 +08:00
d96444cf60
fix: replace getID() with uuid() in dspy context
2026-05-13 11:50:24 +08:00
cd82b345aa
fix: use dappid+userid for downapikey query/insert, matching actual table schema
2026-05-13 11:44:34 +08:00
f313877f4b
fix: remove non-existent kwdownapikey table, use downapikey directly for per-user apikey lookup
2026-05-13 11:22:04 +08:00
fe7025ac0f
fix: use kwdownapikey for per-user apikey existence check to prevent same org sharing apikey
2026-05-12 20:12:19 +08:00
d57d165a08
fix: add openCustomerAccounts call and fix sync message in usersync
2026-05-12 18:54:15 +08:00
59c321d941
fix: check user existence and register user/org if missing using rbac functions
2026-05-12 18:46:02 +08:00
e7193933ae
fix: ensure user and org are created in users table before apikey creation in usersync
2026-05-12 18:37:23 +08:00
2fb9098699
fix: correct indentation in batch loop, fix for-else bug causing continue syntax error
2026-05-12 18:30:56 +08:00
3bb57dafd7
fix: convert tabs to spaces in usersync/index.dspy to resolve TabError
2026-05-12 18:20:24 +08:00
f1ed6ad151
fix: verify user exists before returning existing apikey in usersync, clean stale downapikey records
2026-05-12 18:13:50 +08:00
09acce0637
fix: remove ServerEnv() usage in dspy script, change expires_at to expired_date
2026-05-12 18:03:32 +08:00
fb5a24c240
fix: add POST method to register form submit binding
2026-05-12 10:41:50 +08:00
15079c356b
feat: 支持x-api-key header认证模式
...
- getAuthenticationUserid增加x-api-key header检查
- 优先调用dapi模块注册的x_api_key_auth处理函数
2026-05-11 15:37:23 +08:00