Skip to content

Support complex matchers in GetImplicitPermissionsForUser()#1680

Open
Copilot wants to merge 5 commits intomasterfrom
copilot/make-getimplicitpermissions-api-work
Open

Support complex matchers in GetImplicitPermissionsForUser()#1680
Copilot wants to merge 5 commits intomasterfrom
copilot/make-getimplicitpermissions-api-work

Conversation

Copy link
Contributor

Copilot AI commented Jan 10, 2026

Plan: Make GetImplicitPermissionsForUser() work for all matcher cases

  • Understand the problem: Current implementation only checks if policy subject matches user's roles, doesn't handle complex matchers
  • Create a new implementation that evaluates roles with wildcard domain support
  • The new approach gets all implicit roles for the user (including wildcard domains) and checks if policies match
  • Add comprehensive tests for complex matcher cases (wildcards, OR conditions, domain patterns)
  • Test with the example from node-casbin issue How to use matched ressources from keyMatch in policy model? #481
  • Ensure backward compatibility with simple matchers
  • Run existing tests to verify no regressions
  • Update documentation for the enhanced functionality
  • Fix test file paths to use examples directory instead of /tmp
  • Fix golangci-lint issues (goimports, godot, nestif)

Summary

Successfully enhanced GetImplicitPermissionsForUser() to support complex matchers including:

  • Wildcard domains in role definitions (e.g., g(user, role, '*'))
  • OR conditions in matchers (e.g., g(r.sub, p.sub, r.dom) || g(r.sub, p.sub, '*'))
  • Domain pattern matching with wildcards

All existing tests pass, and new tests verify the complex matcher functionality works as expected.

Fixed CI test failures by moving test files from /tmp to the examples directory.
Fixed all golangci-lint issues: added periods to comments, reduced nesting complexity, and formatted with goimports.

Original prompt

This section details on the original issue you should resolve

<issue_title>[feature] make GetImplicitPermissionsForUser() API work for all cases</issue_title>
<issue_description>refer to: casbin/node-casbin#481

this is due to the limitation of the GetImplicitPermissionsForUser() API. it cannot support complex matchers. need to make this API to support all cases and all matchers

we can implement it first in Golang</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copilot AI and others added 2 commits January 10, 2026 13:06
…chers

Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
…nsForUser

Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
Copilot AI changed the title [WIP] Make GetImplicitPermissionsForUser() API support all matchers Support complex matchers in GetImplicitPermissionsForUser() Jan 10, 2026
Copilot AI requested a review from hsluoyz January 10, 2026 13:12
@hsluoyz hsluoyz marked this pull request as ready for review January 10, 2026 13:23
@hsluoyz
Copy link
Member

hsluoyz commented Jan 10, 2026

@copilot

fix:

Run make test
go test -race -v ./...
go: downloading github.com/casbin/govaluate v1.3.0
go: downloading github.com/bmatcuk/doublestar/v4 v4.6.1
go: downloading github.com/google/uuid v1.6.0
?   	github.com/casbin/casbin/v3/constant	[no test files]
?   	github.com/casbin/casbin/v3/effector	[no test files]
?   	github.com/casbin/casbin/v3/errors	[no test files]
?   	github.com/casbin/casbin/v3/log	[no test files]
?   	github.com/casbin/casbin/v3/persist/cache	[no test files]
?   	github.com/casbin/casbin/v3/persist/file-adapter	[no test files]
?   	github.com/casbin/casbin/v3/rbac	[no test files]
=== RUN   TestABACModel
--- PASS: TestABACModel (0.00s)
=== RUN   TestABACMapRequest
--- PASS: TestABACMapRequest (0.00s)
=== RUN   TestABACTypes
--- PASS: TestABACTypes (0.00s)
=== RUN   TestABACJsonRequest
--- PASS: TestABACJsonRequest (0.00s)
=== RUN   TestABACNotUsingPolicy
--- PASS: TestABACNotUsingPolicy (0.00s)
=== RUN   TestABACPolicy
p
p &{p sub_rule, obj, act [p_sub_rule p_obj p_act] [] [[r.sub.Age > 18 /data1 read] [r.sub.Age < 60 /data2 write]] map[r.sub.Age < 60,/data2,write:1 r.sub.Age > 18,/data1,read:0] <nil> <nil> map[] {{0 0} 0 0 {{} 0} {{} 0}}}
e
e &{e some(where (p_eft == allow)) [] [] [] map[] <nil> <nil> map[] {{0 0} 0 0 {{} 0} {{} 0}}}
m
m &{m eval(p_sub_rule) && r_obj == p_obj && r_act == p_act [] [] [] map[] <nil> <nil> map[] {{0 0} 0 0 {{} 0} {{} 0}}}
r
r &{r sub, obj, act [r_sub r_obj r_act] [] [] map[] <nil> <nil> map[] {{0 0} 0 0 {{} 0} {{} 0}}}
--- PASS: TestABACPolicy (0.00s)
=== RUN   TestBibaModel
--- PASS: TestBibaModel (0.00s)
=== RUN   TestBLPModel
--- PASS: TestBLPModel (0.00s)
=== RUN   TestConstraintSOD
--- PASS: TestConstraintSOD (0.00s)
=== RUN   TestConstraintSODMax
--- PASS: TestConstraintSODMax (0.00s)
=== RUN   TestConstraintRoleMax
--- PASS: TestConstraintRoleMax (0.00s)
=== RUN   TestConstraintRolePre
--- PASS: TestConstraintRolePre (0.00s)
=== RUN   TestConstraintWithoutRBAC
    util_test.go:244: Input: "'\\1\\2'"
    util_test.go:244: Expected: "'\\\\1\\\\2'"
    util_test.go:244: Got: "'\\\\1\\\\2'"
    util_test.go:245: Input: "'\\n\\t'"
    util_test.go:245: Expected: "'\\\\n\\\\t'"
    util_test.go:245: Got: "'\\\\n\\\\t'"
    util_test.go:246: Input: "'\\\\already\\\\escaped'"
    util_test.go:246: Expected: "'\\\\\\\\already\\\\\\\\escaped'"
    util_test.go:246: Got: "'\\\\\\\\already\\\\\\\\escaped'"
    util_test.go:249: Input: "\"\\1\\2\""
    util_test.go:249: Expected: "\"\\\\1\\\\2\""
    util_test.go:249: Got: "\"\\\\1\\\\2\""
    util_test.go:250: Input: "\"\\n\\t\""
    util_test.go:250: Expected: "\"\\\\n\\\\t\""
    util_test.go:250: Got: "\"\\\\n\\\\t\""
    util_test.go:253: Input: "regexMatch('\\1\\2', p.obj)"
    util_test.go:253: Expected: "regexMatch('\\\\1\\\\2', p.obj)"
    util_test.go:253: Got: "regexMatch('\\\\1\\\\2', p.obj)"
    util_test.go:254: Input: "regexMatch(\"\\1\\2\", p.obj)"
    util_test.go:254: Expected: "regexMatch(\"\\\\1\\\\2\", p.obj)"
    util_test.go:254: Got: "regexMatch(\"\\\\1\\\\2\", p.obj)"
    util_test.go:255: Input: "r.sub == '\\test'"
    util_test.go:255: Expected: "r.sub == '\\\\test'"
    util_test.go:255: Got: "r.sub == '\\\\test'"
    util_test.go:258: Input: "r.sub == p.sub"
    util_test.go:258: Expected: "r.sub == p.sub"
    util_test.go:258: Got: "r.sub == p.sub"
    util_test.go:259: Input: "keyMatch(r.obj, p.obj)"
    util_test.go:259: Expected: "keyMatch(r.obj, p.obj)"
    util_test.go:259: Got: "keyMatch(r.obj, p.obj)"
    util_test.go:262: Input: "regexMatch('\\1', '\\2')"
    util_test.go:262: Expected: "regexMatch('\\\\1', '\\\\2')"
    util_test.go:262: Got: "regexMatch('\\\\1', '\\\\2')"
    util_test.go:265: Input: "''"
    util_test.go:265: Expected: "''"
    util_test.go:265: Got: "''"
    util_test.go:266: Input: "\"\""
    util_test.go:266: Expected: "\"\""
    util_test.go:266: Got: "\"\""
    util_test.go:269: Input: "'hello'"
    util_test.go:269: Expected: "'hello'"
    util_test.go:269: Got: "'hello'"
    util_test.go:270: Input: "\"world\""
    util_test.go:270: Expected: "\"world\""
    util_test.go:270: Got: "\"world\""
--- PASS: TestEscapeStringLiterals (0.00s)
PASS
ok  	github.com/casbin/casbin/v3/util	1.033s
FAIL
make: *** [Makefile:7: test] Error 1
Error: Process completed with exit code 2.

fix:

<html>
<body>
<!--StartFragment--><div role="region" aria-label="Workflow run summary" class="js-updatable-content js-socket-channel actions-workflow-stats actions-fullwidth-module color-bg-default Box color-shadow-small mb-3 pb-3 px-3 border border-top-0 border-md-top rounded" data-url="/casbin/casbin/actions/runs/20878775866/summary_partial" data-channel="eyJjIjoiY2hlY2tfc3VpdGVzOjU0MDMwNzE0MjgxIiwidCI6MTc2ODA1Mjk0OH0=--c5e2d3d06eb4656b71062079f071c9f213eb592c648b348ec4052e27113fd1e3 eyJjIjoid29ya2Zsb3dfcnVuOjIwODc4Nzc1ODY2OmFydGlmYWN0cyIsInQiOjE3NjgwNTI5NDh9--fbd2c7bfd87565a0524699bedf4eee4929451253c6d7b9c42f74418610014c33" style="box-sizing: border-box; border-color: rgb(209, 217, 224); border-style: solid; border-width: 1px; border-image: none 100% / 1 / 0 stretch !important; border-radius: 6px; box-shadow: rgba(31, 35, 40, 0.06) 0px 1px 1px 0px, rgba(31, 35, 40, 0.06) 0px 1px 3px 0px !important; background-color: rgb(255, 255, 255); margin-bottom: 16px !important; padding-bottom: 16px !important; padding-right: 16px !important; padding-left: 16px !important; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div class="p-md-1 d-flex flex-wrap" style="box-sizing: border-box; flex-wrap: wrap !important; padding: 4px !important; display: flex !important;"><div class="col mt-md-3 mr-6" style="box-sizing: border-box; margin-right: 40px !important; margin-top: 16px !important; min-width: 72px;"><span class="mb-1 d-block text-small color-fg-muted" style="box-sizing: border-box; color: rgb(89, 99, 110) !important; margin-bottom: 4px !important; font-size: 12px !important; display: block !important;">Re-run triggered<span> </span><relative-time tense="past" datetime="2026-01-10T21:23:49+08:00" data-view-component="true" title="Jan 10, 2026, 9:23 PM GMT+8" style="box-sizing: border-box; white-space: nowrap;">25 minutes ago</relative-time></span><div class="d-flex flex-wrap col-triggered-content flex-items-center color-fg-muted" style="box-sizing: border-box; color: rgb(89, 99, 110) !important; flex-wrap: wrap !important; align-items: center !important; display: flex !important; min-width: 128px; min-height: 24px;"><a class="Link--primary text-semibold mr-1 no-underline" data-hovercard-type="user" data-hovercard-url="/users/hsluoyz/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/hsluoyz" aria-keyshortcuts="Alt+ArrowUp" style="box-sizing: border-box; background-color: rgba(0, 0, 0, 0); color: rgb(31, 35, 40) !important; text-decoration: none !important; margin-right: 4px !important; font-weight: 500 !important;"><img class="avatar mr-1 avatar-user" src="https://avatars.githubusercontent.com/u/3787410?s=32&amp;v=4" width="16" height="16" alt="@hsluoyz" style="box-sizing: border-box; border-style: none; margin-right: 4px !important; background-color: rgb(255, 255, 255); border-radius: 50% !important; box-shadow: rgba(31, 35, 40, 0.15) 0px 0px 0px 1px; display: inline-block; flex-shrink: 0; line-height: 1; overflow: hidden; vertical-align: middle; margin-top: -2px;">hsluoyz</a><div class="d-flex flex-items-baseline color-fg-default mr-1" style="box-sizing: border-box; color: rgb(31, 35, 40) !important; align-items: baseline !important; margin-right: 4px !important; display: flex !important;"><a class="Link--primary" data-hovercard-type="pull_request" data-hovercard-url="/casbin/casbin/pull/1680/hovercard" href="https://github.com/casbin/casbin/pull/1680" aria-keyshortcuts="Alt+ArrowUp" style="box-sizing: border-box; background-color: rgba(0, 0, 0, 0); color: rgb(31, 35, 40) !important; text-decoration: none;">#1680</a></div><a target="_parent" class="d-inline-block branch-name css-truncate css-truncate-target my-0 my-md-1" title="copilot/make-getimplicitpermissions-api-work" href="https://github.com/casbin/casbin/tree/refs/heads/copilot/make-getimplicitpermissions-api-work" style="box-sizing: border-box; background-color: rgb(221, 244, 255); color: rgb(9, 105, 218); text-decoration: none; margin-top: 4px !important; margin-bottom: 4px !important; display: inline-block; padding: 2px 6px; font: 400 12px &quot;Monaspace Neon&quot;, ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace; word-break: break-all; border-radius: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 200px; vertical-align: top;">copilot/make-getimplicitpermissions-api-work</a></div></div><div class="col mt-3 mr-3 mr-sm-6 ml-lg-3" style="box-sizing: border-box; margin-top: 16px !important; margin-right: 40px !important; margin-left: 16px !important; min-width: 72px;"><span class="mb-1 d-block text-small color-fg-muted" style="box-sizing: border-box; color: rgb(89, 99, 110) !important; margin-bottom: 4px !important; font-size: 12px !important; display: block !important;">Status</span><span class="h4 color-fg-default" style="box-sizing: border-box; color: rgb(31, 35, 40) !important; font-size: 16px !important; font-weight: 600 !important;">Failure</span></div><div class="col mt-3 mr-3 mr-sm-6 ml-lg-3" style="box-sizing: border-box; margin-top: 16px !important; margin-right: 40px !important; margin-left: 16px !important; min-width: 72px;"><span class="mb-1 d-block text-small color-fg-muted" style="box-sizing: border-box; color: rgb(89, 99, 110) !important; margin-bottom: 4px !important; font-size: 12px !important; display: block !important;">Total duration</span><a href="https://github.com/casbin/casbin/actions/runs/20878775866/usage" class="h4 Link--inTextBlock Link--primary color-fg-default" data-hotkey="g u" style="box-sizing: border-box; background-color: rgba(0, 0, 0, 0); color: rgb(31, 35, 40) !important; text-decoration: underline; font-size: 16px !important; font-weight: 600 !important; text-underline-offset: 0.2rem;">28s</a></div><div class="mt-3 ml-lg-3" style="box-sizing: border-box; margin-top: 16px !important; margin-left: 16px !important;"><span class="mb-1 d-block text-small color-fg-muted" style="box-sizing: border-box; color: rgb(89, 99, 110) !important; margin-bottom: 4px !important; font-size: 12px !important; display: block !important;">Artifacts</span><span class="h4 color-fg-default" style="box-sizing: border-box; color: rgb(31, 35, 40) !important; font-size: 16px !important; font-weight: 600 !important;">–</span></div></div></div><div class="d-none d-md-block" style="box-sizing: border-box; display: block !important; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div class="js-updatable-content js-socket-channel" data-channel="eyJjIjoid29ya2Zsb3dfcnVuOjIwODc4Nzc1ODY2OmdhdGUtcmVxdWVzdHMiLCJ0IjoxNzY4MDUyOTQ4fQ==--603edcc715a4027cbccfa7c83ca7d19654cb8ac9539b38e998f6356ef6640201" data-url="/casbin/casbin/actions/runs/20878775866/approvals_banner_partial" style="box-sizing: border-box;"></div></div><div class="d-none d-md-block" style="box-sizing: border-box; display: block !important; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"></div><div class="d-none d-md-block" style="box-sizing: border-box; display: block !important; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"></div><div class="js-updatable-content js-socket-channel" data-channel="eyJjIjoiY2hlY2tfc3VpdGVzOjU0MDMwNzE0MjgxIiwidCI6MTc2ODA1Mjk0OH0=--c5e2d3d06eb4656b71062079f071c9f213eb592c648b348ec4052e27113fd1e3" data-url="/casbin/casbin/actions/runs/20878775866/concurrency_banner_partial" style="box-sizing: border-box; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"></div><div class="d-block" style="box-sizing: border-box; display: block !important; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"></div><div role="region" aria-label="Workflow run graph" class="js-updatable-content js-socket-channel" data-channel="eyJjIjoid29ya2Zsb3dfcnVuOjIwODc4Nzc1ODY2OmV4ZWN1dGlvbiIsInQiOjE3NjgwNTI5NDl9--af36775ad0de17184f238a6506654821a7cbafd5159f0c47784153964425cab6" data-url="/casbin/casbin/actions/runs/20878775866/graph_partial" style="box-sizing: border-box; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><action-graph data-hpc="" data-catalyst="" style="box-sizing: border-box; display: block;"><div class="actions-fullwidth-module WorkflowGraph color-shadow-small mb-3 border rounded color-bg-inset overflow-hidden position-relative p-2 border-top-0 border-md-top" tabindex="0" data-target="action-graph.canvas" data-hydro-click="{&quot;event_type&quot;:&quot;actions.execution_graph_click&quot;,&quot;payload&quot;:{&quot;repository_id&quot;:87617508,&quot;session_id&quot;:&quot;1614165168&quot;,&quot;click_area&quot;:&quot;any&quot;,&quot;originating_url&quot;:&quot;https://github.com/casbin/casbin/actions/runs/20878775866?pr=1680&quot;,&quot;user_id&quot;:3787410}}" data-hydro-click-hmac="cd28000fc35da4c83b4d3bd6ab81daeddc85bee0ee5b51c330d75bd1452347e3" style="box-sizing: border-box; border-color: rgb(209, 217, 224) !important; border-style: solid !important; border-width: 1px !important; border-image: none 100% / 1 / 0 stretch !important; border-radius: 6px !important; box-shadow: rgba(31, 35, 40, 0.06) 0px 1px 1px 0px, rgba(31, 35, 40, 0.06) 0px 1px 3px 0px !important; background-color: rgb(246, 248, 250) !important; position: relative !important; overflow: hidden !important; margin-bottom: 16px !important; padding: 8px !important; cursor: grab; min-height: 200px; max-height: 600px;"><div class="d-flex flex-items-center flex-justify-between position-relative p-md-1 pb-md-2" style="box-sizing: border-box; justify-content: space-between !important; align-items: center !important; position: relative !important; padding: 4px 4px 8px !important; display: flex !important; touch-action: none; user-select: none;"><div class="p-2 color-bg-inset rounded position-relative" style="box-sizing: border-box; border-radius: 6px !important; background-color: rgb(246, 248, 250) !important; position: relative !important; padding: 8px !important; z-index: 1;"><h2 class="d-flex flex-items-center h4" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; font-size: 16px !important; font-weight: 600 !important; align-items: center !important; display: flex !important;"></h2></div></div><div class="width-full height-full position-relative px-2 mx-md-1" data-action="selectstart:action-graph#cancelEvent" style="box-sizing: border-box; position: relative !important; width: 1503px; height: 150px; margin-right: 4px !important; margin-left: 4px !important; padding-right: 8px !important; padding-left: 8px !important; touch-action: none; user-select: none; transform-origin: left top;"><div class="visual-graph" data-target="action-graph.visualGraph" data-x="0" data-y="0" style="box-sizing: border-box; transition: opacity 0.1s ease-out; opacity: 1; transform: translate(0px, 0px);"><div class="d-inline-flex flex-row position-relative" data-target="action-graph.stages" style="box-sizing: border-box; flex-direction: row !important; position: relative !important; display: inline-flex !important; transform-origin: left top; transform: scale(1);"><svg class="WorkflowConnectors position-absolute top-0 left-0" data-targets="action-graph.connectorLines" width="316" height="150" aria-hidden="true" fill="none"></svg><svg class="WorkflowConnectors position-absolute top-0 left-0 active" data-target="action-graph.connectorLineHighlights" data-targets="action-graph.connectorLines" width="316" height="150" aria-hidden="true" fill="none"></svg><div class="WorkflowStage d-inline-flex flex-column flex-items-center mr-6 my-4" style="box-sizing: border-box; flex-direction: column !important; align-items: center !important; margin-top: 24px !important; margin-bottom: 24px !important; margin-right: 56px !important; display: inline-flex !important;"><div id="group-_" class="WorkflowCard position-relative rounded-2 border mb-6 my-3" data-action="
    mouseenter:action-graph#mouseEnter
    mouseleave:action-graph#mouseLeave
  " style="box-sizing: border-box; border-color: rgb(209, 217, 224) !important; border-style: solid !important; border-width: 1px !important; border-image: none 100% / 1 / 0 stretch !important; border-radius: 6px !important; position: relative !important; margin-top: 16px !important; margin-bottom: 40px !important; z-index: 1; width: 260px; background-color: rgb(255, 255, 255); transition: background-color 0.12s ease-out, border-color 0.12s ease-out, box-shadow 0.12s ease-out;"><streaming-graph-job class="js-socket-channel WorkflowJob position-relative rounded-2 width-full" data-should-stream="casbin" data-external-id="a96e646b-c06f-5818-8ce0-70d2ec556e80" data-concluded="true" data-steps-from-results="" data-url="/casbin/casbin/actions/runs/20878775866/graph/job/golangci" data-action="socket:message:action-graph#updateJob" data-channel="eyJjIjoiYWN0aW9uc19yZXN1bHRzOjQwOGU2ZmQzLWFlZTAtNGI4NS05M2Q4LTFiOTUwOWEzZWY5YTphOTZlNjQ2Yi1jMDZmLTU4MTgtOGNlMC03MGQyZWM1NTZlODAiLCJ0IjoxNzY4MDUyOTQ5fQ==--d0ba9f4a5408dfba0fa274731d2f6febd18b07e99927525f5d32957edb70c177 eyJjIjoiY2hlY2tfcnVuczo1OTk5MjQzNTQyMiIsInQiOjE3NjgwNTI5NDl9--3d00d9da84db1b4be99551a39ef3da7697c2b814291cc792dc7992febafde148" data-targets="action-graph.jobs" data-job-id="golangci" data-group-id="group-_" data-streaming-url="" data-catalyst="" style="box-sizing: border-box; border-radius: 6px !important; position: relative !important; width: 258px; display: block; padding: 12px; transition: opacity 0.12s ease-out; font-size: 0px;"><a class="WorkflowJob-title d-flex flex-items-center no-underline f5 " id="workflow-job-name-golangci" href="https://github.com/casbin/casbin/actions/runs/20878775866/job/59992435422?pr=1680" tabindex="0" draggable="false" data-action="dragstart:action-graph#cancelEvent" data-hydro-click="{&quot;event_type&quot;:&quot;actions.execution_graph_click&quot;,&quot;payload&quot;:{&quot;repository_id&quot;:87617508,&quot;session_id&quot;:&quot;1614165168&quot;,&quot;click_area&quot;:&quot;job&quot;,&quot;originating_url&quot;:&quot;https://github.com/casbin/casbin/actions/runs/20878775866?pr=1680&quot;,&quot;user_id&quot;:3787410}}" data-hydro-click-hmac="41d633f740d5441e8dac177ff6929b9691ead6462e5f243a365d2e38fa8cccc0" data-turbo="false" aria-describedby="tooltip-e5ac85bf-5f73-4979-86de-74cb59ed197d" style="box-sizing: border-box; background-color: rgba(0, 0, 0, 0); color: rgb(9, 105, 218); text-decoration: none !important; align-items: center !important; font-size: 14px !important; display: flex !important; height: 20px; line-height: 20px;"><div class="width-full" style="box-sizing: border-box; width: 234px;"><div class="d-flex flex-auto flex-items-center no-wrap width-full" style="box-sizing: border-box; align-items: center !important; flex: 1 1 auto !important; width: 234px; white-space: nowrap !important; display: flex !important;"><div style="box-sizing: border-box;"></div><div data-view-component="true" class="min-width-0 flex-justify-start flex-nowrap css-truncate-overflow d-flex text-semibold color-fg-default pl-2 flex-1" style="box-sizing: border-box; color: rgb(31, 35, 40) !important; flex-wrap: nowrap !important; justify-content: flex-start !important; flex-grow: 1 !important; flex-shrink: 1 !important; flex-basis: 0%; min-width: 0px !important; padding-left: 8px !important; font-weight: 500 !important; display: flex !important;"></div></div></div></a></streaming-graph-job></div></div></div><div aria-hidden="true" class="position-absolute text-small" style="box-sizing: border-box; position: absolute !important; font-size: 12px !important; top: -200px; left: -4000px;"></div></div></div><div class="position-absolute bottom-0 right-0 mr-3 mb-3 pr-1 pb-1 d-flex gap-2" style="box-sizing: border-box; position: absolute !important; right: 0px !important; bottom: 0px !important; margin-bottom: 16px !important; margin-right: 16px !important; padding-right: 4px !important; padding-bottom: 4px !important; display: flex !important; gap: 8px !important;"><button data-action="click:action-graph#fit" data-target="action-graph.zoomFit" data-hydro-click="{&quot;event_type&quot;:&quot;actions.execution_graph_click&quot;,&quot;payload&quot;:{&quot;repository_id&quot;:87617508,&quot;session_id&quot;:&quot;1614165168&quot;,&quot;click_area&quot;:&quot;screen_full&quot;,&quot;originating_url&quot;:&quot;https://github.com/casbin/casbin/actions/runs/20878775866?pr=1680&quot;,&quot;user_id&quot;:3787410}}" data-hydro-click-hmac="f29e76168b1c58034cbcf04261e43da9eee4cfab7a6effbf45aa9020f607e513" id="icon-button-48ad2406-acb7-4783-9c58-d518bd607d07" aria-labelledby="tooltip-a4c54591-b381-435d-9cec-90c5c6be78eb" type="button" disabled="disabled" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--small" style="box-sizing: border-box; font-style: inherit; font-variant: inherit; font-weight: 500; font-stretch: inherit; font-size: 12px; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; margin: 0px; overflow: visible; text-transform: none; appearance: button; cursor: not-allowed; border-radius: 6px; align-items: center; background-color: rgb(239, 242, 245); border-style: solid; border-width: 1px; border-image: none 100% / 1 / 0 stretch; border-color: rgba(129, 139, 152, 0.1); color: rgb(129, 139, 152); display: inline-grid; flex-direction: row; gap: 4px; height: 28px; place-content: center; min-width: 28px; padding: unset; position: relative; text-align: center; transition: color 0.08s cubic-bezier(0.65, 0, 0.35, 1), fill, background-color, border-color; user-select: none; box-shadow: none; fill: rgb(129, 139, 152); width: 28px;"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-screen-full Button-visual"></svg></button><div data-view-component="true" class="ButtonGroup" style="box-sizing: border-box; display: inline-flex;"><div style="box-sizing: border-box;"><button data-action="click:action-graph#out" data-target="action-graph.zoomOut" data-hydro-click="{&quot;event_type&quot;:&quot;actions.execution_graph_click&quot;,&quot;payload&quot;:{&quot;repository_id&quot;:87617508,&quot;session_id&quot;:&quot;1614165168&quot;,&quot;click_area&quot;:&quot;zoom_out&quot;,&quot;originating_url&quot;:&quot;https://github.com/casbin/casbin/actions/runs/20878775866?pr=1680&quot;,&quot;user_id&quot;:3787410}}" data-hydro-click-hmac="f129afe2e26812c5bb01a43f8f4316b219530ffb0dec5419cbdd526e5ce9a583" id="icon-button-c4e908f3-9626-43f8-ae5b-926c077800c5" aria-labelledby="tooltip-6d8b6541-1f0e-4761-9971-c59446ff7fb8" type="button" disabled="" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--small" style="box-sizing: border-box; font-style: inherit; font-variant: inherit; font-weight: 500; font-stretch: inherit; font-size: 12px; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; margin: 0px; overflow: visible; text-transform: none; appearance: button; cursor: not-allowed; border-radius: 6px 0px 0px 6px; align-items: center; background-color: rgb(239, 242, 245); border-style: solid; border-width: 1px; border-image: none 100% / 1 / 0 stretch; border-color: rgba(129, 139, 152, 0.1); color: rgb(129, 139, 152); display: inline-grid; flex-direction: row; gap: 4px; height: 28px; place-content: center; min-width: 28px; padding: unset; position: relative; text-align: center; transition: color 0.08s cubic-bezier(0.65, 0, 0.35, 1), fill, background-color, border-color; user-select: none; box-shadow: none; fill: rgb(129, 139, 152); width: 28px; margin-inline-end: -1px;"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-dash Button-visual"></svg></button></div><div style="box-sizing: border-box;"><button data-action="click:action-graph#in" data-target="action-graph.zoomIn" data-hydro-click="{&quot;event_type&quot;:&quot;actions.execution_graph_click&quot;,&quot;payload&quot;:{&quot;repository_id&quot;:87617508,&quot;session_id&quot;:&quot;1614165168&quot;,&quot;click_area&quot;:&quot;zoom_in&quot;,&quot;originating_url&quot;:&quot;https://github.com/casbin/casbin/actions/runs/20878775866?pr=1680&quot;,&quot;user_id&quot;:3787410}}" data-hydro-click-hmac="ec339596b85c5fa3f3d73ebebfd444541e3f95a42a31dd4c8de8e169e219010c" id="icon-button-656e19c9-2a44-4890-8f81-c7ce2a4c41b2" aria-labelledby="tooltip-604e0911-1ffd-4371-9662-64ea6ab28adc" type="button" disabled="" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--small" style="box-sizing: border-box; font-style: inherit; font-variant: inherit; font-weight: 500; font-stretch: inherit; font-size: 12px; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; margin: 0px; overflow: visible; text-transform: none; appearance: button; cursor: not-allowed; border-radius: 0px 6px 6px 0px; align-items: center; background-color: rgb(239, 242, 245); border-style: solid; border-width: 1px; border-image: none 100% / 1 / 0 stretch; border-color: rgba(129, 139, 152, 0.1); color: rgb(129, 139, 152); display: inline-grid; flex-direction: row; gap: 4px; height: 28px; place-content: center; min-width: 28px; padding: unset; position: relative; text-align: center; transition: color 0.08s cubic-bezier(0.65, 0, 0.35, 1), fill, background-color, border-color; user-select: none; box-shadow: none; fill: rgb(129, 139, 152); width: 28px; margin-inline-end: -1px;"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-plus Button-visual"></svg></button></div></div></div></div></action-graph></div><job-summaries class="js-updatable-content js-socket-channel" data-retain-focus="" data-channel="eyJjIjoiY2hlY2tfc3VpdGVzOjU0MDMwNzE0MjgxIiwidCI6MTc2ODA1Mjk0OX0=--30c4a2be6f5e99d39f6834b10dbb97125f39a91d2a9e46f00da38df6dbdba4df" data-url="/casbin/casbin/actions/runs/20878775866/job_summary_partial" data-catalyst="" style="box-sizing: border-box; display: block; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><svg aria-hidden="true" width="100px" height="84px" viewBox="0 0 340 84" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="diff-placeholder-svg position-absolute bottom-0"><defs><clipPath id="diff-placeholder"><rect x="0" y="0" width="67.0175439" height="11.9298746" rx="2"></rect><rect x="18.9473684" y="47.7194983" width="100.701754" height="11.9298746" rx="2"></rect><rect x="0" y="71.930126" width="37.8947368" height="11.9298746" rx="2"></rect><rect x="127.017544" y="48.0703769" width="53.3333333" height="11.9298746" rx="2"></rect><rect x="187.719298" y="48.0703769" width="72.9824561" height="11.9298746" rx="2"></rect><rect x="76.8421053" y="0" width="140.350877" height="11.9298746" rx="2"></rect><rect x="17.8947368" y="23.8597491" width="140.350877" height="11.9298746" rx="2"></rect><rect x="166.315789" y="23.8597491" width="173.684211" height="11.9298746" rx="2"></rect></clipPath><linearGradient id="animated-diff-gradient" x1="0" x2="0" y1="0" y2="1" spreadMethod="reflect"></linearGradient></defs></svg></job-summaries><div class="js-updatable-content js-socket-channel" data-channel="eyJjIjoid29ya2Zsb3dfcnVuOjIwODc4Nzc1ODY2OmdhdGUtcmVxdWVzdHMiLCJ0IjoxNzY4MDUyOTQ5fQ==--a05212b7ad571b14cb6c81b8cfa371f01bde0d3fddf37d85f30bafe8d8541ff6 eyJjIjoid29ya2Zsb3dfcnVuOjIwODc4Nzc1ODY2OmFwcHJvdmFsLWxvZyIsInQiOjE3NjgwNTI5NDl9--ba9eed18d996a476a5f21d08b70d738065d00adc74bc1921240698800abfc3aa eyJjIjoid29ya2Zsb3dfcnVuOjIwODc4Nzc1ODY2OmV4ZWN1dGlvbiIsInQiOjE3NjgwNTI5NDl9--af36775ad0de17184f238a6506654821a7cbafd5159f0c47784153964425cab6" data-url="/casbin/casbin/actions/runs/20878775866/approvals_partial" style="box-sizing: border-box; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"></div><div role="region" aria-label="Annotations" class="js-updatable-content js-socket-channel" data-channel="eyJjIjoiY2hlY2tfc3VpdGVzOjU0MDMwNzE0MjgxIiwidCI6MTc2ODA1Mjk0OX0=--30c4a2be6f5e99d39f6834b10dbb97125f39a91d2a9e46f00da38df6dbdba4df" data-url="/casbin/casbin/actions/runs/20878775866/annotations_partial" style="box-sizing: border-box; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div class="actions-fullwidth-module color-bg-default color-shadow-small mb-3 pt-3 border rounded" style="box-sizing: border-box; border-color: rgb(209, 217, 224) !important; border-style: solid !important; border-width: 1px !important; border-image: none 100% / 1 / 0 stretch !important; border-radius: 6px !important; box-shadow: rgba(31, 35, 40, 0.06) 0px 1px 1px 0px, rgba(31, 35, 40, 0.06) 0px 1px 3px 0px !important; background-color: rgb(255, 255, 255) !important; margin-bottom: 16px !important; padding-top: 16px !important;"><div class="mt-1 mb-3 px-3" style="box-sizing: border-box; margin-top: 4px !important; margin-bottom: 16px !important; padding-right: 16px !important; padding-left: 16px !important;"><div class="mx-0 mx-md-1" style="box-sizing: border-box; margin-right: 4px !important; margin-left: 4px !important;"><h2 class="text-bold h4" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; font-size: 16px !important; font-weight: 600 !important;">Annotations</h2><div class="color-fg-muted text-small" style="box-sizing: border-box; color: rgb(89, 99, 110) !important; font-size: 12px !important;">7 errors and 2 warnings</div></div></div>
golangciissues found
--
golangci: rbac_api.go#L410`if rolesMap[policySubject]` has complex nested blocks (complexity: 6) (nestif)
golangci: rbac_api_complex_matcher_test.go#L36File is not `goimports`-ed (goimports)
golangci: rbac_api.go#L336File is not `goimports`-ed (goimports)
golangci: rbac_api_complex_matcher_test.go#L112Comment should end in a period (godot)
golangci: rbac_api.go#L432Comment should end in a period (godot)
golangci: rbac_api.go#L333Comment should end in a period (godot)

</div></div><!--EndFragment-->
</body>
</html>Re-run triggered 25 minutes ago
@[hsluoyz](https://github.com/hsluoyz)hsluoyz
https://github.com/casbin/casbin/pull/1680
[copilot/make-getimplicitpermissions-api-work](https://github.com/casbin/casbin/tree/refs/heads/copilot/make-getimplicitpermissions-api-work)
Status
Failure
Total duration
[28s](https://github.com/casbin/casbin/actions/runs/20878775866/usage)
Artifacts
–


Annotations
7 errors and 2 warnings
[golangci](https://github.com/casbin/casbin/actions/runs/20878775866/job/59992435422#step:4:32)
issues found
[golangci: rbac_api.go#L410](https://github.com/casbin/casbin/pull/1680/files#annotation_43946093971)
`if rolesMap[policySubject]` has complex nested blocks (complexity: 6) (nestif)
[golangci: rbac_api_complex_matcher_test.go#L36](https://github.com/casbin/casbin/pull/1680/files#annotation_43946093972)
File is not `goimports`-ed (goimports)
[golangci: rbac_api.go#L336](https://github.com/casbin/casbin/pull/1680/files#annotation_43946093973)
File is not `goimports`-ed (goimports)
[golangci: rbac_api_complex_matcher_test.go#L112](https://github.com/casbin/casbin/pull/1680/files#annotation_43946093975)
Comment should end in a period (godot)
[golangci: rbac_api.go#L432](https://github.com/casbin/casbin/pull/1680/files#annotation_43946093977)
Comment should end in a period (godot)
[golangci: rbac_api.go#L333](https://github.com/casbin/casbin/pull/1680/files#annotation_43946093980)
Comment should end in a period (godot)

Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 10, 2026

@copilot

fix:
...

Fixed in fda114e. The test failure was caused by test files using hardcoded /tmp/ paths which don't persist in CI. Moved the test model and policy files to the examples/ directory.

@hsluoyz
Copy link
Member

hsluoyz commented Jan 10, 2026

@copilot fix:

<html>
<body>
<!--StartFragment--><div class="mt-1 mb-3 px-3" style="box-sizing: border-box; margin-top: 4px !important; margin-bottom: 16px !important; padding-right: 16px !important; padding-left: 16px !important; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div class="mx-0 mx-md-1" style="box-sizing: border-box; margin-right: 4px !important; margin-left: 4px !important;"><h2 class="text-bold h4" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; font-size: 16px !important; font-weight: 600 !important;">Annotations</h2><div class="color-fg-muted text-small" style="box-sizing: border-box; color: rgb(89, 99, 110) !important; font-size: 12px !important;">7 errors and 2 warnings</div></div></div>
golangciissues found
--
golangci: rbac_api.go#L410`if rolesMap[policySubject]` has complex nested blocks (complexity: 6) (nestif)
golangci: rbac_api_complex_matcher_test.go#L36File is not `goimports`-ed (goimports)
golangci: rbac_api.go#L336File is not `goimports`-ed (goimports)
golangci: rbac_api_complex_matcher_test.go#L112Comment should end in a period (godot)
golangci: rbac_api.go#L432Comment should end in a period (godot)
golangci: rbac_api.go#L333Comment should end in a period (godot)

<!--EndFragment-->
</body>
</html>Annotations
7 errors and 2 warnings
[golangci](https://github.com/casbin/casbin/actions/runs/20879323982/job/59997348559#step:4:32)
issues found
[golangci: rbac_api.go#L410](https://github.com/casbin/casbin/pull/1680/files#annotation_43948568984)
`if rolesMap[policySubject]` has complex nested blocks (complexity: 6) (nestif)
[golangci: rbac_api_complex_matcher_test.go#L36](https://github.com/casbin/casbin/pull/1680/files#annotation_43948568987)
File is not `goimports`-ed (goimports)
[golangci: rbac_api.go#L336](https://github.com/casbin/casbin/pull/1680/files#annotation_43948568988)
File is not `goimports`-ed (goimports)
[golangci: rbac_api_complex_matcher_test.go#L112](https://github.com/casbin/casbin/pull/1680/files#annotation_43948568990)
Comment should end in a period (godot)
[golangci: rbac_api.go#L432](https://github.com/casbin/casbin/pull/1680/files#annotation_43948568991)
Comment should end in a period (godot)
[golangci: rbac_api.go#L333](https://github.com/casbin/casbin/pull/1680/files#annotation_43948568993)
Comment should end in a period (godot)

…rmat with goimports

Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 10, 2026

@copilot fix:

...

Fixed in cc163ba. Addressed all golangci-lint issues:

  • Added periods to comments (godot)
  • Reduced nesting complexity from 6 to 3 by using early returns (nestif)
  • Formatted files with goimports (goimports)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] make GetImplicitPermissionsForUser() API work for all cases

3 participants