kanidm/docs/v1.0.0rc9/rustdoc/src/kanidmd_lib/plugins/dyngroup.rs.html
2022-10-13 01:24:08 +00:00

1850 lines
123 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `kanidmd/lib/src/plugins/dyngroup.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>dyngroup.rs - source</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" type="text/css" href="../../../normalize.css"><link rel="stylesheet" type="text/css" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../../ayu.css" disabled><link rel="stylesheet" type="text/css" href="../../../dark.css" disabled><link rel="stylesheet" type="text/css" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../source-script.js"></script><script defer src="../../../source-files.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc source"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle">&#9776;</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a></nav><main><div class="width-limiter"><div class="sub-container"><a class="sub-logo-container" href="../../../kanidmd_lib/index.html"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></a><nav class="sub"><form class="search-form"><div class="search-container"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><button type="button">?</button></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></div></form></nav></div><section id="main-content" class="content"><div class="example-wrap"><pre class="line-numbers"><span id="1">1</span>
<span id="2">2</span>
<span id="3">3</span>
<span id="4">4</span>
<span id="5">5</span>
<span id="6">6</span>
<span id="7">7</span>
<span id="8">8</span>
<span id="9">9</span>
<span id="10">10</span>
<span id="11">11</span>
<span id="12">12</span>
<span id="13">13</span>
<span id="14">14</span>
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
<span id="20">20</span>
<span id="21">21</span>
<span id="22">22</span>
<span id="23">23</span>
<span id="24">24</span>
<span id="25">25</span>
<span id="26">26</span>
<span id="27">27</span>
<span id="28">28</span>
<span id="29">29</span>
<span id="30">30</span>
<span id="31">31</span>
<span id="32">32</span>
<span id="33">33</span>
<span id="34">34</span>
<span id="35">35</span>
<span id="36">36</span>
<span id="37">37</span>
<span id="38">38</span>
<span id="39">39</span>
<span id="40">40</span>
<span id="41">41</span>
<span id="42">42</span>
<span id="43">43</span>
<span id="44">44</span>
<span id="45">45</span>
<span id="46">46</span>
<span id="47">47</span>
<span id="48">48</span>
<span id="49">49</span>
<span id="50">50</span>
<span id="51">51</span>
<span id="52">52</span>
<span id="53">53</span>
<span id="54">54</span>
<span id="55">55</span>
<span id="56">56</span>
<span id="57">57</span>
<span id="58">58</span>
<span id="59">59</span>
<span id="60">60</span>
<span id="61">61</span>
<span id="62">62</span>
<span id="63">63</span>
<span id="64">64</span>
<span id="65">65</span>
<span id="66">66</span>
<span id="67">67</span>
<span id="68">68</span>
<span id="69">69</span>
<span id="70">70</span>
<span id="71">71</span>
<span id="72">72</span>
<span id="73">73</span>
<span id="74">74</span>
<span id="75">75</span>
<span id="76">76</span>
<span id="77">77</span>
<span id="78">78</span>
<span id="79">79</span>
<span id="80">80</span>
<span id="81">81</span>
<span id="82">82</span>
<span id="83">83</span>
<span id="84">84</span>
<span id="85">85</span>
<span id="86">86</span>
<span id="87">87</span>
<span id="88">88</span>
<span id="89">89</span>
<span id="90">90</span>
<span id="91">91</span>
<span id="92">92</span>
<span id="93">93</span>
<span id="94">94</span>
<span id="95">95</span>
<span id="96">96</span>
<span id="97">97</span>
<span id="98">98</span>
<span id="99">99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
<span id="162">162</span>
<span id="163">163</span>
<span id="164">164</span>
<span id="165">165</span>
<span id="166">166</span>
<span id="167">167</span>
<span id="168">168</span>
<span id="169">169</span>
<span id="170">170</span>
<span id="171">171</span>
<span id="172">172</span>
<span id="173">173</span>
<span id="174">174</span>
<span id="175">175</span>
<span id="176">176</span>
<span id="177">177</span>
<span id="178">178</span>
<span id="179">179</span>
<span id="180">180</span>
<span id="181">181</span>
<span id="182">182</span>
<span id="183">183</span>
<span id="184">184</span>
<span id="185">185</span>
<span id="186">186</span>
<span id="187">187</span>
<span id="188">188</span>
<span id="189">189</span>
<span id="190">190</span>
<span id="191">191</span>
<span id="192">192</span>
<span id="193">193</span>
<span id="194">194</span>
<span id="195">195</span>
<span id="196">196</span>
<span id="197">197</span>
<span id="198">198</span>
<span id="199">199</span>
<span id="200">200</span>
<span id="201">201</span>
<span id="202">202</span>
<span id="203">203</span>
<span id="204">204</span>
<span id="205">205</span>
<span id="206">206</span>
<span id="207">207</span>
<span id="208">208</span>
<span id="209">209</span>
<span id="210">210</span>
<span id="211">211</span>
<span id="212">212</span>
<span id="213">213</span>
<span id="214">214</span>
<span id="215">215</span>
<span id="216">216</span>
<span id="217">217</span>
<span id="218">218</span>
<span id="219">219</span>
<span id="220">220</span>
<span id="221">221</span>
<span id="222">222</span>
<span id="223">223</span>
<span id="224">224</span>
<span id="225">225</span>
<span id="226">226</span>
<span id="227">227</span>
<span id="228">228</span>
<span id="229">229</span>
<span id="230">230</span>
<span id="231">231</span>
<span id="232">232</span>
<span id="233">233</span>
<span id="234">234</span>
<span id="235">235</span>
<span id="236">236</span>
<span id="237">237</span>
<span id="238">238</span>
<span id="239">239</span>
<span id="240">240</span>
<span id="241">241</span>
<span id="242">242</span>
<span id="243">243</span>
<span id="244">244</span>
<span id="245">245</span>
<span id="246">246</span>
<span id="247">247</span>
<span id="248">248</span>
<span id="249">249</span>
<span id="250">250</span>
<span id="251">251</span>
<span id="252">252</span>
<span id="253">253</span>
<span id="254">254</span>
<span id="255">255</span>
<span id="256">256</span>
<span id="257">257</span>
<span id="258">258</span>
<span id="259">259</span>
<span id="260">260</span>
<span id="261">261</span>
<span id="262">262</span>
<span id="263">263</span>
<span id="264">264</span>
<span id="265">265</span>
<span id="266">266</span>
<span id="267">267</span>
<span id="268">268</span>
<span id="269">269</span>
<span id="270">270</span>
<span id="271">271</span>
<span id="272">272</span>
<span id="273">273</span>
<span id="274">274</span>
<span id="275">275</span>
<span id="276">276</span>
<span id="277">277</span>
<span id="278">278</span>
<span id="279">279</span>
<span id="280">280</span>
<span id="281">281</span>
<span id="282">282</span>
<span id="283">283</span>
<span id="284">284</span>
<span id="285">285</span>
<span id="286">286</span>
<span id="287">287</span>
<span id="288">288</span>
<span id="289">289</span>
<span id="290">290</span>
<span id="291">291</span>
<span id="292">292</span>
<span id="293">293</span>
<span id="294">294</span>
<span id="295">295</span>
<span id="296">296</span>
<span id="297">297</span>
<span id="298">298</span>
<span id="299">299</span>
<span id="300">300</span>
<span id="301">301</span>
<span id="302">302</span>
<span id="303">303</span>
<span id="304">304</span>
<span id="305">305</span>
<span id="306">306</span>
<span id="307">307</span>
<span id="308">308</span>
<span id="309">309</span>
<span id="310">310</span>
<span id="311">311</span>
<span id="312">312</span>
<span id="313">313</span>
<span id="314">314</span>
<span id="315">315</span>
<span id="316">316</span>
<span id="317">317</span>
<span id="318">318</span>
<span id="319">319</span>
<span id="320">320</span>
<span id="321">321</span>
<span id="322">322</span>
<span id="323">323</span>
<span id="324">324</span>
<span id="325">325</span>
<span id="326">326</span>
<span id="327">327</span>
<span id="328">328</span>
<span id="329">329</span>
<span id="330">330</span>
<span id="331">331</span>
<span id="332">332</span>
<span id="333">333</span>
<span id="334">334</span>
<span id="335">335</span>
<span id="336">336</span>
<span id="337">337</span>
<span id="338">338</span>
<span id="339">339</span>
<span id="340">340</span>
<span id="341">341</span>
<span id="342">342</span>
<span id="343">343</span>
<span id="344">344</span>
<span id="345">345</span>
<span id="346">346</span>
<span id="347">347</span>
<span id="348">348</span>
<span id="349">349</span>
<span id="350">350</span>
<span id="351">351</span>
<span id="352">352</span>
<span id="353">353</span>
<span id="354">354</span>
<span id="355">355</span>
<span id="356">356</span>
<span id="357">357</span>
<span id="358">358</span>
<span id="359">359</span>
<span id="360">360</span>
<span id="361">361</span>
<span id="362">362</span>
<span id="363">363</span>
<span id="364">364</span>
<span id="365">365</span>
<span id="366">366</span>
<span id="367">367</span>
<span id="368">368</span>
<span id="369">369</span>
<span id="370">370</span>
<span id="371">371</span>
<span id="372">372</span>
<span id="373">373</span>
<span id="374">374</span>
<span id="375">375</span>
<span id="376">376</span>
<span id="377">377</span>
<span id="378">378</span>
<span id="379">379</span>
<span id="380">380</span>
<span id="381">381</span>
<span id="382">382</span>
<span id="383">383</span>
<span id="384">384</span>
<span id="385">385</span>
<span id="386">386</span>
<span id="387">387</span>
<span id="388">388</span>
<span id="389">389</span>
<span id="390">390</span>
<span id="391">391</span>
<span id="392">392</span>
<span id="393">393</span>
<span id="394">394</span>
<span id="395">395</span>
<span id="396">396</span>
<span id="397">397</span>
<span id="398">398</span>
<span id="399">399</span>
<span id="400">400</span>
<span id="401">401</span>
<span id="402">402</span>
<span id="403">403</span>
<span id="404">404</span>
<span id="405">405</span>
<span id="406">406</span>
<span id="407">407</span>
<span id="408">408</span>
<span id="409">409</span>
<span id="410">410</span>
<span id="411">411</span>
<span id="412">412</span>
<span id="413">413</span>
<span id="414">414</span>
<span id="415">415</span>
<span id="416">416</span>
<span id="417">417</span>
<span id="418">418</span>
<span id="419">419</span>
<span id="420">420</span>
<span id="421">421</span>
<span id="422">422</span>
<span id="423">423</span>
<span id="424">424</span>
<span id="425">425</span>
<span id="426">426</span>
<span id="427">427</span>
<span id="428">428</span>
<span id="429">429</span>
<span id="430">430</span>
<span id="431">431</span>
<span id="432">432</span>
<span id="433">433</span>
<span id="434">434</span>
<span id="435">435</span>
<span id="436">436</span>
<span id="437">437</span>
<span id="438">438</span>
<span id="439">439</span>
<span id="440">440</span>
<span id="441">441</span>
<span id="442">442</span>
<span id="443">443</span>
<span id="444">444</span>
<span id="445">445</span>
<span id="446">446</span>
<span id="447">447</span>
<span id="448">448</span>
<span id="449">449</span>
<span id="450">450</span>
<span id="451">451</span>
<span id="452">452</span>
<span id="453">453</span>
<span id="454">454</span>
<span id="455">455</span>
<span id="456">456</span>
<span id="457">457</span>
<span id="458">458</span>
<span id="459">459</span>
<span id="460">460</span>
<span id="461">461</span>
<span id="462">462</span>
<span id="463">463</span>
<span id="464">464</span>
<span id="465">465</span>
<span id="466">466</span>
<span id="467">467</span>
<span id="468">468</span>
<span id="469">469</span>
<span id="470">470</span>
<span id="471">471</span>
<span id="472">472</span>
<span id="473">473</span>
<span id="474">474</span>
<span id="475">475</span>
<span id="476">476</span>
<span id="477">477</span>
<span id="478">478</span>
<span id="479">479</span>
<span id="480">480</span>
<span id="481">481</span>
<span id="482">482</span>
<span id="483">483</span>
<span id="484">484</span>
<span id="485">485</span>
<span id="486">486</span>
<span id="487">487</span>
<span id="488">488</span>
<span id="489">489</span>
<span id="490">490</span>
<span id="491">491</span>
<span id="492">492</span>
<span id="493">493</span>
<span id="494">494</span>
<span id="495">495</span>
<span id="496">496</span>
<span id="497">497</span>
<span id="498">498</span>
<span id="499">499</span>
<span id="500">500</span>
<span id="501">501</span>
<span id="502">502</span>
<span id="503">503</span>
<span id="504">504</span>
<span id="505">505</span>
<span id="506">506</span>
<span id="507">507</span>
<span id="508">508</span>
<span id="509">509</span>
<span id="510">510</span>
<span id="511">511</span>
<span id="512">512</span>
<span id="513">513</span>
<span id="514">514</span>
<span id="515">515</span>
<span id="516">516</span>
<span id="517">517</span>
<span id="518">518</span>
<span id="519">519</span>
<span id="520">520</span>
<span id="521">521</span>
<span id="522">522</span>
<span id="523">523</span>
<span id="524">524</span>
<span id="525">525</span>
<span id="526">526</span>
<span id="527">527</span>
<span id="528">528</span>
<span id="529">529</span>
<span id="530">530</span>
<span id="531">531</span>
<span id="532">532</span>
<span id="533">533</span>
<span id="534">534</span>
<span id="535">535</span>
<span id="536">536</span>
<span id="537">537</span>
<span id="538">538</span>
<span id="539">539</span>
<span id="540">540</span>
<span id="541">541</span>
<span id="542">542</span>
<span id="543">543</span>
<span id="544">544</span>
<span id="545">545</span>
<span id="546">546</span>
<span id="547">547</span>
<span id="548">548</span>
<span id="549">549</span>
<span id="550">550</span>
<span id="551">551</span>
<span id="552">552</span>
<span id="553">553</span>
<span id="554">554</span>
<span id="555">555</span>
<span id="556">556</span>
<span id="557">557</span>
<span id="558">558</span>
<span id="559">559</span>
<span id="560">560</span>
<span id="561">561</span>
<span id="562">562</span>
<span id="563">563</span>
<span id="564">564</span>
<span id="565">565</span>
<span id="566">566</span>
<span id="567">567</span>
<span id="568">568</span>
<span id="569">569</span>
<span id="570">570</span>
<span id="571">571</span>
<span id="572">572</span>
<span id="573">573</span>
<span id="574">574</span>
<span id="575">575</span>
<span id="576">576</span>
<span id="577">577</span>
<span id="578">578</span>
<span id="579">579</span>
<span id="580">580</span>
<span id="581">581</span>
<span id="582">582</span>
<span id="583">583</span>
<span id="584">584</span>
<span id="585">585</span>
<span id="586">586</span>
<span id="587">587</span>
<span id="588">588</span>
<span id="589">589</span>
<span id="590">590</span>
<span id="591">591</span>
<span id="592">592</span>
<span id="593">593</span>
<span id="594">594</span>
<span id="595">595</span>
<span id="596">596</span>
<span id="597">597</span>
<span id="598">598</span>
<span id="599">599</span>
<span id="600">600</span>
<span id="601">601</span>
<span id="602">602</span>
<span id="603">603</span>
<span id="604">604</span>
<span id="605">605</span>
<span id="606">606</span>
<span id="607">607</span>
<span id="608">608</span>
<span id="609">609</span>
<span id="610">610</span>
<span id="611">611</span>
<span id="612">612</span>
<span id="613">613</span>
<span id="614">614</span>
<span id="615">615</span>
<span id="616">616</span>
<span id="617">617</span>
<span id="618">618</span>
<span id="619">619</span>
<span id="620">620</span>
<span id="621">621</span>
<span id="622">622</span>
<span id="623">623</span>
<span id="624">624</span>
<span id="625">625</span>
<span id="626">626</span>
<span id="627">627</span>
<span id="628">628</span>
<span id="629">629</span>
<span id="630">630</span>
<span id="631">631</span>
<span id="632">632</span>
<span id="633">633</span>
<span id="634">634</span>
<span id="635">635</span>
<span id="636">636</span>
<span id="637">637</span>
<span id="638">638</span>
<span id="639">639</span>
<span id="640">640</span>
<span id="641">641</span>
<span id="642">642</span>
<span id="643">643</span>
<span id="644">644</span>
<span id="645">645</span>
<span id="646">646</span>
<span id="647">647</span>
<span id="648">648</span>
<span id="649">649</span>
<span id="650">650</span>
<span id="651">651</span>
<span id="652">652</span>
<span id="653">653</span>
<span id="654">654</span>
<span id="655">655</span>
<span id="656">656</span>
<span id="657">657</span>
<span id="658">658</span>
<span id="659">659</span>
<span id="660">660</span>
<span id="661">661</span>
<span id="662">662</span>
<span id="663">663</span>
<span id="664">664</span>
<span id="665">665</span>
<span id="666">666</span>
<span id="667">667</span>
<span id="668">668</span>
<span id="669">669</span>
<span id="670">670</span>
<span id="671">671</span>
<span id="672">672</span>
<span id="673">673</span>
<span id="674">674</span>
<span id="675">675</span>
<span id="676">676</span>
<span id="677">677</span>
<span id="678">678</span>
<span id="679">679</span>
<span id="680">680</span>
<span id="681">681</span>
<span id="682">682</span>
<span id="683">683</span>
<span id="684">684</span>
<span id="685">685</span>
<span id="686">686</span>
<span id="687">687</span>
<span id="688">688</span>
<span id="689">689</span>
<span id="690">690</span>
<span id="691">691</span>
<span id="692">692</span>
<span id="693">693</span>
<span id="694">694</span>
<span id="695">695</span>
<span id="696">696</span>
<span id="697">697</span>
<span id="698">698</span>
<span id="699">699</span>
<span id="700">700</span>
<span id="701">701</span>
<span id="702">702</span>
<span id="703">703</span>
<span id="704">704</span>
<span id="705">705</span>
<span id="706">706</span>
<span id="707">707</span>
<span id="708">708</span>
<span id="709">709</span>
<span id="710">710</span>
<span id="711">711</span>
<span id="712">712</span>
<span id="713">713</span>
<span id="714">714</span>
<span id="715">715</span>
<span id="716">716</span>
<span id="717">717</span>
<span id="718">718</span>
<span id="719">719</span>
<span id="720">720</span>
<span id="721">721</span>
<span id="722">722</span>
<span id="723">723</span>
<span id="724">724</span>
<span id="725">725</span>
<span id="726">726</span>
<span id="727">727</span>
<span id="728">728</span>
<span id="729">729</span>
<span id="730">730</span>
<span id="731">731</span>
<span id="732">732</span>
<span id="733">733</span>
<span id="734">734</span>
<span id="735">735</span>
<span id="736">736</span>
<span id="737">737</span>
<span id="738">738</span>
<span id="739">739</span>
<span id="740">740</span>
<span id="741">741</span>
<span id="742">742</span>
<span id="743">743</span>
<span id="744">744</span>
<span id="745">745</span>
<span id="746">746</span>
<span id="747">747</span>
<span id="748">748</span>
<span id="749">749</span>
<span id="750">750</span>
<span id="751">751</span>
<span id="752">752</span>
<span id="753">753</span>
<span id="754">754</span>
<span id="755">755</span>
<span id="756">756</span>
<span id="757">757</span>
<span id="758">758</span>
<span id="759">759</span>
<span id="760">760</span>
<span id="761">761</span>
<span id="762">762</span>
<span id="763">763</span>
<span id="764">764</span>
<span id="765">765</span>
<span id="766">766</span>
<span id="767">767</span>
<span id="768">768</span>
<span id="769">769</span>
<span id="770">770</span>
<span id="771">771</span>
<span id="772">772</span>
<span id="773">773</span>
<span id="774">774</span>
<span id="775">775</span>
<span id="776">776</span>
<span id="777">777</span>
<span id="778">778</span>
<span id="779">779</span>
<span id="780">780</span>
<span id="781">781</span>
<span id="782">782</span>
<span id="783">783</span>
<span id="784">784</span>
<span id="785">785</span>
<span id="786">786</span>
<span id="787">787</span>
<span id="788">788</span>
<span id="789">789</span>
<span id="790">790</span>
<span id="791">791</span>
<span id="792">792</span>
<span id="793">793</span>
<span id="794">794</span>
<span id="795">795</span>
<span id="796">796</span>
<span id="797">797</span>
<span id="798">798</span>
<span id="799">799</span>
<span id="800">800</span>
<span id="801">801</span>
<span id="802">802</span>
<span id="803">803</span>
<span id="804">804</span>
<span id="805">805</span>
<span id="806">806</span>
<span id="807">807</span>
<span id="808">808</span>
<span id="809">809</span>
<span id="810">810</span>
<span id="811">811</span>
<span id="812">812</span>
<span id="813">813</span>
<span id="814">814</span>
<span id="815">815</span>
<span id="816">816</span>
<span id="817">817</span>
<span id="818">818</span>
<span id="819">819</span>
<span id="820">820</span>
<span id="821">821</span>
<span id="822">822</span>
<span id="823">823</span>
<span id="824">824</span>
<span id="825">825</span>
<span id="826">826</span>
<span id="827">827</span>
<span id="828">828</span>
<span id="829">829</span>
<span id="830">830</span>
<span id="831">831</span>
<span id="832">832</span>
<span id="833">833</span>
<span id="834">834</span>
<span id="835">835</span>
<span id="836">836</span>
<span id="837">837</span>
<span id="838">838</span>
<span id="839">839</span>
<span id="840">840</span>
<span id="841">841</span>
<span id="842">842</span>
<span id="843">843</span>
<span id="844">844</span>
<span id="845">845</span>
<span id="846">846</span>
<span id="847">847</span>
<span id="848">848</span>
<span id="849">849</span>
<span id="850">850</span>
<span id="851">851</span>
<span id="852">852</span>
<span id="853">853</span>
<span id="854">854</span>
<span id="855">855</span>
<span id="856">856</span>
<span id="857">857</span>
<span id="858">858</span>
<span id="859">859</span>
<span id="860">860</span>
<span id="861">861</span>
<span id="862">862</span>
<span id="863">863</span>
<span id="864">864</span>
<span id="865">865</span>
<span id="866">866</span>
<span id="867">867</span>
<span id="868">868</span>
<span id="869">869</span>
<span id="870">870</span>
<span id="871">871</span>
<span id="872">872</span>
<span id="873">873</span>
<span id="874">874</span>
<span id="875">875</span>
<span id="876">876</span>
<span id="877">877</span>
<span id="878">878</span>
<span id="879">879</span>
<span id="880">880</span>
<span id="881">881</span>
<span id="882">882</span>
<span id="883">883</span>
<span id="884">884</span>
<span id="885">885</span>
<span id="886">886</span>
<span id="887">887</span>
<span id="888">888</span>
<span id="889">889</span>
<span id="890">890</span>
<span id="891">891</span>
<span id="892">892</span>
<span id="893">893</span>
<span id="894">894</span>
<span id="895">895</span>
<span id="896">896</span>
<span id="897">897</span>
<span id="898">898</span>
<span id="899">899</span>
<span id="900">900</span>
<span id="901">901</span>
<span id="902">902</span>
<span id="903">903</span>
<span id="904">904</span>
<span id="905">905</span>
<span id="906">906</span>
<span id="907">907</span>
<span id="908">908</span>
<span id="909">909</span>
<span id="910">910</span>
<span id="911">911</span>
<span id="912">912</span>
<span id="913">913</span>
<span id="914">914</span>
<span id="915">915</span>
<span id="916">916</span>
<span id="917">917</span>
<span id="918">918</span>
<span id="919">919</span>
<span id="920">920</span>
<span id="921">921</span>
<span id="922">922</span>
<span id="923">923</span>
<span id="924">924</span>
</pre><pre class="rust"><code><span class="kw">use</span> <span class="ident">std::collections::BTreeMap</span>;
<span class="kw">use</span> <span class="ident">std::sync::Arc</span>;
<span class="kw">use</span> <span class="ident">kanidm_proto::v1::Filter</span> <span class="kw">as</span> <span class="ident">ProtoFilter</span>;
<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::event</span>::{<span class="ident">CreateEvent</span>, <span class="ident">ModifyEvent</span>};
<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::filter::FilterInvalid</span>;
<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::prelude</span>::<span class="kw-2">*</span>;
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">DynGroupCache</span> {
<span class="ident">insts</span>: <span class="ident">BTreeMap</span><span class="op">&lt;</span><span class="ident">Uuid</span>, <span class="ident">Filter</span><span class="op">&lt;</span><span class="ident">FilterInvalid</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">Default</span> <span class="kw">for</span> <span class="ident">DynGroupCache</span> {
<span class="kw">fn</span> <span class="ident">default</span>() -&gt; <span class="self">Self</span> {
<span class="ident">DynGroupCache</span> {
<span class="ident">insts</span>: <span class="ident">BTreeMap::default</span>(),
}
}
}
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">DynGroup</span>;
<span class="kw">impl</span> <span class="ident">DynGroup</span> {
<span class="kw">fn</span> <span class="ident">apply_dyngroup_change</span>(
<span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span>,
<span class="ident">ident</span>: <span class="kw-2">&amp;</span><span class="ident">Identity</span>,
<span class="ident">pre_candidates</span>: <span class="kw-2">&amp;mut</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">EntrySealedCommitted</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="ident">candidates</span>: <span class="kw-2">&amp;mut</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">EntryInvalidCommitted</span><span class="op">&gt;</span>,
<span class="ident">affected_uuids</span>: <span class="kw-2">&amp;mut</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Uuid</span><span class="op">&gt;</span>,
<span class="ident">expect</span>: <span class="ident">bool</span>,
<span class="ident">ident_internal</span>: <span class="kw-2">&amp;</span><span class="ident">Identity</span>,
<span class="ident">dyn_groups</span>: <span class="kw-2">&amp;mut</span> <span class="ident">DynGroupCache</span>,
<span class="ident">n_dyn_groups</span>: <span class="kw-2">&amp;</span>[<span class="kw-2">&amp;</span><span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntrySealed</span>, <span class="ident">EntryCommitted</span><span class="op">&gt;</span>],
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">OperationError</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="op">!</span><span class="ident">ident</span>.<span class="ident">is_internal</span>() {
<span class="comment">// It should be impossible to trigger this right now due to protected plugin.</span>
<span class="macro">error!</span>(<span class="string">&quot;It is currently an error to create a dynamic group&quot;</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">OperationError::SystemProtectedObject</span>);
}
<span class="comment">// Search all the new groups first.</span>
<span class="kw">let</span> <span class="ident">filt</span> <span class="op">=</span> <span class="macro">filter!</span>(<span class="ident">FC::Or</span>(
<span class="ident">n_dyn_groups</span>
.<span class="ident">into_iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">f_eq</span>(<span class="string">&quot;uuid&quot;</span>, <span class="ident">PartialValue::new_uuid</span>(<span class="ident">e</span>.<span class="ident">get_uuid</span>())))
.<span class="ident">collect</span>()
));
<span class="kw">let</span> <span class="ident">work_set</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">internal_search_writeable</span>(<span class="kw-2">&amp;</span><span class="ident">filt</span>)<span class="question-mark">?</span>;
<span class="comment">// Go through them all and update the new groups.</span>
<span class="kw">for</span> (<span class="ident">pre</span>, <span class="kw-2">mut</span> <span class="ident">nd_group</span>) <span class="kw">in</span> <span class="ident">work_set</span>.<span class="ident">into_iter</span>() {
<span class="kw">let</span> <span class="ident">scope_f</span>: <span class="ident">ProtoFilter</span> <span class="op">=</span> <span class="ident">nd_group</span>
.<span class="ident">get_ava_single_protofilter</span>(<span class="string">&quot;dyngroup_filter&quot;</span>)
.<span class="ident">cloned</span>()
.<span class="ident">ok_or_else</span>(<span class="op">|</span><span class="op">|</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;Missing dyngroup_filter&quot;</span>);
<span class="ident">OperationError::InvalidEntryState</span>
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">scope_i</span> <span class="op">=</span> <span class="ident">Filter::from_rw</span>(<span class="ident">ident_internal</span>, <span class="kw-2">&amp;</span><span class="ident">scope_f</span>, <span class="ident">qs</span>).<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;dyngroup_filter validation failed {:?}&quot;</span>, <span class="ident">e</span>);
<span class="ident">e</span>
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">uuid</span> <span class="op">=</span> <span class="ident">pre</span>.<span class="ident">get_uuid</span>();
<span class="comment">// Add our uuid as affected.</span>
<span class="ident">affected_uuids</span>.<span class="ident">push</span>(<span class="ident">uuid</span>);
<span class="comment">// Apply the filter and get all the uuids.</span>
<span class="kw">let</span> <span class="ident">entries</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">internal_search</span>(<span class="ident">scope_i</span>.<span class="ident">clone</span>()).<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;internal search failure -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="ident">e</span>
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="ident">ValueSetRefer::from_iter</span>(<span class="ident">entries</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">e</span>.<span class="ident">get_uuid</span>()));
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">uuid_iter</span>) <span class="op">=</span> <span class="ident">members</span>.<span class="ident">as_ref</span>().<span class="ident">and_then</span>(<span class="op">|</span><span class="ident">a</span><span class="op">|</span> <span class="ident">a</span>.<span class="ident">as_ref_uuid_iter</span>()) {
<span class="ident">affected_uuids</span>.<span class="ident">extend</span>(<span class="ident">uuid_iter</span>);
}
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">members</span>) <span class="op">=</span> <span class="ident">members</span> {
<span class="comment">// Only set something if there is actually something to do!</span>
<span class="ident">nd_group</span>.<span class="ident">set_ava_set</span>(<span class="string">&quot;member&quot;</span>, <span class="ident">members</span>);
<span class="comment">// push the entries to pre/cand</span>
} <span class="kw">else</span> {
<span class="ident">nd_group</span>.<span class="ident">purge_ava</span>(<span class="string">&quot;member&quot;</span>);
}
<span class="ident">pre_candidates</span>.<span class="ident">push</span>(<span class="ident">pre</span>);
<span class="ident">candidates</span>.<span class="ident">push</span>(<span class="ident">nd_group</span>);
<span class="comment">// Insert to our new instances</span>
<span class="kw">if</span> <span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">insert</span>(<span class="ident">uuid</span>, <span class="ident">scope_i</span>).<span class="ident">is_none</span>() <span class="op">==</span> <span class="ident">expect</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;dyngroup cache uuid conflict {}&quot;</span>, <span class="ident">uuid</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">OperationError::InvalidState</span>);
}
}
<span class="prelude-val">Ok</span>(())
}
<span class="attribute">#[<span class="ident">instrument</span>(<span class="ident">level</span> <span class="op">=</span> <span class="string">&quot;debug&quot;</span>, <span class="ident">name</span> <span class="op">=</span> <span class="string">&quot;dyngroup_reload&quot;</span>, <span class="ident">skip</span>(<span class="ident">qs</span>))]</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">reload</span>(<span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">OperationError</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">ident_internal</span> <span class="op">=</span> <span class="ident">Identity::from_internal</span>();
<span class="comment">// Internal search all our definitions.</span>
<span class="kw">let</span> <span class="ident">filt</span> <span class="op">=</span> <span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;class&quot;</span>, <span class="ident">PVCLASS_DYNGROUP</span>.<span class="ident">clone</span>()));
<span class="kw">let</span> <span class="ident">entries</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">internal_search</span>(<span class="ident">filt</span>).<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;internal search failure -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="ident">e</span>
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">dyn_groups</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">get_dyngroup_cache</span>();
<span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">clear</span>();
<span class="kw">for</span> <span class="ident">nd_group</span> <span class="kw">in</span> <span class="ident">entries</span>.<span class="ident">into_iter</span>() {
<span class="kw">let</span> <span class="ident">scope_f</span>: <span class="ident">ProtoFilter</span> <span class="op">=</span> <span class="ident">nd_group</span>
.<span class="ident">get_ava_single_protofilter</span>(<span class="string">&quot;dyngroup_filter&quot;</span>)
.<span class="ident">cloned</span>()
.<span class="ident">ok_or_else</span>(<span class="op">|</span><span class="op">|</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;Missing dyngroup_filter&quot;</span>);
<span class="ident">OperationError::InvalidEntryState</span>
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">scope_i</span> <span class="op">=</span> <span class="ident">Filter::from_rw</span>(<span class="kw-2">&amp;</span><span class="ident">ident_internal</span>, <span class="kw-2">&amp;</span><span class="ident">scope_f</span>, <span class="ident">qs</span>).<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;dyngroup_filter validation failed {:?}&quot;</span>, <span class="ident">e</span>);
<span class="ident">e</span>
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">uuid</span> <span class="op">=</span> <span class="ident">nd_group</span>.<span class="ident">get_uuid</span>();
<span class="kw">if</span> <span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">insert</span>(<span class="ident">uuid</span>, <span class="ident">scope_i</span>).<span class="ident">is_some</span>() {
<span class="macro">admin_error!</span>(<span class="string">&quot;dyngroup cache uuid conflict {}&quot;</span>, <span class="ident">uuid</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">OperationError::InvalidState</span>);
}
}
<span class="prelude-val">Ok</span>(())
}
<span class="attribute">#[<span class="ident">instrument</span>(<span class="ident">level</span> <span class="op">=</span> <span class="string">&quot;debug&quot;</span>, <span class="ident">name</span> <span class="op">=</span> <span class="string">&quot;dyngroup_post_create&quot;</span>, <span class="ident">skip</span>(<span class="ident">qs</span>, <span class="ident">cand</span>, <span class="ident">ce</span>))]</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">post_create</span>(
<span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span>,
<span class="ident">cand</span>: <span class="kw-2">&amp;</span>[<span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntrySealed</span>, <span class="ident">EntryCommitted</span><span class="op">&gt;</span>],
<span class="ident">ce</span>: <span class="kw-2">&amp;</span><span class="ident">CreateEvent</span>,
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Uuid</span><span class="op">&gt;</span>, <span class="ident">OperationError</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">affected_uuids</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">cand</span>.<span class="ident">len</span>());
<span class="kw">let</span> <span class="ident">ident_internal</span> <span class="op">=</span> <span class="ident">Identity::from_internal</span>();
<span class="kw">let</span> (<span class="ident">n_dyn_groups</span>, <span class="ident">entries</span>): (<span class="ident">Vec</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">Entry</span><span class="op">&lt;</span><span class="kw">_</span>, <span class="kw">_</span><span class="op">&gt;</span><span class="op">&gt;</span>, <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span>) <span class="op">=</span> <span class="ident">cand</span>
.<span class="ident">iter</span>()
.<span class="ident">partition</span>(<span class="op">|</span><span class="ident">entry</span><span class="op">|</span> <span class="ident">entry</span>.<span class="ident">attribute_equality</span>(<span class="string">&quot;class&quot;</span>, <span class="kw-2">&amp;</span><span class="ident">PVCLASS_DYNGROUP</span>));
<span class="kw">let</span> <span class="ident">dyn_groups</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">get_dyngroup_cache</span>();
<span class="comment">// For any other entries, check if they SHOULD trigger</span>
<span class="comment">// a dyn group inclusion. We do this FIRST because the new</span>
<span class="comment">// dyn groups will see the created entries on an internal search</span>
<span class="comment">// so we don&#39;t need to reference them.</span>
<span class="comment">//</span>
<span class="kw">let</span> <span class="ident">resolve_filter_cache</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">get_resolve_filter_cache</span>();
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">pre_candidates</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">len</span>() <span class="op">+</span> <span class="ident">cand</span>.<span class="ident">len</span>());
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">candidates</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">len</span>() <span class="op">+</span> <span class="ident">cand</span>.<span class="ident">len</span>());
<span class="macro">trace!</span>(<span class="question-mark">?</span><span class="ident">dyn_groups</span>.<span class="ident">insts</span>);
<span class="kw">for</span> (<span class="ident">dg_uuid</span>, <span class="ident">dg_filter</span>) <span class="kw">in</span> <span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">iter</span>() {
<span class="kw">let</span> <span class="ident">dg_filter_valid</span> <span class="op">=</span> <span class="ident">dg_filter</span>
.<span class="ident">validate</span>(<span class="ident">qs</span>.<span class="ident">get_schema</span>())
.<span class="ident">map_err</span>(<span class="ident">OperationError::SchemaViolation</span>)
.<span class="ident">and_then</span>(<span class="op">|</span><span class="ident">f</span><span class="op">|</span> <span class="ident">f</span>.<span class="ident">resolve</span>(<span class="kw-2">&amp;</span><span class="ident">ident_internal</span>, <span class="prelude-val">None</span>, <span class="prelude-val">Some</span>(<span class="ident">resolve_filter_cache</span>)))<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">matches</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">entries</span>
.<span class="ident">iter</span>()
.<span class="ident">filter_map</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="kw">if</span> <span class="ident">e</span>.<span class="ident">entry_match_no_index</span>(<span class="kw-2">&amp;</span><span class="ident">dg_filter_valid</span>) {
<span class="prelude-val">Some</span>(<span class="ident">e</span>.<span class="ident">get_uuid</span>())
} <span class="kw">else</span> {
<span class="prelude-val">None</span>
}
})
.<span class="ident">collect</span>();
<span class="kw">if</span> <span class="op">!</span><span class="ident">matches</span>.<span class="ident">is_empty</span>() {
<span class="kw">let</span> <span class="ident">filt</span> <span class="op">=</span> <span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;uuid&quot;</span>, <span class="ident">PartialValue::new_uuid</span>(<span class="kw-2">*</span><span class="ident">dg_uuid</span>)));
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">work_set</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">internal_search_writeable</span>(<span class="kw-2">&amp;</span><span class="ident">filt</span>)<span class="question-mark">?</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>((<span class="ident">pre</span>, <span class="kw-2">mut</span> <span class="ident">d_group</span>)) <span class="op">=</span> <span class="ident">work_set</span>.<span class="ident">pop</span>() {
<span class="ident">matches</span>
.<span class="ident">iter</span>()
.<span class="ident">copied</span>()
.<span class="ident">for_each</span>(<span class="op">|</span><span class="ident">u</span><span class="op">|</span> <span class="ident">d_group</span>.<span class="ident">add_ava</span>(<span class="string">&quot;member&quot;</span>, <span class="ident">Value::new_refer</span>(<span class="ident">u</span>)));
<span class="ident">affected_uuids</span>.<span class="ident">extend</span>(<span class="ident">matches</span>.<span class="ident">into_iter</span>());
<span class="ident">affected_uuids</span>.<span class="ident">push</span>(<span class="kw-2">*</span><span class="ident">dg_uuid</span>);
<span class="ident">pre_candidates</span>.<span class="ident">push</span>(<span class="ident">pre</span>);
<span class="ident">candidates</span>.<span class="ident">push</span>(<span class="ident">d_group</span>);
}
}
}
<span class="comment">// If we created any dyn groups, populate them now.</span>
<span class="comment">// if the event is not internal, reject (for now)</span>
<span class="kw">if</span> <span class="op">!</span><span class="ident">n_dyn_groups</span>.<span class="ident">is_empty</span>() {
<span class="macro">trace!</span>(<span class="string">&quot;considering new dyngroups&quot;</span>);
<span class="ident"><span class="self">Self</span>::apply_dyngroup_change</span>(
<span class="ident">qs</span>,
<span class="kw-2">&amp;</span><span class="ident">ce</span>.<span class="ident">ident</span>,
<span class="kw-2">&amp;mut</span> <span class="ident">pre_candidates</span>,
<span class="kw-2">&amp;mut</span> <span class="ident">candidates</span>,
<span class="kw-2">&amp;mut</span> <span class="ident">affected_uuids</span>,
<span class="bool-val">false</span>,
<span class="kw-2">&amp;</span><span class="ident">ident_internal</span>,
<span class="ident">dyn_groups</span>,
<span class="ident">n_dyn_groups</span>.<span class="ident">as_slice</span>(),
)<span class="question-mark">?</span>;
}
<span class="comment">// Write back the new changes.</span>
<span class="macro">debug_assert!</span>(<span class="ident">pre_candidates</span>.<span class="ident">len</span>() <span class="op">==</span> <span class="ident">candidates</span>.<span class="ident">len</span>());
<span class="comment">// Write this stripe if populated.</span>
<span class="kw">if</span> <span class="op">!</span><span class="ident">pre_candidates</span>.<span class="ident">is_empty</span>() {
<span class="ident">qs</span>.<span class="ident">internal_batch_modify</span>(<span class="ident">pre_candidates</span>, <span class="ident">candidates</span>)
.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;Failed to commit dyngroup set {:?}&quot;</span>, <span class="ident">e</span>);
<span class="ident">e</span>
})<span class="question-mark">?</span>;
}
<span class="prelude-val">Ok</span>(<span class="ident">affected_uuids</span>)
}
<span class="attribute">#[<span class="ident">instrument</span>(
<span class="ident">level</span> <span class="op">=</span> <span class="string">&quot;debug&quot;</span>,
<span class="ident">name</span> <span class="op">=</span> <span class="string">&quot;memberof_post_modify&quot;</span>,
<span class="ident">skip</span>(<span class="ident">qs</span>, <span class="ident">pre_cand</span>, <span class="ident">cand</span>, <span class="ident">me</span>)
)]</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">post_modify</span>(
<span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span>,
<span class="ident">pre_cand</span>: <span class="kw-2">&amp;</span>[<span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntrySealed</span>, <span class="ident">EntryCommitted</span><span class="op">&gt;</span><span class="op">&gt;</span>],
<span class="ident">cand</span>: <span class="kw-2">&amp;</span>[<span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntrySealed</span>, <span class="ident">EntryCommitted</span><span class="op">&gt;</span>],
<span class="ident">me</span>: <span class="kw-2">&amp;</span><span class="ident">ModifyEvent</span>,
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Uuid</span><span class="op">&gt;</span>, <span class="ident">OperationError</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">affected_uuids</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">cand</span>.<span class="ident">len</span>());
<span class="kw">let</span> <span class="ident">ident_internal</span> <span class="op">=</span> <span class="ident">Identity::from_internal</span>();
<span class="kw">let</span> <span class="ident">resolve_filter_cache</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">get_resolve_filter_cache</span>();
<span class="comment">// Probably should be filter here instead.</span>
<span class="kw">let</span> (<span class="kw">_</span>, <span class="ident">pre_entries</span>): (<span class="ident">Vec</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">Entry</span><span class="op">&lt;</span><span class="kw">_</span>, <span class="kw">_</span><span class="op">&gt;</span><span class="op">&gt;</span><span class="op">&gt;</span>, <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span>) <span class="op">=</span> <span class="ident">pre_cand</span>
.<span class="ident">iter</span>()
.<span class="ident">partition</span>(<span class="op">|</span><span class="ident">entry</span><span class="op">|</span> <span class="ident">entry</span>.<span class="ident">attribute_equality</span>(<span class="string">&quot;class&quot;</span>, <span class="kw-2">&amp;</span><span class="ident">PVCLASS_DYNGROUP</span>));
<span class="kw">let</span> (<span class="ident">n_dyn_groups</span>, <span class="ident">post_entries</span>): (<span class="ident">Vec</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">Entry</span><span class="op">&lt;</span><span class="kw">_</span>, <span class="kw">_</span><span class="op">&gt;</span><span class="op">&gt;</span>, <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span>) <span class="op">=</span> <span class="ident">cand</span>
.<span class="ident">iter</span>()
.<span class="ident">partition</span>(<span class="op">|</span><span class="ident">entry</span><span class="op">|</span> <span class="ident">entry</span>.<span class="ident">attribute_equality</span>(<span class="string">&quot;class&quot;</span>, <span class="kw-2">&amp;</span><span class="ident">PVCLASS_DYNGROUP</span>));
<span class="kw">let</span> <span class="ident">dyn_groups</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">get_dyngroup_cache</span>();
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">pre_candidates</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">len</span>() <span class="op">+</span> <span class="ident">cand</span>.<span class="ident">len</span>());
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">candidates</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">len</span>() <span class="op">+</span> <span class="ident">cand</span>.<span class="ident">len</span>());
<span class="comment">// If we modified a dyngroups member or filter, re-trigger it here.</span>
<span class="comment">// if the event is not internal, reject (for now)</span>
<span class="comment">// We do this *first* so that we don&#39;t accidentally include/exclude anything that</span>
<span class="comment">// changed in this op.</span>
<span class="kw">if</span> <span class="op">!</span><span class="ident">n_dyn_groups</span>.<span class="ident">is_empty</span>() {
<span class="macro">trace!</span>(<span class="string">&quot;considering modified dyngroups&quot;</span>);
<span class="ident"><span class="self">Self</span>::apply_dyngroup_change</span>(
<span class="ident">qs</span>,
<span class="kw-2">&amp;</span><span class="ident">me</span>.<span class="ident">ident</span>,
<span class="kw-2">&amp;mut</span> <span class="ident">pre_candidates</span>,
<span class="kw-2">&amp;mut</span> <span class="ident">candidates</span>,
<span class="kw-2">&amp;mut</span> <span class="ident">affected_uuids</span>,
<span class="bool-val">true</span>,
<span class="kw-2">&amp;</span><span class="ident">ident_internal</span>,
<span class="ident">dyn_groups</span>,
<span class="ident">n_dyn_groups</span>.<span class="ident">as_slice</span>(),
)<span class="question-mark">?</span>;
}
<span class="comment">// If we modified anything else, check if a dyngroup is affected by it&#39;s change</span>
<span class="comment">// if it was a member.</span>
<span class="macro">trace!</span>(<span class="question-mark">?</span><span class="ident">dyn_groups</span>.<span class="ident">insts</span>);
<span class="kw">for</span> (<span class="ident">dg_uuid</span>, <span class="ident">dg_filter</span>) <span class="kw">in</span> <span class="ident">dyn_groups</span>.<span class="ident">insts</span>.<span class="ident">iter</span>() {
<span class="kw">let</span> <span class="ident">dg_filter_valid</span> <span class="op">=</span> <span class="ident">dg_filter</span>
.<span class="ident">validate</span>(<span class="ident">qs</span>.<span class="ident">get_schema</span>())
.<span class="ident">map_err</span>(<span class="ident">OperationError::SchemaViolation</span>)
.<span class="ident">and_then</span>(<span class="op">|</span><span class="ident">f</span><span class="op">|</span> <span class="ident">f</span>.<span class="ident">resolve</span>(<span class="kw-2">&amp;</span><span class="ident">ident_internal</span>, <span class="prelude-val">None</span>, <span class="prelude-val">Some</span>(<span class="ident">resolve_filter_cache</span>)))<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">matches</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">pre_entries</span>
.<span class="ident">iter</span>()
.<span class="ident">zip</span>(<span class="ident">post_entries</span>.<span class="ident">iter</span>())
.<span class="ident">filter_map</span>(<span class="op">|</span>(<span class="ident">pre</span>, <span class="ident">post</span>)<span class="op">|</span> {
<span class="kw">let</span> <span class="ident">pre_t</span> <span class="op">=</span> <span class="ident">pre</span>.<span class="ident">entry_match_no_index</span>(<span class="kw-2">&amp;</span><span class="ident">dg_filter_valid</span>);
<span class="kw">let</span> <span class="ident">post_t</span> <span class="op">=</span> <span class="ident">post</span>.<span class="ident">entry_match_no_index</span>(<span class="kw-2">&amp;</span><span class="ident">dg_filter_valid</span>);
<span class="kw">if</span> <span class="ident">pre_t</span> <span class="op">&amp;&amp;</span> <span class="op">!</span><span class="ident">post_t</span> {
<span class="prelude-val">Some</span>(<span class="prelude-val">Err</span>(<span class="ident">post</span>.<span class="ident">get_uuid</span>()))
} <span class="kw">else</span> <span class="kw">if</span> <span class="op">!</span><span class="ident">pre_t</span> <span class="op">&amp;&amp;</span> <span class="ident">post_t</span> {
<span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(<span class="ident">post</span>.<span class="ident">get_uuid</span>()))
} <span class="kw">else</span> {
<span class="prelude-val">None</span>
}
})
.<span class="ident">collect</span>();
<span class="kw">if</span> <span class="op">!</span><span class="ident">matches</span>.<span class="ident">is_empty</span>() {
<span class="kw">let</span> <span class="ident">filt</span> <span class="op">=</span> <span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;uuid&quot;</span>, <span class="ident">PartialValue::new_uuid</span>(<span class="kw-2">*</span><span class="ident">dg_uuid</span>)));
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">work_set</span> <span class="op">=</span> <span class="ident">qs</span>.<span class="ident">internal_search_writeable</span>(<span class="kw-2">&amp;</span><span class="ident">filt</span>)<span class="question-mark">?</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>((<span class="ident">pre</span>, <span class="kw-2">mut</span> <span class="ident">d_group</span>)) <span class="op">=</span> <span class="ident">work_set</span>.<span class="ident">pop</span>() {
<span class="ident">matches</span>.<span class="ident">iter</span>().<span class="ident">copied</span>().<span class="ident">for_each</span>(<span class="op">|</span><span class="ident">choice</span><span class="op">|</span> <span class="kw">match</span> <span class="ident">choice</span> {
<span class="prelude-val">Ok</span>(<span class="ident">u</span>) =&gt; <span class="ident">d_group</span>.<span class="ident">add_ava</span>(<span class="string">&quot;member&quot;</span>, <span class="ident">Value::new_refer</span>(<span class="ident">u</span>)),
<span class="prelude-val">Err</span>(<span class="ident">u</span>) =&gt; <span class="ident">d_group</span>.<span class="ident">remove_ava</span>(<span class="string">&quot;member&quot;</span>, <span class="kw-2">&amp;</span><span class="ident">PartialValue::new_refer</span>(<span class="ident">u</span>)),
});
<span class="ident">affected_uuids</span>.<span class="ident">extend</span>(<span class="ident">matches</span>.<span class="ident">into_iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">choice</span><span class="op">|</span> <span class="kw">match</span> <span class="ident">choice</span> {
<span class="prelude-val">Ok</span>(<span class="ident">u</span>) =&gt; <span class="ident">u</span>,
<span class="prelude-val">Err</span>(<span class="ident">u</span>) =&gt; <span class="ident">u</span>,
}));
<span class="ident">affected_uuids</span>.<span class="ident">push</span>(<span class="kw-2">*</span><span class="ident">dg_uuid</span>);
<span class="ident">pre_candidates</span>.<span class="ident">push</span>(<span class="ident">pre</span>);
<span class="ident">candidates</span>.<span class="ident">push</span>(<span class="ident">d_group</span>);
}
}
}
<span class="comment">// Write back the new changes.</span>
<span class="macro">debug_assert!</span>(<span class="ident">pre_candidates</span>.<span class="ident">len</span>() <span class="op">==</span> <span class="ident">candidates</span>.<span class="ident">len</span>());
<span class="comment">// Write this stripe if populated.</span>
<span class="kw">if</span> <span class="op">!</span><span class="ident">pre_candidates</span>.<span class="ident">is_empty</span>() {
<span class="ident">qs</span>.<span class="ident">internal_batch_modify</span>(<span class="ident">pre_candidates</span>, <span class="ident">candidates</span>)
.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">admin_error!</span>(<span class="string">&quot;Failed to commit dyngroup set {:?}&quot;</span>, <span class="ident">e</span>);
<span class="ident">e</span>
})<span class="question-mark">?</span>;
}
<span class="prelude-val">Ok</span>(<span class="ident">affected_uuids</span>)
}
<span class="comment">// No post_delete handler is needed as refint takes care of this for us.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">verify</span>(<span class="ident">_qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerReadTransaction</span>) -&gt; <span class="ident">Vec</span><span class="op">&lt;</span><span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">ConsistencyError</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="macro">vec!</span>[]
}
}
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">test</span>)]</span>
<span class="kw">mod</span> <span class="ident">tests</span> {
<span class="kw">use</span> <span class="ident">kanidm_proto::v1::Filter</span> <span class="kw">as</span> <span class="ident">ProtoFilter</span>;
<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::prelude</span>::<span class="kw-2">*</span>;
<span class="kw">const</span> <span class="ident">UUID_TEST_GROUP</span>: <span class="ident">Uuid</span> <span class="op">=</span> <span class="macro">uuid::uuid!</span>(<span class="string">&quot;7bfd9931-06c2-4608-8a46-78719bb746fe&quot;</span>);
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_create_dyngroup_add_new_group</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_group</span>];
<span class="kw">let</span> <span class="ident">create</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>];
<span class="macro">run_create_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="ident">create</span>,
<span class="prelude-val">None</span>,
<span class="comment">// Need to validate it did things</span>
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="ident">d_group</span>
.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>)
.<span class="ident">expect</span>(<span class="string">&quot;No members on dyn group&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">members</span>.<span class="ident">to_refer_single</span>() <span class="op">==</span> <span class="prelude-val">Some</span>(<span class="ident">UUID_TEST_GROUP</span>));
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_create_dyngroup_add_matching_entry</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>];
<span class="kw">let</span> <span class="ident">create</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_group</span>];
<span class="macro">run_create_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="ident">create</span>,
<span class="prelude-val">None</span>,
<span class="comment">// Need to validate it did things</span>
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="ident">d_group</span>
.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>)
.<span class="ident">expect</span>(<span class="string">&quot;No members on dyn group&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">members</span>.<span class="ident">to_refer_single</span>() <span class="op">==</span> <span class="prelude-val">Some</span>(<span class="ident">UUID_TEST_GROUP</span>));
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_create_dyngroup_add_non_matching_entry</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(
<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(),
<span class="string">&quot;no_possible_match_to_be_found&quot;</span>.<span class="ident">to_string</span>()
))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>];
<span class="kw">let</span> <span class="ident">create</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_group</span>];
<span class="macro">run_create_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="ident">create</span>,
<span class="prelude-val">None</span>,
<span class="comment">// Need to validate it did things</span>
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">d_group</span>.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>).<span class="ident">is_none</span>());
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_create_dyngroup_add_matching_entry_and_group</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[];
<span class="kw">let</span> <span class="ident">create</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_create_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="ident">create</span>,
<span class="prelude-val">None</span>,
<span class="comment">// Need to validate it did things</span>
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="ident">d_group</span>
.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>)
.<span class="ident">expect</span>(<span class="string">&quot;No members on dyn group&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">members</span>.<span class="ident">to_refer_single</span>() <span class="op">==</span> <span class="prelude-val">Some</span>(<span class="ident">UUID_TEST_GROUP</span>));
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_modify_dyngroup_existing_dyngroup_filter_into_scope</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(
<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(),
<span class="string">&quot;no_such_entry_exists&quot;</span>.<span class="ident">to_string</span>()
))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_modify_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>))),
<span class="ident">ModifyList::new_list</span>(<span class="macro">vec!</span>[
<span class="ident">Modify::Purged</span>(<span class="string">&quot;dyngroup_filter&quot;</span>.<span class="ident">into</span>()),
<span class="ident">Modify::Present</span>(
<span class="ident">AttrString::from</span>(<span class="string">&quot;dyngroup_filter&quot;</span>),
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
]),
<span class="prelude-val">None</span>,
<span class="op">|</span><span class="kw">_</span><span class="op">|</span> {},
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="ident">d_group</span>
.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>)
.<span class="ident">expect</span>(<span class="string">&quot;No members on dyn group&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">members</span>.<span class="ident">to_refer_single</span>() <span class="op">==</span> <span class="prelude-val">Some</span>(<span class="ident">UUID_TEST_GROUP</span>));
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_modify_dyngroup_existing_dyngroup_filter_outof_scope</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_modify_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>))),
<span class="ident">ModifyList::new_list</span>(<span class="macro">vec!</span>[
<span class="ident">Modify::Purged</span>(<span class="string">&quot;dyngroup_filter&quot;</span>.<span class="ident">into</span>()),
<span class="ident">Modify::Present</span>(
<span class="ident">AttrString::from</span>(<span class="string">&quot;dyngroup_filter&quot;</span>),
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(
<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(),
<span class="string">&quot;no_such_entry_exists&quot;</span>.<span class="ident">to_string</span>()
))
)
]),
<span class="prelude-val">None</span>,
<span class="op">|</span><span class="kw">_</span><span class="op">|</span> {},
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">d_group</span>.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>).<span class="ident">is_none</span>());
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_modify_dyngroup_existing_dyngroup_member_add</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_modify_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>))),
<span class="ident">ModifyList::new_list</span>(<span class="macro">vec!</span>[<span class="ident">Modify::Present</span>(
<span class="ident">AttrString::from</span>(<span class="string">&quot;member&quot;</span>),
<span class="ident">Value::new_refer</span>(<span class="ident">UUID_ADMIN</span>)
)]),
<span class="prelude-val">None</span>,
<span class="op">|</span><span class="kw">_</span><span class="op">|</span> {},
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="ident">d_group</span>
.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>)
.<span class="ident">expect</span>(<span class="string">&quot;No members on dyn group&quot;</span>);
<span class="comment">// We assert to refer single here because we should have &quot;removed&quot; uuid_admin being added</span>
<span class="comment">// at all.</span>
<span class="macro">assert!</span>(<span class="ident">members</span>.<span class="ident">to_refer_single</span>() <span class="op">==</span> <span class="prelude-val">Some</span>(<span class="ident">UUID_TEST_GROUP</span>));
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_modify_dyngroup_existing_dyngroup_member_remove</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_modify_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>))),
<span class="ident">ModifyList::new_list</span>(<span class="macro">vec!</span>[<span class="ident">Modify::Purged</span>(<span class="ident">AttrString::from</span>(<span class="string">&quot;member&quot;</span>),)]),
<span class="prelude-val">None</span>,
<span class="op">|</span><span class="kw">_</span><span class="op">|</span> {},
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="ident">d_group</span>
.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>)
.<span class="ident">expect</span>(<span class="string">&quot;No members on dyn group&quot;</span>);
<span class="comment">// We assert to refer single here because we should have re-added the members</span>
<span class="macro">assert!</span>(<span class="ident">members</span>.<span class="ident">to_refer_single</span>() <span class="op">==</span> <span class="prelude-val">Some</span>(<span class="ident">UUID_TEST_GROUP</span>));
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_modify_dyngroup_into_matching_entry</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;not_testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_modify_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;not_testgroup&quot;</span>))),
<span class="ident">ModifyList::new_list</span>(<span class="macro">vec!</span>[
<span class="ident">Modify::Purged</span>(<span class="ident">AttrString::from</span>(<span class="string">&quot;name&quot;</span>),),
<span class="ident">Modify::Present</span>(<span class="ident">AttrString::from</span>(<span class="string">&quot;name&quot;</span>), <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>))
]),
<span class="prelude-val">None</span>,
<span class="op">|</span><span class="kw">_</span><span class="op">|</span> {},
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="ident">d_group</span>
.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>)
.<span class="ident">expect</span>(<span class="string">&quot;No members on dyn group&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">members</span>.<span class="ident">to_refer_single</span>() <span class="op">==</span> <span class="prelude-val">Some</span>(<span class="ident">UUID_TEST_GROUP</span>));
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_modify_dyngroup_into_non_matching_entry</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_modify_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>))),
<span class="ident">ModifyList::new_list</span>(<span class="macro">vec!</span>[
<span class="ident">Modify::Purged</span>(<span class="ident">AttrString::from</span>(<span class="string">&quot;name&quot;</span>),),
<span class="ident">Modify::Present</span>(<span class="ident">AttrString::from</span>(<span class="string">&quot;name&quot;</span>), <span class="ident">Value::new_iname</span>(<span class="string">&quot;not_testgroup&quot;</span>))
]),
<span class="prelude-val">None</span>,
<span class="op">|</span><span class="kw">_</span><span class="op">|</span> {},
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">d_group</span>.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>).<span class="ident">is_none</span>());
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_delete_dyngroup_matching_entry</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_delete_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>))),
<span class="prelude-val">None</span>,
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(
<span class="string">&quot;name&quot;</span>,
<span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)
)))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">d_group</span>.<span class="ident">get_ava_set</span>(<span class="string">&quot;member&quot;</span>).<span class="ident">is_none</span>());
}
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_delete_dyngroup_group</span>() {
<span class="kw">let</span> <span class="ident">e_dyn</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;object&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;dyngroup&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>)),
(
<span class="string">&quot;dyngroup_filter&quot;</span>,
<span class="ident">Value::JsonFilt</span>(<span class="ident">ProtoFilter::Eq</span>(<span class="string">&quot;name&quot;</span>.<span class="ident">to_string</span>(), <span class="string">&quot;testgroup&quot;</span>.<span class="ident">to_string</span>()))
)
);
<span class="kw">let</span> <span class="ident">e_group</span>: <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">EntryInit</span>, <span class="ident">EntryNew</span><span class="op">&gt;</span> <span class="op">=</span> <span class="macro">entry_init!</span>(
(<span class="string">&quot;class&quot;</span>, <span class="ident">Value::new_class</span>(<span class="string">&quot;group&quot;</span>)),
(<span class="string">&quot;name&quot;</span>, <span class="ident">Value::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>)),
(<span class="string">&quot;uuid&quot;</span>, <span class="ident">Value::new_uuid</span>(<span class="ident">UUID_TEST_GROUP</span>))
);
<span class="kw">let</span> <span class="ident">preload</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="ident">e_dyn</span>, <span class="ident">e_group</span>];
<span class="macro">run_delete_test!</span>(
<span class="prelude-val">Ok</span>(()),
<span class="ident">preload</span>,
<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;test_dyngroup&quot;</span>))),
<span class="prelude-val">None</span>,
<span class="op">|</span><span class="ident">qs</span>: <span class="kw-2">&amp;</span><span class="ident">QueryServerWriteTransaction</span><span class="op">|</span> {
<span class="comment">// Note we check memberof is empty here!</span>
<span class="kw">let</span> <span class="ident">cands</span> <span class="op">=</span> <span class="ident">qs</span>
.<span class="ident">internal_search</span>(<span class="macro">filter!</span>(<span class="ident">f_eq</span>(<span class="string">&quot;name&quot;</span>, <span class="ident">PartialValue::new_iname</span>(<span class="string">&quot;testgroup&quot;</span>))))
.<span class="ident">expect</span>(<span class="string">&quot;Internal search failure&quot;</span>);
<span class="kw">let</span> <span class="ident">d_group</span> <span class="op">=</span> <span class="ident">cands</span>.<span class="ident">get</span>(<span class="number">0</span>).<span class="ident">expect</span>(<span class="string">&quot;Unable to access group.&quot;</span>);
<span class="macro">assert!</span>(<span class="ident">d_group</span>.<span class="ident">get_ava_set</span>(<span class="string">&quot;memberof&quot;</span>).<span class="ident">is_none</span>());
}
);
}
}
</code></pre></div>
</section></div></main><div id="rustdoc-vars" data-root-path="../../../" data-current-crate="kanidmd_lib" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.64.0 (a55dd71d5 2022-09-19)" ></div></body></html>