• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

casbin / Casbin.NET / 65

07 Nov 2025 02:38PM UTC coverage: 60.678% (-0.04%) from 60.72%
65

push

github

web-flow
fix: respect AutoSave flag for grouping policy operations (#395)

3205 of 5282 relevant lines covered (60.68%)

36278.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.51
/Casbin/Extensions/Model/ModelExtension.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Threading.Tasks;
4
using Casbin.Functions;
5
using Casbin.Persist;
6
using Casbin.Rbac;
7

8
namespace Casbin.Model
9
{
10
    public static class ModelExtension
11
    {
12
        public static bool SortPolicy(this IModel model)
13
        {
14
            string value = model.Sections.GetValue(PermConstants.Section.PolicyEffectSection,
340✔
15
                PermConstants.DefaultPolicyEffectType);
340✔
16
            switch (value)
17
            {
18
                case PermConstants.PolicyEffect.Priority:
19
                case PermConstants.PolicyEffect.PriorityDenyOverride:
20
                    return model.PolicyStoreHolder.PolicyStore.SortPolicyByPriority(PermConstants.Section.PolicySection,
12✔
21
                        PermConstants.DefaultPolicyType);
12✔
22
                case PermConstants.PolicyEffect.SubjectPriority:
23
                    Dictionary<string, int> map = model.Sections.GetRoleAssertion(PermConstants.DefaultRoleType)
4✔
24
                        .GetSubjectHierarchyMap();
4✔
25
                    return model.PolicyStoreHolder.PolicyStore.SortPolicyBySubjectHierarchy(
4✔
26
                        PermConstants.Section.PolicySection,
4✔
27
                        PermConstants.DefaultPolicyType, map);
4✔
28
                default:
29
                    return false;
324✔
30
            }
31
        }
32

33
        public static bool LoadPolicy(this IModel model)
34
        {
35
            if (model.AdapterHolder.Adapter is null)
188✔
36
            {
37
                return false;
133✔
38
            }
39

40
            if (model.AdapterHolder.EpochAdapter is null)
55✔
41
            {
42
                return false;
×
43
            }
44

45
            DefaultPolicyStore policyStore = new();
55✔
46
            foreach (KeyValuePair<string, PolicyAssertion> pair in model.Sections.GetPolicyAssertions())
220✔
47
            {
48
                policyStore.AddNode(PermConstants.Section.PolicySection, pair.Key, pair.Value);
55✔
49
            }
50

51
            if (model.Sections.ContainsSection(PermConstants.Section.RoleSection))
55✔
52
            {
53
                foreach (KeyValuePair<string, RoleAssertion> pair in model.Sections.GetRoleAssertions())
114✔
54
                {
55
                    policyStore.AddNode(PermConstants.Section.RoleSection, pair.Key, pair.Value);
29✔
56
                }
57
            }
58

59
            model.AdapterHolder.EpochAdapter.LoadPolicy(policyStore);
55✔
60
            model.PolicyStoreHolder.PolicyStore = policyStore;
55✔
61
            return true;
55✔
62
        }
63

64
        public static async Task<bool> LoadPolicyAsync(this IModel model)
65
        {
66
            if (model.AdapterHolder.Adapter is null)
9✔
67
            {
68
                return false;
×
69
            }
70

71
            if (model.AdapterHolder.EpochAdapter is null)
9✔
72
            {
73
                return false;
×
74
            }
75

76
            DefaultPolicyStore policyStore = new();
9✔
77
            foreach (KeyValuePair<string, PolicyAssertion> pair in model.Sections.GetPolicyAssertions())
36✔
78
            {
79
                policyStore.AddNode(PermConstants.Section.PolicySection, pair.Key, pair.Value);
9✔
80
            }
81

82
            if (model.Sections.ContainsSection(PermConstants.Section.RoleSection))
9✔
83
            {
84
                foreach (KeyValuePair<string, RoleAssertion> pair in model.Sections.GetRoleAssertions())
4✔
85
                {
86
                    policyStore.AddNode(PermConstants.Section.RoleSection, pair.Key, pair.Value);
1✔
87
                }
88
            }
89

90
            await model.AdapterHolder.EpochAdapter.LoadPolicyAsync(policyStore);
9✔
91
            model.PolicyStoreHolder.PolicyStore = policyStore;
9✔
92
            return true;
9✔
93
        }
9✔
94

95
        public static bool LoadFilteredPolicy(this IModel model, IPolicyFilter filter)
96
        {
97
            model.PolicyStoreHolder.PolicyStore?.ClearPolicy();
7✔
98
            return LoadFilteredPolicyInternal(model, filter);
7✔
99
        }
100

101
        public static async Task<bool> LoadFilteredPolicyAsync(this IModel model, IPolicyFilter filter)
102
        {
103
            model.PolicyStoreHolder.PolicyStore?.ClearPolicy();
7✔
104
            return await LoadFilteredPolicyInternalAsync(model, filter);
7✔
105
        }
7✔
106

107
        public static bool LoadIncrementalFilteredPolicy(this IModel model, IPolicyFilter filter)
108
        {
109
            return LoadFilteredPolicyInternal(model, filter);
3✔
110
        }
111

112
        public static async Task<bool> LoadIncrementalFilteredPolicyAsync(this IModel model, IPolicyFilter filter)
113
        {
114
            return await LoadFilteredPolicyInternalAsync(model, filter);
3✔
115
        }
3✔
116

117
        private static bool LoadFilteredPolicyInternal(IModel model, IPolicyFilter filter)
118
        {
119
            if (model.AdapterHolder.Adapter is null)
10✔
120
            {
121
                return false;
×
122
            }
123

124
            if (model.AdapterHolder.FilteredAdapter is null)
10✔
125
            {
126
                return false;
×
127
            }
128

129
            // Initialize policy store if it doesn't exist
130
            if (model.PolicyStoreHolder.PolicyStore is null)
10✔
131
            {
132
                DefaultPolicyStore policyStore = new();
×
133
                foreach (KeyValuePair<string, PolicyAssertion> pair in model.Sections.GetPolicyAssertions())
×
134
                {
135
                    policyStore.AddNode(PermConstants.Section.PolicySection, pair.Key, pair.Value);
×
136
                }
137

138
                if (model.Sections.ContainsSection(PermConstants.Section.RoleSection))
×
139
                {
140
                    foreach (KeyValuePair<string, RoleAssertion> pair in model.Sections.GetRoleAssertions())
×
141
                    {
142
                        policyStore.AddNode(PermConstants.Section.RoleSection, pair.Key, pair.Value);
×
143
                    }
144
                }
145
                model.PolicyStoreHolder.PolicyStore = policyStore;
×
146
            }
147

148
            model.AdapterHolder.FilteredAdapter.LoadFilteredPolicy(model.PolicyStoreHolder.PolicyStore, filter);
10✔
149
            return true;
10✔
150
        }
151

152
        private static async Task<bool> LoadFilteredPolicyInternalAsync(IModel model, IPolicyFilter filter)
153
        {
154
            if (model.AdapterHolder.Adapter is null)
10✔
155
            {
156
                return false;
×
157
            }
158

159
            if (model.AdapterHolder.FilteredAdapter is null)
10✔
160
            {
161
                return false;
×
162
            }
163

164
            // Initialize policy store if it doesn't exist
165
            if (model.PolicyStoreHolder.PolicyStore is null)
10✔
166
            {
167
                DefaultPolicyStore policyStore = new();
×
168
                foreach (KeyValuePair<string, PolicyAssertion> pair in model.Sections.GetPolicyAssertions())
×
169
                {
170
                    policyStore.AddNode(PermConstants.Section.PolicySection, pair.Key, pair.Value);
×
171
                }
172

173
                if (model.Sections.ContainsSection(PermConstants.Section.RoleSection))
×
174
                {
175
                    foreach (KeyValuePair<string, RoleAssertion> pair in model.Sections.GetRoleAssertions())
×
176
                    {
177
                        policyStore.AddNode(PermConstants.Section.RoleSection, pair.Key, pair.Value);
×
178
                    }
179
                }
180
                model.PolicyStoreHolder.PolicyStore = policyStore;
×
181
            }
182

183
            await model.AdapterHolder.FilteredAdapter.LoadFilteredPolicyAsync(model.PolicyStoreHolder.PolicyStore, filter);
10✔
184
            return true;
10✔
185
        }
10✔
186

187
        public static bool SavePolicy(this IModel model)
188
        {
189
            if (model.AdapterHolder.Adapter is null)
4✔
190
            {
191
                return false;
×
192
            }
193

194
            if (model.AdapterHolder.EpochAdapter is null)
4✔
195
            {
196
                throw new InvalidOperationException("Cannot save policy when use a readonly adapter");
×
197
            }
198

199
            if (model.AdapterHolder.FilteredAdapter is not null && model.AdapterHolder.FilteredAdapter.IsFiltered)
4✔
200
            {
201
                throw new InvalidOperationException("Cannot save filtered policies");
×
202
            }
203

204
            model.AdapterHolder.EpochAdapter.SavePolicy(model.PolicyStoreHolder.PolicyStore);
4✔
205
            return true;
4✔
206
        }
207

208
        public static async Task<bool> SavePolicyAsync(this IModel model)
209
        {
210
            if (model.AdapterHolder.Adapter is null)
4✔
211
            {
212
                return false;
×
213
            }
214

215
            if (model.AdapterHolder.EpochAdapter is null)
4✔
216
            {
217
                throw new InvalidOperationException("Cannot save policy when use a readonly adapter");
×
218
            }
219

220
            if (model.AdapterHolder.FilteredAdapter is not null && model.AdapterHolder.FilteredAdapter.IsFiltered)
4✔
221
            {
222
                throw new InvalidOperationException("Cannot save filtered policies");
×
223
            }
224

225
            await model.AdapterHolder.EpochAdapter.SavePolicyAsync(model.PolicyStoreHolder.PolicyStore);
4✔
226
            return true;
4✔
227
        }
4✔
228

229
        public static void SetAutoSave(this IModel model, bool autoSave)
230
        {
231
            // Set AutoSave for policy assertions (section "p")
232
            foreach (KeyValuePair<string, PolicyAssertion> pair in model.Sections.GetPolicyAssertions())
24✔
233
            {
234
                pair.Value.PolicyManager.AutoSave = autoSave;
6✔
235
            }
236

237
            // Set AutoSave for role/grouping assertions (section "g") if they exist
238
            if (model.Sections.ContainsSection(PermConstants.Section.RoleSection))
6✔
239
            {
240
                foreach (KeyValuePair<string, RoleAssertion> pair in model.Sections.GetRoleAssertions())
8✔
241
                {
242
                    pair.Value.PolicyManager.AutoSave = autoSave;
2✔
243
                }
244
            }
245
        }
6✔
246

247
        public static IPolicyManager GetPolicyManager(this IModel model, string section,
248
            string policyType = PermConstants.DefaultPolicyType) =>
249
            model.Sections.GetPolicyAssertion(section, policyType).PolicyManager;
5,269✔
250

251
        public static IRoleManager
252
            GetRoleManager(this IModel model, string roleType = PermConstants.DefaultRoleType) =>
253
            model.Sections.GetRoleAssertion(roleType).RoleManager;
206✔
254

255
        public static void SetRoleManager(this IModel model, string roleType, IRoleManager roleManager)
256
        {
257
            RoleAssertion assertion = model.Sections.GetRoleAssertion(roleType);
5✔
258
            assertion.RoleManager = roleManager;
5✔
259
            model.EnforceCache.Clear();
5✔
260
            model.GFunctionCachePool.Clear(roleType);
5✔
261
            model.ExpressionHandler.SetFunction(roleType, BuiltInFunctions.GenerateGFunction(
5✔
262
                assertion.RoleManager, model.GFunctionCachePool.GetCache(roleType)));
5✔
263
        }
5✔
264

265
        /// <summary>
266
        ///     Initializes the roles in RBAC.
267
        /// </summary>
268
        public static void BuildRoleLinks(this IModel model, string roleType = null)
269
        {
270
            if (model.Sections.ContainsSection(PermConstants.Section.RoleSection) is false)
131✔
271
            {
272
                return;
39✔
273
            }
274

275
            if (roleType is not null)
92✔
276
            {
277
                RoleAssertion assertion = model.Sections.GetRoleAssertion(roleType);
×
278
                assertion.RoleManager.Clear();
×
279
                assertion.BuildRoleLinks();
×
280
                model.GFunctionCachePool.Clear(roleType);
×
281
                return;
×
282
            }
283

284
            foreach (KeyValuePair<string, RoleAssertion> pair in model.Sections.GetRoleAssertions())
390✔
285
            {
286
                string name = pair.Key;
103✔
287
                RoleAssertion assertion = pair.Value;
103✔
288
                assertion.RoleManager.Clear();
103✔
289
                model.GFunctionCachePool.Clear(name);
103✔
290
            }
291

292
            foreach (KeyValuePair<string, RoleAssertion> pair in model.Sections.GetRoleAssertions())
390✔
293
            {
294
                RoleAssertion assertion = pair.Value;
103✔
295
                assertion.BuildRoleLinks();
103✔
296
            }
297
        }
92✔
298

299
        /// <summary>
300
        ///     Provides incremental build the role inheritance relation.
301
        /// </summary>
302
        /// <param name="model"></param>
303
        /// <param name="policyOperation"></param>
304
        /// <param name="roleType"></param>
305
        /// <param name="rule"></param>
306
        public static void BuildIncrementalRoleLink(this IModel model, PolicyOperation policyOperation,
307
            string roleType, IPolicyValues rule)
308
        {
309
            if (model.Sections.ContainsSection(PermConstants.Section.RoleSection) is false)
61✔
310
            {
311
                return;
×
312
            }
313

314
            RoleAssertion assertion = model.Sections.GetRoleAssertion(roleType);
61✔
315
            assertion.BuildIncrementalRoleLink(policyOperation, rule);
61✔
316
            model.GFunctionCachePool.Clear(roleType);
61✔
317
        }
61✔
318

319
        /// <summary>
320
        ///     Provides incremental build the role inheritance relation.
321
        /// </summary>
322
        /// <param name="model"></param>
323
        /// <param name="policyOperation"></param>
324
        /// <param name="roleType"></param>
325
        /// <param name="oldRule"></param>
326
        /// <param name="newRule"></param>
327
        public static void BuildIncrementalRoleLink(this IModel model, PolicyOperation policyOperation,
328
            string roleType, IPolicyValues oldRule, IPolicyValues newRule)
329
        {
330
            if (model.Sections.ContainsSection(PermConstants.Section.RoleSection) is false)
4✔
331
            {
332
                return;
×
333
            }
334

335
            RoleAssertion assertion = model.Sections.GetRoleAssertion(roleType);
4✔
336
            assertion.BuildIncrementalRoleLink(policyOperation, oldRule, newRule);
4✔
337
            model.GFunctionCachePool.Clear(roleType);
4✔
338
        }
4✔
339

340
        /// <summary>
341
        ///     Provides incremental build the role inheritance relations.
342
        /// </summary>
343
        /// <param name="model"></param>
344
        /// <param name="policyOperation"></param>
345
        /// <param name="roleType"></param>
346
        /// <param name="rules"></param>
347
        public static void BuildIncrementalRoleLinks(this IModel model, PolicyOperation policyOperation,
348
            string roleType, IEnumerable<IPolicyValues> rules)
349
        {
350
            if (model.Sections.ContainsSection(PermConstants.Section.RoleSection) is false)
1,022✔
351
            {
352
                return;
×
353
            }
354

355
            RoleAssertion assertion = model.Sections.GetRoleAssertion(roleType);
1,022✔
356
            assertion.BuildIncrementalRoleLinks(policyOperation, rules);
1,022✔
357
            model.GFunctionCachePool.Clear(roleType);
1,022✔
358
        }
1,022✔
359

360
        /// <summary>
361
        ///     Provides incremental build the role inheritance relations.
362
        /// </summary>
363
        /// <param name="model"></param>
364
        /// <param name="policyOperation"></param>
365
        /// <param name="roleType"></param>
366
        /// <param name="oldRules"></param>
367
        /// <param name="newRules"></param>
368
        public static void BuildIncrementalRoleLinks(this IModel model, PolicyOperation policyOperation,
369
            string roleType, IEnumerable<IPolicyValues> oldRules, IEnumerable<IPolicyValues> newRules)
370
        {
371
            if (model.Sections.ContainsSection(PermConstants.Section.RoleSection) is false)
2✔
372
            {
373
                return;
×
374
            }
375

376
            RoleAssertion assertion = model.Sections.GetRoleAssertion(roleType);
2✔
377
            assertion.BuildIncrementalRoleLinks(policyOperation, oldRules, newRules);
2✔
378
            model.GFunctionCachePool.Clear(roleType);
2✔
379
        }
2✔
380
    }
381
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc