@@ -194,33 +194,26 @@ func showAccessOnEntity(ctx *ExecContext, name *ast.QualifiedName) error {
194194 return mdlerrors .NewNotFound ("entity" , name .String ())
195195 }
196196
197- if len (entity .AccessRules ) == 0 {
198- fmt .Fprintf (ctx .Output , "No access rules on %s\n " , name )
199- return nil
200- }
201-
202- // Build attribute name map
197+ // Build attribute name map (shared by both output paths)
203198 attrNames := make (map [string ]string )
204199 for _ , attr := range entity .Attributes {
205200 attrNames [string (attr .ID )] = attr .Name
206201 }
207202
208- fmt .Fprintf (ctx .Output , "Access rules for %s.%s:\n \n " , name .Module , name .Name )
209-
210- for i , rule := range entity .AccessRules {
211- // Show roles
212- var roleStrs []string
213- for _ , rn := range rule .ModuleRoleNames {
214- roleStrs = append (roleStrs , rn )
203+ // ruleRoles returns the role name list for a rule.
204+ ruleRoles := func (rule * domainmodel.AccessRule ) []string {
205+ if len (rule .ModuleRoleNames ) > 0 {
206+ return rule .ModuleRoleNames
215207 }
216- if len (roleStrs ) == 0 {
217- for _ , rid := range rule .ModuleRoles {
218- roleStrs = append (roleStrs , string (rid ))
219- }
208+ var out []string
209+ for _ , rid := range rule .ModuleRoles {
210+ out = append (out , string (rid ))
220211 }
221- fmt .Fprintf (ctx .Output , "Rule %d: %s\n " , i + 1 , strings .Join (roleStrs , ", " ))
212+ return out
213+ }
222214
223- // Show CRUD rights (READ/WRITE inferred from DefaultMemberAccessRights + MemberAccesses)
215+ // ruleRights computes CRUD rights for a rule.
216+ ruleRights := func (rule * domainmodel.AccessRule ) []string {
224217 var rights []string
225218 if rule .AllowCreate {
226219 rights = append (rights , "CREATE" )
@@ -245,30 +238,63 @@ func showAccessOnEntity(ctx *ExecContext, name *ast.QualifiedName) error {
245238 if rule .AllowDelete {
246239 rights = append (rights , "DELETE" )
247240 }
248- fmt .Fprintf (ctx .Output , " Rights: %s\n " , strings .Join (rights , ", " ))
241+ return rights
242+ }
243+
244+ // memberName resolves display name for a MemberAccess entry.
245+ memberName := func (ma * domainmodel.MemberAccess ) string {
246+ if ma .AttributeName != "" {
247+ return ma .AttributeName
248+ }
249+ if ma .AssociationName != "" {
250+ return ma .AssociationName
251+ }
252+ if an , ok := attrNames [string (ma .AttributeID )]; ok {
253+ return an
254+ }
255+ return string (ma .AttributeID )
256+ }
257+
258+ if ctx .Format == FormatJSON {
259+ result := & TableResult {
260+ Columns : []string {"Rule" , "Roles" , "Rights" , "DefaultMemberAccess" , "MemberAccess" , "XPath" },
261+ }
262+ for i , rule := range entity .AccessRules {
263+ var memberParts []string
264+ for _ , ma := range rule .MemberAccesses {
265+ memberParts = append (memberParts , memberName (ma )+ ":" + string (ma .AccessRights ))
266+ }
267+ result .Rows = append (result .Rows , []any {
268+ i + 1 ,
269+ strings .Join (ruleRoles (rule ), ", " ),
270+ strings .Join (ruleRights (rule ), ", " ),
271+ string (rule .DefaultMemberAccessRights ),
272+ strings .Join (memberParts , ", " ),
273+ rule .XPathConstraint ,
274+ })
275+ }
276+ return writeResult (ctx , result )
277+ }
278+
279+ if len (entity .AccessRules ) == 0 {
280+ fmt .Fprintf (ctx .Output , "No access rules on %s\n " , name )
281+ return nil
282+ }
283+
284+ fmt .Fprintf (ctx .Output , "Access rules for %s.%s:\n \n " , name .Module , name .Name )
285+
286+ for i , rule := range entity .AccessRules {
287+ fmt .Fprintf (ctx .Output , "Rule %d: %s\n " , i + 1 , strings .Join (ruleRoles (rule ), ", " ))
288+ fmt .Fprintf (ctx .Output , " Rights: %s\n " , strings .Join (ruleRights (rule ), ", " ))
249289
250- // Show default member access
251290 if rule .DefaultMemberAccessRights != "" {
252291 fmt .Fprintf (ctx .Output , " Default member access: %s\n " , rule .DefaultMemberAccessRights )
253292 }
254293
255- // Show member-level access
256294 for _ , ma := range rule .MemberAccesses {
257- memberName := ma .AttributeName
258- if memberName == "" {
259- memberName = ma .AssociationName
260- }
261- if memberName == "" {
262- if an , ok := attrNames [string (ma .AttributeID )]; ok {
263- memberName = an
264- } else {
265- memberName = string (ma .AttributeID )
266- }
267- }
268- fmt .Fprintf (ctx .Output , " %s: %s\n " , memberName , ma .AccessRights )
295+ fmt .Fprintf (ctx .Output , " %s: %s\n " , memberName (ma ), ma .AccessRights )
269296 }
270297
271- // Show XPath constraint
272298 if rule .XPathConstraint != "" {
273299 fmt .Fprintf (ctx .Output , " WHERE '%s'\n " , rule .XPathConstraint )
274300 }
0 commit comments