231 Commits

Author SHA1 Message Date
ce7eb2a193 refactor: bind hot_reload event via EventDispatcher, add on_hot_reload to UserPermissions 2026-06-01 18:10:29 +08:00
c949a51f2e fix: gen_sms_code.dspy handle both None return and exception from generate_sms_code 2026-05-31 12:26:55 +08:00
4038b7d0b9 fix: gen_sms_code.dspy catch exception and return actual error message 2026-05-31 11:56:46 +08:00
7f2c3d25dd feat: 用户菜单添加完善信息功能 - 新增 edit_profile.dspy/save_profile.dspy - usermenu.ui 添加完善信息入口 - load_path.py 注册权限路径 2026-05-31 10:52:13 +08:00
26d1fd1447 feat: register_user 添加 customer.admin 角色,注册时同时分配 customer 和 admin 权限 2026-05-31 10:38:32 +08:00
c9dd80a484 fix: 暗色主题输入框颜色全局优化
- bricks.css: inputbox背景 #1E293B → #0F172A
- login.css: 同步更新保持一致
2026-05-30 14:32:11 +08:00
b0d6b59613 fix: 注册表单仅输入区域滚动,暗色主题输入框颜色优化
- 注册Tab结构: Text(固定) + VScrollPanel(仅Form) + Button(固定)
- 暗色主题输入框背景 #0f172a -> #1e293b,更协调
2026-05-30 14:27:33 +08:00
d1b3ca0914 fix: 修复登录弹窗三个显示问题
- 注册表单超出无滚动: 三个Tab内容均包裹VScrollPanel(scrollpanel)
- Form toolbar不可见: 滚动容器让submit/reset按钮可达
- 文本未国际化: title/label/otext均加i18n:true, archor纠正
- CSS: tabpanel flex布局, tabpanel-content flex:1+min-height:0
- PopupWindow cheight 28->30 给更多显示空间
2026-05-30 14:16:00 +08:00
36569c0e41 feat: 现代化登录/注册界面改造
- login.css: 全新现代化样式,支持亮/暗主题
- login.ui: 三Tab布局(密码登录/手机登录/注册),手机登录支持短信验证码
- sms_register.dspy: 短信验证注册后端,验证通过后自动注册并登录
- load_path.py: 添加 sms_register.dspy 到 any 权限
- 修复手机登录 setValue 调用 (上一轮已提交)
- 注册流程: 手机号+短信验证码+用户名+密码,短信验证通过后才允许注册
2026-05-30 14:08:11 +08:00
019e9702fc fix: use setValue() on codeid field widget instead of direct value assignment 2026-05-30 13:36:54 +08:00
cec79caf88 fix: phone login form.setValue is not a function - use name_inputs direct value set 2026-05-30 13:35:07 +08:00
b532548d19 fix: keep previous rp_caches when DB returns empty result
sqlExe can return [] without raising an exception (bad connection,
cursor issue). When load_roleperms gets 0 records but had valid
cache before, keep the old cache instead of replacing with {}.
Prevents intermittent 403 from transient DB issues.
2026-05-30 11:34:13 +08:00
fbbe011a8d fix: rp_caches race condition causing intermittent 403
load_roleperms() was setting self.rp_caches = {} before the async
DB query. During the await, other coroutines saw {} (not None),
skipped the load, and checked permissions against an empty dict,
causing intermittent 403 on random paths.

Fix: build in local dict first, assign atomically when complete.
2026-05-30 11:19:32 +08:00
c776c0b3b5 fix: rp_cache should reload from DB when cache is disabled 2026-05-30 10:19:00 +08:00
04e9b718db fix: check_roles_path supports % wildcard alongside **
load_path.py scripts across modules register paths like '/module/api/%'
using SQL LIKE wildcard, but check_roles_path() only recognized '**' as
wildcard suffix. This caused all %-terminated paths to be treated as
exact matches, resulting in 403 for any sub-path.

Now both '/module/api/%' and '/module/api/**' work as prefix wildcards.
2026-05-29 23:12:22 +08:00
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