34 KiB
GVA Parity Audit: Identity and Access
Scope and method
- Reference:
C:\Users\Yvan\AppData\Local\Temp\gva-parity-02f3783, commit02f37833255e0e339c3d69199cb5a468f17de9fc(the agreed GVA snapshot from 2026-08-06). - Audited local surface:
/base,/jwt,/user,/authority,/menu,/api,/casbin,/authorityBtn,/department,/position, plus request data-scope construction and policy enforcement. - Excluded by request: code generation/AutoCode, AI/MCP/skills, plugins, and endpoints that are not migrated into this repository.
- Method: for every migrated endpoint, compared method/path, binding and defaults, explicit validation, private-route authorization/operation recording, service/repository side effects and transactions, and error/success response envelope.
OK means the six dimensions above match the reference for normal operation. The
priority labels follow the consolidated plan: P1 can change route/management
behavior, P2 affects deployed clients or failure/rolling-deployment semantics,
and P3 is a lower-impact observable difference.
Shared routing and authorization evidence
| Concern | Local evidence | GVA evidence | Assessment |
|---|---|---|---|
| Public/private route split | internal/server/gin.go:34-61 |
server/initialize/router.go:71-121 |
Both expose base routes publicly and run protected routes through JWT, password-expiry guard, Casbin authorization, and data-scope context. |
| Authorization path normalization | internal/server/middleware/access.go:12-48 |
server/middleware/casbin_rbac.go:12-31 |
Both remove router-prefix before enforcing authorityId + path + method; local reads policies from DB rather than retaining an enforcer cache. |
| Data-scope identity | internal/server/middleware/access.go:35-47, internal/data/authority.go:415-480 |
server/middleware/data_scope.go:12-31, server/service/system/data_scope.go:17-101 |
Scope, direct/all/subtree/custom department resolution, and request-context injection match. |
| Operation records | internal/server/middleware/audit.go:137-170 |
route-level middleware.OperationRecord() in server/router/system/*.go |
The local exact route allowlist mirrors the reference's recording groups; rejected auth requests are not recorded in either flow. |
Findings
P2: security-rate-limit cache namespace differs
/base/login and /base/captcha count requests under KRA_SecLimit<ip><route> locally, but GVA uses GVA_SecLimit<ip><route>. With a shared cache during a rolling migration, rate-limit counters do not carry over, so a caller can obtain a fresh counter simply by reaching the other implementation.
- Local:
internal/server/middleware/rate_limit.go:13-36, especially:29. - GVA:
server/middleware/limit_ip.go:101-104. - Recommendation: use
GVA_SecLimitfor the compatible administrative API, or read both prefixes during a documented migration window. - Regression test: seed
GVA_SecLimit127.0.0.1/base/loginat the configured limit and assert the localPOST /base/loginreturns code7without invoking the handler.
P2: version response header name differs on every endpoint
The local global access logger writes X-Kra-Version; GVA writes X-Gva-Version. This is an externally observable HTTP contract difference for public and protected responses, including failures generated before handlers run.
- Local:
internal/server/middleware/access_log.go:20-36, especially:35. - GVA:
server/middleware/access_log.go:69-73, especially:71. - Recommendation: emit
X-Gva-Version(optionally retainX-Kra-Versiontemporarily as an additive header). - Regression test: request
/health,/base/captcha, and one authenticated endpoint; assert the GVA header name and value are present.
P1: /api/freshCasbin cannot report the reference refresh failure
GVA reloads its in-memory Casbin enforcer and returns 刷新失败 if the enforcer is unavailable or policy loading fails. The local authorization implementation intentionally reads casbin_rule directly and turns the endpoint into an unconditional success no-op. Normal permission changes take effect correctly, but operators cannot receive the GVA failure response.
- Local:
internal/server/handler/api.go:201-206. - GVA:
server/api/v1/system/sys_api.go:314-329,server/service/system/sys_casbin.go:159-166. - Recommendation: document the no-cache implementation in the API migration notes, or provide a compatibility health check that can fail when policy storage is unavailable.
- Regression test: inject a failing policy-store read and verify the chosen compatibility behavior is intentional and stable.
P3: empty authorityIds handling is intentionally safer locally
POST /user/setUserAuthorities accepts an empty array at the HTTP boundary in both implementations. The GVA service then indexes authorityIds[0] after deleting the old links (server/service/system/sys_user.go:199-231), which produces a panic/500 for an empty array. Kra returns a normal business error from internal/biz/user.go:165-170 instead. This is safer behavior, but it is still a contract difference that clients/tests should make explicit.
- Recommendation: keep the safe local response and add a shared validation rule requiring at least one authority ID; do not reproduce the GVA panic.
- Regression test: submit
{"id": <user>, "authorityIds": []}and assert a deterministic non-500 error with no role links lost.
Endpoint-by-endpoint matrix
Base, session, and token lifecycle
Route evidence: local internal/server/router/public.go:9-16, internal/server/router/user.go:28-30; GVA server/router/system/sys_base.go:10-17, server/router/system/sys_jwt.go:9-14.
| Endpoint | Binding, validation, authorization | Core logic / transaction / response | Result and handler evidence |
|---|---|---|---|
POST /base/captcha |
No body. Public; security limiter applies. Reads configured dimensions and IP failure count; starts count at 1 and enables captcha when open==0 or failures exceed threshold. |
Creates base64 digit captcha, persists it with configured expiry, returns captchaId, picPath, captchaLength, openCaptcha; same messages. |
P2 only for shared limiter key. Local internal/server/handler/public.go:35-52; GVA server/api/v1/system/sys_captcha.go:29-69. |
POST /base/login |
JSON username/password/captcha/captchaId; username and password required. Public; security limiter applies. |
Same lock check, conditional captcha verification and counter increment, credential/disabled handling, login audit, password-expiry flag, token issue, multipoint old-token revocation/active-token replacement, cookie and response fields. | P2 only for shared limiter key. Local internal/server/handler/public.go:54-100, internal/biz/authentication.go:63-132; GVA server/api/v1/system/sys_user.go:26-167. |
POST /jwt/jsonInBlacklist |
Private JWT/Casbin route; token read from x-token, then cookie fallback. |
Persists revoked JWT and clears cookie; local checks blacklist directly on future authentication while GVA also fills cache. Client-visible invalidation and response match. | OK. Local internal/server/handler/session.go:13-27, internal/data/api_token.go:128-130; GVA server/api/v1/system/sys_jwt_blacklist.go:20-35, server/service/system/jwt_black_list.go:24-35. |
User identity and profile
Route evidence: local internal/server/router/user.go:9-30, internal/server/router/organization.go:18,28; GVA server/router/system/sys_user.go:10-30.
| Endpoint | Binding, validation, authorization | Core logic / transaction / response | Result and handler evidence |
|---|---|---|---|
POST /user/getUserList |
JSON page/search; page and pageSize must be nonzero; private/Casbin. | Filters username/nickname/phone/email; allowed sort fields and default id desc; paginated PageResult. |
OK. Local internal/server/handler/user.go:24-44, internal/data/user.go:280-322; GVA server/api/v1/system/sys_user.go:185-219, server/service/system/sys_user.go:100-144. |
POST /user/admin_register |
JSON username/password/nickname/authority; required fields and configured password policy; private/Casbin + operation record. | Hashes password; duplicate-username check and user/role link creation in a transaction; response envelope contains user. |
OK. Local internal/server/handler/user.go:46-81, internal/data/user.go:333-405; GVA server/api/v1/system/sys_user.go:170-183, server/service/system/sys_user.go:30-69. |
PUT /user/setUserInfo |
JSON user fields; nonzero ID; private/Casbin + record. |
If authorityIds supplied, replaces role links first; then updates mutable profile fields, preserving GVA's separate-write partial-failure behavior. |
OK. Local internal/server/handler/user.go:83-98, internal/biz/user.go:121-133; GVA server/api/v1/system/sys_user.go:321-339. |
PUT /user/setSelfInfo |
JSON profile; identity comes from JWT; private/Casbin + record. | Updates caller-owned profile fields and returns 设置成功. |
OK. Local internal/server/handler/user.go:100-117, internal/data/user.go:406-429; GVA server/api/v1/system/sys_user.go:341-362, server/service/system/sys_user.go:345-348. |
DELETE /user/deleteUser |
JSON id, nonzero; blocks self-delete; private/Casbin + record. |
Transaction soft-deletes user and deletes role/department/position links. | OK. Local internal/server/handler/user.go:119-139, internal/data/user.go:493-510; GVA server/api/v1/system/sys_user.go:297-319, server/service/system/sys_user.go:301-318. |
POST /user/resetPassword |
JSON ID/password; password policy; private/Casbin + record. | Rehashes, stamps password_updated_at, preserves mustChangePassword state as GVA does. |
OK. Local internal/server/handler/user.go:141-156, internal/biz/user.go:140-149; GVA server/api/v1/system/sys_user.go:410-431, server/service/system/sys_user.go:414-421. |
POST /user/changePassword |
JSON old/new password; both required; JWT identity; password-expiry guard allows this route. | Verifies old hash, validates new password, rehashes, updates timestamp and clears forced-change flag. | OK. Local internal/server/handler/user.go:158-186, internal/biz/user.go:150-164; GVA server/api/v1/system/sys_user.go:71-94, server/service/system/sys_user.go:75-94. |
PUT /user/setSelfSetting |
JSON map; JWT identity; private/Casbin + record. | Marshals and stores origin_setting; same success envelope. |
OK. Local internal/server/handler/user.go:188-204, internal/data/user.go:563-569; GVA server/api/v1/system/sys_user.go:345-362. |
POST /user/setUserAuthorities |
JSON target ID and authority IDs; private/Casbin + record. | For non-empty IDs, transaction replaces role links and sets first supplied role as primary; strict-role guard is enforced for submitted role IDs. Empty IDs return a deterministic local business error, while GVA panics after deleting links. | P3 safer-input divergence. Local internal/server/handler/user.go:206-217, internal/biz/user.go:165-170, internal/data/user.go:512-544; GVA server/api/v1/system/sys_user.go:195-230, server/service/system/sys_user.go:199-232. |
POST /user/setUserAuthority |
JSON authority ID required; caller identity from JWT; private/Casbin + record. | Verifies membership and default router, updates active authority, signs a same-expiry replacement token, writes new-token/new-expires-at and cookie. |
OK. Local internal/server/handler/user.go:219-244, internal/biz/authentication.go:138-153; GVA server/api/v1/system/sys_user.go:146-193, server/service/system/sys_user.go:150-193. |
GET /user/getUserInfo |
No body; JWT identity; private/Casbin and password-expiry guard allows it. | Loads by JWT UUID with authorities, primary/multiple departments, positions, default-router fallback, and name paths. | OK. Local internal/server/handler/user.go:246-258, internal/data/user.go:44-97; GVA server/api/v1/system/sys_user.go:364-408, server/service/system/sys_user.go:368-409. |
POST /user/setUserDepartments |
JSON user ID, deptIds, primaryDeptId; nonzero user ID; private/Casbin + record. |
Transaction replaces department links; selects first department as missing primary and rejects a primary outside the submitted set. | OK. Local internal/server/handler/organization.go:119-134, internal/data/department.go:242-274; GVA server/api/v1/system/sys_user.go:234-274, server/service/system/sys_user.go:236-274. |
POST /user/setUserPositions |
JSON user ID and position IDs; nonzero user ID; private/Casbin + record. | Transaction replaces user-position links. | OK. Local internal/server/handler/organization.go:238-253, internal/data/position.go:133-147; GVA server/api/v1/system/sys_user.go:276-295, server/service/system/sys_user.go:277-295. |
Authorities and data scope
Route evidence: local internal/server/router/authority.go:9-20; GVA server/router/system/sys_authority.go:10-26.
| Endpoint | Binding, validation, authorization | Core logic / transaction / response | Result and handler evidence |
|---|---|---|---|
POST /authority/getAuthorityList |
No body; private/Casbin. | Builds tree under current authority; applies strict-tree visibility, including non-root direct children behavior. | OK. Local internal/server/handler/authority.go:15-21, internal/data/authority.go:300-342; GVA server/api/v1/system/sys_authority.go:163-181, server/service/system/sys_authority.go:151-186. |
POST /authority/createAuthority |
JSON authority ID/name required; strict mode reparents a root request to actor; private/Casbin + record. | Transaction checks duplicate, applies defaults, seeds dashboard menu and the nine default policies; success contains authority. |
OK. Local internal/server/handler/authority.go:23-42, internal/data/authority.go:72-114; GVA server/api/v1/system/sys_authority.go:26-65, server/service/system/sys_authority.go:32-74, server/model/system/request/sys_casbin.go:15-26. |
POST /authority/copyAuthority |
JSON old/new authority; both IDs and new name required; private/Casbin + record. | Transaction copies assigned menus, buttons and deduplicated policies; strict mode prevents copying out-of-scope policy paths. | OK. Local internal/server/handler/authority.go:44-67, internal/data/authority.go:115-241; GVA server/api/v1/system/sys_authority.go:67-101, server/service/system/sys_authority.go:76-123. |
PUT /authority/updateAuthority |
JSON authority ID/name required; private/Casbin + record. | Looks up target then updates authority metadata and returns it under authority. |
OK. Local internal/server/handler/authority.go:69-88, internal/data/authority.go:242-250; GVA server/api/v1/system/sys_authority.go:133-161, server/service/system/sys_authority.go:125-145. |
POST /authority/deleteAuthority |
JSON authority ID required; private/Casbin + record. | Transaction blocks users/primary users/children, clears user/menu/button/policy links, permanently removes authority row. | OK. Local internal/server/handler/authority.go:90-104, internal/data/authority.go:251-299; GVA server/api/v1/system/sys_authority.go:103-131, server/service/system/sys_authority.go:127-149. |
POST /authority/setRoleUsers |
JSON authority ID required; private/Casbin + record. | Transaction replaces role-user links; changes primary role of removed users only when another role remains. | OK. Local internal/server/handler/authority.go:106-120, internal/data/authority.go:343-385; GVA server/api/v1/system/sys_authority.go:263-286, server/service/system/sys_authority.go:303-367. |
GET /authority/getUsersByAuthority |
Query authorityId; private/Casbin. |
Returns empty array rather than null. | OK. Local internal/server/handler/authority.go:122-136; GVA server/api/v1/system/sys_authority.go:236-261. |
POST /authority/setDataScope |
JSON authority ID required; private/Casbin + record. | Transaction updates data_scope, clears old custom departments, inserts submitted departments only for scope 5. |
OK. Local internal/server/handler/authority.go:138-152, internal/data/authority.go:390-409; GVA server/api/v1/system/sys_authority.go:183-207, server/service/system/sys_authority.go:238-262. |
GET /authority/getDataScopeDepts |
Query authorityId; private/Casbin. |
Returns custom department IDs, normalizing nil to []. |
OK. Local internal/server/handler/authority.go:154-168; GVA server/api/v1/system/sys_authority.go:209-234, server/service/system/sys_authority.go:264-270. |
Menu and navigation
Route evidence: local internal/server/router/menu.go:9-21, internal/server/router/user.go:24-26; GVA server/router/system/sys_menu.go:10-29.
| Endpoint | Binding, validation, authorization | Core logic / transaction / response | Result and handler evidence |
|---|---|---|---|
POST /menu/getMenu |
Empty body; JWT authority; private/Casbin. | Reads role-assigned menus, ordered tree, parameters and selected button map; returns {menus}. |
OK. Local internal/server/handler/navigation.go:14-28, internal/data/user.go:197-278; GVA server/api/v1/system/sys_menu.go:25-44, server/service/system/sys_menu.go:30-87. |
POST /menu/getMenuList |
No effective body fields; private/Casbin. | Produces strict-aware base-menu tree with parameters/buttons. | OK. Local internal/server/handler/menu.go:15-22, internal/data/menu.go:181-243; GVA server/api/v1/system/sys_menu.go:325-342, server/service/system/sys_menu.go:89-121. |
POST /menu/getBaseMenuTree |
Empty body; private/Casbin. | Same base tree, wrapped as {menus}. |
OK. Local internal/server/handler/menu.go:24-31; GVA server/api/v1/system/sys_menu.go:46-64. |
POST /menu/addBaseMenu |
JSON path/name/component/meta.title required; nonnegative sort; private/Casbin + record. | Transaction rejects duplicate name, validates parent and default-router constraints, inserts menu then parameters/buttons. | OK. Local internal/server/handler/menu.go:33-64, internal/data/menu.go:60-99; GVA server/api/v1/system/sys_menu.go:125-158, server/service/system/sys_menu.go:123-171. |
POST /menu/updateBaseMenu |
Same validation as create; private/Casbin + record. | Transaction finds menu, checks renamed duplicate, replaces parameters/buttons, updates scalar fields. | OK. Local internal/server/handler/menu.go:66-97, internal/data/menu.go:101-122; GVA server/api/v1/system/sys_menu.go:190-223, server/service/system/sys_base_menu.go. |
POST /menu/deleteBaseMenu |
JSON nonzero ID; private/Casbin + record. | Transaction blocks children/default-router use, then deletes menu, relations and permission buttons. | OK. Local internal/server/handler/menu.go:99-114, internal/data/menu.go:124-155; GVA server/api/v1/system/sys_menu.go:160-188. |
POST /menu/getBaseMenuById |
JSON nonzero ID; private/Casbin + record. | Loads menu with parameters/buttons and returns {menu}. |
OK. Local internal/server/handler/menu.go:116-132, internal/data/menu.go:158-180; GVA server/api/v1/system/sys_menu.go:225-253. |
POST /menu/addMenuAuthority |
JSON authority ID required; private/Casbin + record. | Strict-mode target/menu scope checks, then transaction replaces role-menu links. | OK. Local internal/server/handler/menu.go:134-149, internal/data/menu.go:259-309; GVA server/api/v1/system/sys_menu.go:66-93, server/service/system/sys_menu.go:202-241. |
POST /menu/getMenuAuthority |
JSON authority ID required; private/Casbin. | Reads target role's own assigned base menus without applying caller's listing filter; response {menus}. |
OK. Local internal/server/handler/menu.go:151-167, internal/data/menu.go:313-331; GVA server/api/v1/system/sys_menu.go:95-123. |
GET /menu/getMenuRoles |
Query nonzero menuId; private/Casbin. |
Returns role IDs and defaultRouterAuthorityIds, normalizing nil arrays. |
OK. Local internal/server/handler/menu.go:169-196, internal/data/menu.go:333-346; GVA server/api/v1/system/sys_menu.go:255-296. |
POST /menu/setMenuRoles |
JSON nonzero menuId; private/Casbin + record. |
Transaction replaces all role-menu rows. | OK. Local internal/server/handler/menu.go:198-212, internal/data/menu.go:348-364; GVA server/api/v1/system/sys_menu.go:298-323, server/service/system/sys_menu.go. |
API registry and Casbin policy management
Route evidence: local internal/server/router/api.go:9-28; GVA server/router/system/sys_api.go:10-35, server/router/system/sys_casbin.go:10-19.
| Endpoint | Binding, validation, authorization | Core logic / transaction / response | Result and handler evidence |
|---|---|---|---|
POST /api/getApiList |
JSON page/pageSize nonzero plus filters/order; private/Casbin. | Same filters, allowed sort whitelist and paged PageResult. |
OK. Local internal/server/handler/api.go:15-34, internal/data/api.go:121-181; GVA server/api/v1/system/sys_api.go:177-210, server/service/system/sys_api.go:185-232. |
POST /api/getAllApis |
No body; private/Casbin. | Returns all APIs ordered id desc, but strict non-root caller only sees APIs permitted by own policies. |
OK. Local internal/server/handler/api.go:36-42, internal/data/api.go:121-152; GVA server/api/v1/system/sys_api.go:271-289, server/service/system/sys_api.go:239-270. |
POST /api/createApi |
JSON path/description/apiGroup/method all required; private/Casbin + record. | Duplicate path+method rejection; creates and returns populated API row. | OK. Local internal/server/handler/api.go:44-59, internal/data/api.go:55-69; GVA server/api/v1/system/sys_api.go:26-53, server/service/system/sys_api.go:26-33. |
POST /api/updateApi |
Same required fields; private/Casbin + record. | Finds target, rejects duplicate changed path/method, updates matching policies first, then API metadata. | OK. Local internal/server/handler/api.go:61-75, internal/data/api.go:70-94; GVA server/api/v1/system/sys_api.go:242-269, server/service/system/sys_api.go:278-304. |
POST /api/deleteApi |
JSON nonzero ID; private/Casbin + record. | Requires existing row then deletes it and matching policy/legacy relation rows. | OK. Local internal/server/handler/api.go:77-91, internal/biz/api.go:39-47, internal/data/api.go:95-120; GVA server/api/v1/system/sys_api.go:147-175, server/service/system/sys_api.go:165-177. |
DELETE /api/deleteApisByIds |
JSON ID slice; private/Casbin + record. | Transaction deletes selected rows and matching policies; empty/missing ID behavior follows GVA bulk semantics. | OK. Local internal/server/handler/api.go:93-103, internal/data/api.go:95-120; GVA server/api/v1/system/sys_api.go:291-312, server/service/system/sys_api.go:312-332. |
POST /api/getApiById |
JSON nonzero ID; private/Casbin + record. | Finds one API and wraps it as {api}. |
OK. Local internal/server/handler/api.go:105-120; GVA server/api/v1/system/sys_api.go:212-240. |
GET /api/getApiGroups |
No body; private/Casbin + record. | Natural-ID scan produces first-seen group list and path-segment map. | OK. Local internal/server/handler/api.go:122-128, internal/service/api.go:64-86; GVA server/api/v1/system/sys_api.go:77-96, server/service/system/sys_api.go:35-56. |
GET /api/getApiRoles |
Query path and method required; private/Casbin. | Reads role IDs from p policies; nil becomes []. |
OK. Local internal/server/handler/api.go:130-144, internal/data/api.go:182-201; GVA server/api/v1/system/sys_api.go:334-360, server/service/system/sys_casbin.go:169-184. |
POST /api/setApiRoles |
JSON path/method required; private/Casbin + record. | Transaction removes all matching policy rows then inserts the requested roles; GVA cache reload is unnecessary locally because policy is DB-read. | OK. Local internal/server/handler/api.go:146-161, internal/data/api.go:202-222; GVA server/api/v1/system/sys_api.go:362-389, server/service/system/sys_casbin.go:186-206. |
GET /api/syncApi |
No body; private/Casbin + record. | Compares engine routes to API rows and ignore rows; returns all arrays as newApis/deleteApis/ignoreApis. |
OK. Local internal/server/handler/api.go:163-178, internal/biz/api.go:50-95; GVA server/api/v1/system/sys_api.go:55-75, server/service/system/sys_api.go:58-130. |
POST /api/ignoreApi |
JSON path/method/flag; private/Casbin + record. | Inserts duplicate ignore row when flag true; permanently deletes all matching ignore rows when false. | OK. Local internal/server/handler/api.go:180-191, internal/data/api.go:335-350; GVA server/api/v1/system/sys_api.go:98-120, server/service/system/sys_api.go:132-137. |
POST /api/enterSyncApi |
JSON submitted added/deleted arrays; private/Casbin + record. | Transaction inserts submitted additions and deletes matching APIs/policies. | OK. Local internal/server/handler/api.go:193-199, internal/data/api.go:351-384; GVA server/api/v1/system/sys_api.go:122-145, server/service/system/sys_api.go:139-157. |
GET /api/freshCasbin |
Public, no body. | GVA reloads cache; local is a DB-policy no-op. | P1; see finding. Local internal/server/handler/api.go:201-206; GVA server/api/v1/system/sys_api.go:314-329. |
POST /casbin/updateCasbin |
JSON nonzero authority ID; private/Casbin + record. | Enforces strict target and policy scope, clears old authority policies, deduplicates and adds replacement paths. | OK. Local internal/server/handler/api.go:208-222, internal/data/api.go:261-334; GVA server/api/v1/system/sys_casbin.go:23-52, server/service/system/sys_casbin.go:29-89. |
POST /casbin/getPolicyPathByAuthorityId |
JSON nonzero authority ID; private/Casbin. | Returns {paths} with path/method policy pairs. Local DB query avoids GVA cache staleness in normal endpoint flows. |
OK. Local internal/server/handler/api.go:224-239, internal/data/api.go:238-260; GVA server/api/v1/system/sys_casbin.go:54-79, server/service/system/sys_casbin.go:121-140. |
Authority button permissions
Route evidence: local internal/server/router/permission.go:9-14; GVA server/router/system/sys_authority_btn.go:11-19.
| Endpoint | Binding, validation, authorization | Core logic / transaction / response | Result and handler evidence |
|---|---|---|---|
POST /authorityBtn/getAuthorityBtn |
JSON authority/menu IDs; private/Casbin. | Loads selected base-button IDs and returns {selected}. |
OK. Local internal/server/handler/permission.go:17-29, internal/data/permission.go:58-75; GVA server/api/v1/system/sys_authority_btn.go:21-44, server/service/system/sys_authority_btn.go:18-34. |
POST /authorityBtn/setAuthorityBtn |
JSON authority/menu IDs and selection; private/Casbin. | Transaction deletes current selection for that authority/menu and inserts submitted IDs. | OK. Local internal/server/handler/permission.go:31-42, internal/data/permission.go:76-90; GVA server/api/v1/system/sys_authority_btn.go:46-68, server/service/system/sys_authority_btn.go:36-63. |
POST /authorityBtn/canRemoveAuthorityBtn |
Query id; private/Casbin. |
Succeeds only when no authority-button reference exists; same failure message. | OK. Local internal/server/handler/permission.go:44-55, internal/data/permission.go:91-100; GVA server/api/v1/system/sys_authority_btn.go:70-85, server/service/system/sys_authority_btn.go:65-74. |
Departments and positions
Route evidence: local internal/server/router/organization.go:9-29; GVA server/router/system/sys_department.go:10-24, server/router/system/sys_position.go:10-24.
| Endpoint | Binding, validation, authorization | Core logic / transaction / response | Result and handler evidence |
|---|---|---|---|
POST /department/getDepartmentList |
JSON search is deliberately best-effort; private/Casbin. | Name search returns flat list; no search builds sorted recursive tree with leaders. | OK. Local internal/server/handler/organization.go:20-28, internal/data/department.go:173-219; GVA server/api/v1/system/sys_department.go:100-119, server/service/system/sys_department.go:151-187. |
POST /department/createDepartment |
JSON name required; private/Casbin + record. | Resolves parent, derives ancestors (0 root), and inserts department. |
OK. Local internal/server/handler/organization.go:30-44, internal/data/department.go:85-100; GVA server/api/v1/system/sys_department.go:23-48, server/service/system/sys_department.go:88-100. |
PUT /department/updateDepartment |
JSON nonzero ID; private/Casbin + record. | Rejects self-parent, validates parent, recomputes this node's ancestors only. | OK. Local internal/server/handler/organization.go:46-60, internal/data/department.go:101-120; GVA server/api/v1/system/sys_department.go:50-75, server/service/system/sys_department.go:102-121. |
DELETE /department/deleteDepartment |
JSON ID; private/Casbin + record. | Blocks children, primary-department users and join-table users before deleting. | OK. Local internal/server/handler/organization.go:62-72, internal/data/department.go:121-149; GVA server/api/v1/system/sys_department.go:77-98, server/service/system/sys_department.go:123-149. |
GET /department/findDepartment |
Query ID; private/Casbin. | Loads one department with leader. | OK. Local internal/server/handler/organization.go:74-85, internal/data/department.go:150-172; GVA server/api/v1/system/sys_department.go:121-142, server/service/system/sys_department.go:151-153. |
GET /department/getDepartmentUsers |
Query department ID; private/Casbin. | Reads join-table user IDs; nil normalizes to []. |
OK. Local internal/server/handler/organization.go:87-101, internal/data/department.go:220-225; GVA server/api/v1/system/sys_department.go:144-169, server/service/system/sys_department.go:190-195. |
POST /department/setDepartmentUsers |
JSON nonzero department ID; private/Casbin + record. | Transaction replaces membership; clears removed primary department and sets the department for additions without one. | OK. Local internal/server/handler/organization.go:103-117, internal/data/department.go:226-241; GVA server/api/v1/system/sys_department.go:171-194, server/service/system/sys_department.go:197-243. |
POST /position/getPositionList |
JSON search; no page validation by either implementation; private/Casbin. | Same name/code/status filters, sort ordering, raw supplied limit/offset and PageResult. |
OK. Local internal/server/handler/organization.go:136-147, internal/data/position.go:77-111; GVA server/api/v1/system/sys_position.go:100-127, server/service/system/sys_position.go:76-101. |
POST /position/createPosition |
JSON name required; private/Casbin + record. | Inserts name/code/sort/status/remark. | OK. Local internal/server/handler/organization.go:149-163, internal/data/position.go:51-53; GVA server/api/v1/system/sys_position.go:23-48, server/service/system/sys_position.go:19-22. |
PUT /position/updatePosition |
JSON nonzero ID; private/Casbin + record. | Updates name/code/sort/status/remark. | OK. Local internal/server/handler/organization.go:165-179, internal/data/position.go:54-56; GVA server/api/v1/system/sys_position.go:50-75, server/service/system/sys_position.go:24-36. |
DELETE /position/deletePosition |
JSON ID; private/Casbin + record. | Blocks existing user-position links, then soft-deletes. | OK. Local internal/server/handler/organization.go:181-191, internal/data/position.go:57-70; GVA server/api/v1/system/sys_position.go:77-98, server/service/system/sys_position.go:38-51. |
GET /position/findPosition |
Query ID; private/Casbin. | Loads one position. | OK. Local internal/server/handler/organization.go:193-204, internal/data/position.go:71-76; GVA server/api/v1/system/sys_position.go:129-150, server/service/system/sys_position.go:53-57. |
GET /position/getPositionUsers |
Query position ID; private/Casbin. | Reads user IDs and normalizes nil to []. |
OK. Local internal/server/handler/organization.go:206-220, internal/data/position.go:112-117; GVA server/api/v1/system/sys_position.go:152-177, server/service/system/sys_position.go:103-108. |
POST /position/setPositionUsers |
JSON nonzero position ID; private/Casbin + record. | Transaction replaces all links for target position. | OK. Local internal/server/handler/organization.go:222-236, internal/data/position.go:118-132; GVA server/api/v1/system/sys_position.go:179-202, server/service/system/sys_position.go:110-130. |
Recommended validation plan
- Contract tests: table-drive every route above for method/path, envelope, success message, and required-field failure. Add the two response-header cases and public
freshCasbinbehavior. - Shared-cache migration tests: run both binaries against one Redis/cache instance and verify captcha/login rate limits, captcha values, multipoint session keys, and JWT blacklist behavior across the boundary.
- Authority/Casbin transaction tests: duplicate policies, strict non-root role assignment, copy authority, update API path/method, sync deletion, and role/menu/button replacement with injected write failures.
- Organization/data-scope tests: multi-department primary reassignment, department move ancestors, scope 1/2/4/5 read/write filtering, and blocked-write audit events.
- Manual smoke suite: login -> switch role -> load menus -> assign API/menu/button policies -> refresh/verify authorization -> logout -> assert old token rejection.
Conclusion
All audited migrated identity/access endpoints match GVA's route, validation, permission, data mutation, transaction, and JSON-envelope behavior under normal operation. The scoped identity/access findings are: the P2 rate-limit cache prefix, the P2 version response-header name, the P1 freshCasbin failure-semantics difference, and the P3 safer handling of an empty authorityIds array. Cross-cutting route-table/static-file, CORS, JWT-store, and router-prefix synchronization findings are tracked in parity-crosscut.md rather than duplicated here.