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

me-viper / OpaDotNet.Extensions / 6456985396

09 Oct 2023 07:32AM UTC coverage: 86.322% (-1.3%) from 87.664%
6456985396

push

github

me-viper
feat: Improve custom built-ins handling

81 of 108 branches covered (0.0%)

Branch coverage included in aggregate %.

59 of 59 new or added lines in 3 files covered. (100.0%)

487 of 550 relevant lines covered (88.55%)

2453.56 hits per line

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

81.67
/src/OpaDotNet.Extensions.AspNetCore/ConfigurationPolicySource.cs
1
using JetBrains.Annotations;
2

3
using Microsoft.Extensions.Options;
4

5
using OpaDotNet.Compilation.Abstractions;
6

7
namespace OpaDotNet.Extensions.AspNetCore;
8

9
[UsedImplicitly]
10
public class ConfigurationPolicySource : OpaPolicySource
11
{
12
    private readonly IDisposable? _policyChangeMonitor;
13

14
    private OpaPolicyOptions _opts;
15

16
    public ConfigurationPolicySource(
17
        IRegoCompiler compiler,
18
        IOptions<OpaAuthorizationOptions> authOptions,
19
        IOptionsMonitor<OpaPolicyOptions> policy,
20
        IOpaImportsAbiFactory importsAbiFactory,
21
        ILoggerFactory loggerFactory) : base(compiler, authOptions, importsAbiFactory, loggerFactory)
5✔
22
    {
5✔
23
        ArgumentNullException.ThrowIfNull(policy);
5✔
24

25
        _opts = policy.CurrentValue;
5✔
26
        _policyChangeMonitor = policy.OnChange(
5✔
27
            p =>
5✔
28
            {
3✔
29
                try
5✔
30
                {
3✔
31
                    if (!HasChanged(p, _opts))
3!
32
                    {
×
33
                        Logger.LogDebug("No changes in policies configuration");
×
34
                        return;
×
35
                    }
5✔
36

5✔
37
                    _opts = p;
3✔
38
                    Task.Run(() => CompileBundle(true)).ConfigureAwait(false);
6✔
39
                }
3✔
40
                catch (Exception)
×
41
                {
×
42
                    // ignored
5✔
43
                }
×
44
            }
3✔
45
            );
5✔
46
    }
5✔
47

48
    private static bool HasChanged(OpaPolicyOptions a, OpaPolicyOptions b)
49
    {
3✔
50
        if (ReferenceEquals(a, b))
3!
51
            return false;
×
52

53
        if (a.Keys.Count != b.Keys.Count)
3!
54
            return true;
×
55

56
        foreach (var (k, v) in a)
12!
57
        {
3✔
58
            if (!b.TryGetValue(k, out var ov))
3!
59
                return true;
×
60

61
            if (!v.Equals(ov))
3!
62
                return true;
3✔
63
        }
×
64

65
        return false;
×
66
    }
3✔
67

68
    /// <inheritdoc />
69
    protected override async Task<Stream?> CompileBundleFromSource(bool recompiling, CancellationToken cancellationToken = default)
70
    {
8✔
71
        var hasSources = false;
8✔
72
        using var ms = new MemoryStream();
8✔
73
        var bundleWriter = new BundleWriter(ms);
8✔
74

75
        await using (bundleWriter.ConfigureAwait(false))
8✔
76
        {
8✔
77
            foreach (var (name, policy) in _opts)
50✔
78
            {
13✔
79
                if (!string.IsNullOrWhiteSpace(policy.DataJson))
13✔
80
                    bundleWriter.WriteEntry(policy.DataJson, $"/{policy.Package}/data.json");
4✔
81

82
                if (!string.IsNullOrWhiteSpace(policy.DataYaml))
13✔
83
                    bundleWriter.WriteEntry(policy.DataYaml, $"/{policy.Package}/data.yaml");
6✔
84

85
                if (!string.IsNullOrWhiteSpace(policy.Source))
13✔
86
                {
13✔
87
                    hasSources = true;
13✔
88
                    bundleWriter.WriteEntry(policy.Source, $"/{policy.Package}/{name}.rego");
13✔
89
                }
13✔
90
            }
13✔
91
        }
8✔
92

93
        if (!hasSources)
8✔
94
            throw new RegoCompilationException("Configuration has no policies defined");
1✔
95

96
        ms.Seek(0, SeekOrigin.Begin);
7✔
97

98
        Stream? capsStream = null;
7✔
99

100
        try
101
        {
7✔
102
            if (ImportsAbiFactory.Capabilities != null)
7!
103
                capsStream = ImportsAbiFactory.Capabilities.Invoke();
×
104

105
            var result = await Compiler.Compile(
7✔
106
                ms,
7✔
107
                new()
7✔
108
                {
7✔
109
                    IsBundle = true,
7✔
110
                    Entrypoints = Options.Value.Entrypoints,
7✔
111
                    CapabilitiesStream = capsStream,
7✔
112
                },
7✔
113
                cancellationToken: cancellationToken
7✔
114
                ).ConfigureAwait(false);
7✔
115

116
            return result;
7✔
117
        }
118
        finally
119
        {
7✔
120
            if (capsStream != null)
7!
121
                await capsStream.DisposeAsync().ConfigureAwait(false);
×
122
        }
7✔
123
    }
7✔
124

125
    /// <inheritdoc />
126
    protected override void Dispose(bool disposing)
127
    {
5✔
128
        try
129
        {
5✔
130
            if (disposing)
5✔
131
                _policyChangeMonitor?.Dispose();
5!
132
        }
5✔
133
        finally
134
        {
5✔
135
            base.Dispose(disposing);
5✔
136
        }
5✔
137
    }
5✔
138
}
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